swfmillでケータイFlashを動的生成してみよう(文字列置換編)

By ookura - 08/12/12 - このエントリをはてなブックマークに追加このエントリをYahoo!ブックマークに追加このエントリをdel.icio.usに追加このエントリをFC2ブックマークに追加

前回はswfmillのインストールについて説明しました。
今回はswfmillを使ったswf内のテキストやリンクの置換方法について説明します。
参考:swfmillでケータイFlashを動的生成してみよう(インストール編)

PHPとswfmillの連携

ではswfmillがインストールできたところで実際に変換する処理をPHPで作成します。
 
処理の流れとしては、以下のようになります。
・swfファイルを用意する
・swfファイルを読み込む
・swfmillに対してパイプ処理でswfファイルの内容を渡してxmlデータを取得する
・xmlデータの内容を書き換える
・swfmillに対してパイプ処理でxmlデータを渡してswfファイルの内容を取得する
・flashのヘッダを出力してswfファイルの内容を出力する
 
 


swfファイルを用意する

あらかじめFlashLite1.1のswfファイルを用意します。
今回は文字列の置換処理のサンプルになりますので静止テキストとリンクを配置しただけのシンプルなFlashです。
文字列は何でもよいのですが今回は以下の文字列を設定しました。
「{$titleText}」「{$commentText}」
[図47]
[図48]
 
リンクの文字列を以下のように設定します。
「{$linkText1}」「{$linkText2}」
[図49]
 
リンク先のURLは以下のように指定します。
「{$linkUrl1}」「{$linkUrl2}」
[図50]

on (press) {
    getURL("{$linkUrl1}");
}

 
静止テキストのフォントはデバイスフォントの「_等幅」にしておきます。
※「MS ゴシック」のような組み込みフォントにするとXMLデータ上で文字が分解されてしまい、置換処理ができません。
 
できたらパブリッシュしてサーバーにアップロードします。
 
 


swfファイルを読み込む

file_get_contents関数でswfファイルの内容を読み込みます。

$swfData = file_get_contents('sample1594.swf');

 
 


swfmillにswfを渡してxmlデータを取得する

PHPファイルを文字コードUTF-8で作成します。
 
proc_open関数でパイプ処理を行います。
proc_open
事前に$descriptorspecに入出力とエラー出力先を指定しておきます。
エラー出力先のファイルは事前に書き込み可能なパーミッションにして配置しておきます。
 
Flash Lite 1.1の内部文字コードが「cp932(Flash6でUnicodeになる前の文字コード)」なので、-e cp932 のようにオプションで文字コードを指定しています。
もしFlash Lite 2.0以上の場合は内部コードがUTF-8なのでこのオプションはつけません。
 
第一引数でswf2xmlを指定してSWFからXMLへの変換を行います。
第二引数でstdinを指定して標準入力としてswfの内容をswfmillに送ります。
第三引数でstdoutを指定して標準出力としてxmlの内容を取得します。
 
パイプ処理した後の値はstream_get_contents関数で取得しています。
stream_get_contents
それぞれのパイプを閉じてからproc_close関数でプロセスを閉じておきます。

// SWFからXMLに変換

// コマンド実行時の入出力とエラー出力先を指定
$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "error-output.txt", "a")
);

// swfmillコマンドを実行してリソースとファイルポインタを取得
$process = proc_open('/usr/local/bin/swfmill -e cp932 swf2xml stdin stdout', $descriptorspec, $pipes);

if (is_resource($process)) {
    // 標準入力にSWFファイルのバイナリデータを書き込み
    fwrite($pipes[0], $swfData);
    fclose($pipes[0]);
    
    // 標準出力からXMLデータを読み込み
    $xmlString = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    
    // パイプを全て閉じてからプロセスを閉じる
    proc_close($process);
}

 
$xmlStringにはXMLが文字列として代入されます。
 
 


xmlデータの内容を書き換える

あらかじめswfファイルの中で設定した文字列を書き換えます。
 
置換用の配列を指定しておきます。
確認のため、置換結果は複数用意しておきます。

// 置換する値を連想配列で設定
$replaceStrings[0] = array(
    'titleText'   => "ページタイトル",
    'commentText' => "コメント1行目\nコメント2行目",
    'linkText1'   => "→リンク1",
    'linkText2'   => "→リンク2",
    'linkUrl1'    => "link1.html",
    'linkUrl2'    => "link2.html",
);
$replaceStrings[1] = array(
    'titleText'   => "携帯サイトをつくろう。",
    'commentText' => "携帯サイト制作のための\n役立つ情報満載サイト",
    'linkText1'   => "→新着記事",
    'linkText2'   => "→カテゴリ一覧",
    'linkUrl1'    => "link3.html",
    'linkUrl2'    => "link4.html",
);

 
静止テキストの改行コードは、XMLでは「
」となっていますので、改行がある場合は「
」に置換します。
この置換作業ではテキストの高さは調整しませんので、改行を含む場合はあらかじめswfの静止テキストに改行を入れておく必要があります。
 
「{$変数名}」を「値」に書き換えます。
 

foreach($replaceStrings[$pattern] as $key => $value){
    // 文字列内の改行を置換
    $value = str_replace("\n", '
', $value);
    
    // 文字列を連想配列の値に置換
    $xmlString = str_replace('{$' . $key . '}', $value, $xmlString);
    
}

 
$xmlStringにはXMLを文字列置換した結果が代入されます。
 
 


swfmillにxmlデータを渡してswfを取得する

swfmillでxml2swfを指定してXMLからswfに戻します。
今回は標準入力にXMLデータを指定し、標準出力でSWFのバイナリデータを取得します。

// コマンド実行時の入出力とエラー出力先を指定
$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "error-output.txt", "a")
);

// swfmillコマンドを実行してリソースとファイルポインタを取得
$process = proc_open('/usr/local/bin/swfmill -e cp932 xml2swf stdin stdout', $descriptorspec, $pipes);

if (is_resource($process)) {
    
    // 標準入力にXMLデータを書き込み
    fwrite($pipes[0], $xmlString);
    fclose($pipes[0]);
    
    // 標準出力からSWFファイルのバイナリデータを読み込み
    $swfOutput = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    
    // パイプを全て閉じてからプロセスを閉じる
    proc_close($process);
}

 
$swfOutputには置換結果のSWFのバイナリデータが代入されます。
 
 


swfファイルを出力する

flashのヘッダ「Content-type: application/x-shockwave-flash」を出力してブラウザにswfとして認識させます。
swfのデータ$swfOutputを出力するとブラウザからは動的に生成されたFlashが確認できます。

// SWFのヘッダを出力
header('Content-type: application/x-shockwave-flash');

// SWFのデータを出力
echo $swfOutput;

 
 


備考

・置換用に設定する文字列には特に決まりはありませんので、ActionScriptのエラーにならない範囲で決めればよいと思います。
 筆者の場合はSmartyを参考にした次第です。
 
・変換コマンドの実行に関してはいろいろな方法があり、上記で紹介したものよりもっと効率的な方法があるかと思います。
 
 


PHPソース例

実際のソースは以下の通りです。
 
sample1594.php

<?php
/* 
 * swfのテキストとリンクを置換して出力するサンプル
 */

// 置換パターンを指定
$pattern = intval($_GET['pattern']);
if (!in_array($pattern, array(0,1))) {
    $pattern = 0;
}

// SWFファイルの内容を取得
$swfData = file_get_contents('sample1594.swf');


// SWFからXMLに変換

// コマンド実行時の入出力とエラー出力先を指定
$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "error-output.txt", "a")
);

// swfmillコマンドを実行してリソースとファイルポインタを取得
$process = proc_open('/usr/local/bin/swfmill -e cp932 swf2xml stdin stdout', $descriptorspec, $pipes);

if (is_resource($process)) {
    // 標準入力にSWFファイルのバイナリデータを書き込み
    fwrite($pipes[0], $swfData);
    fclose($pipes[0]);
    
    // 標準出力からXMLデータを読み込み
    $xmlString = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    
    // パイプを全て閉じてからプロセスを閉じる
    proc_close($process);
}

// 文字列置換

// 置換する値を連想配列で設定
$replaceStrings[0] = array(
    'titleText'   => "ページタイトル",
    'commentText' => "コメント1行目\nコメント2行目",
    'linkText1'   => "→リンク1",
    'linkText2'   => "→リンク2",
    'linkUrl1'    => "link1.html",
    'linkUrl2'    => "link2.html",
);
$replaceStrings[1] = array(
    'titleText'   => "携帯サイトをつくろう。",
    'commentText' => "携帯サイト制作のための\n役立つ情報満載サイト",
    'linkText1'   => "→新着記事",
    'linkText2'   => "→カテゴリ一覧",
    'linkUrl1'    => "link3.html",
    'linkUrl2'    => "link4.html",
);

foreach($replaceStrings[$pattern] as $key => $value){
    // 文字列内の改行を置換
    $value = str_replace("\n", '&#13;', $value);
    
    // 文字列を連想配列の値に置換
    $xmlString = str_replace('{$' . $key . '}', $value, $xmlString);
    
}


// XMLからSWFに変換

// コマンド実行時の入出力とエラー出力先を指定
$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "error-output.txt", "a")
);

// swfmillコマンドを実行してリソースとファイルポインタを取得
$process = proc_open('/usr/local/bin/swfmill -e cp932 xml2swf stdin stdout', $descriptorspec, $pipes);

if (is_resource($process)) {
    
    // 標準入力にXMLデータを書き込み
    fwrite($pipes[0], $xmlString);
    fclose($pipes[0]);
    
    // 標準出力からSWFファイルのバイナリデータを読み込み
    $swfOutput = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    
    // パイプを全て閉じてからプロセスを閉じる
    proc_close($process);
}

// SWFのヘッダを出力
header('Content-type: application/x-shockwave-flash');

// SWFのデータを出力
echo $swfOutput;
?>

 
 


実行例

実行例はこちらからご確認下さい。

URLをメールで送る
http://ookura.tanikaze.com/Sample/post1594/
 
 


Flashサイト動的生成関連の記事一覧

1.ケータイFlashの概要
 1-1 ケータイFlashの概要について
 
2.ケータイFlashのページ作成
 2-1 ケータイFlashのページを作ってみよう
 2-2 ケータイFlashで縦スクロールするページを作ってみよう
 
3.swfmillでケータイFlashを動的生成
 3-1 swfmillでケータイFlashを動的生成してみよう(インストール編)
 3-2 swfmillでケータイFlashを動的生成してみよう(文字列置換編)
 3-3 swfmillでケータイFlashを動的生成してみよう(画像置換編)
 3-4 ケータイFlashのレイアウトを文章量に同期させよう
 
4.ActionScriptとPHPの連携
 4-1 ActionScriptで文字列をPHPから動的に取得しよう
 4-2 ケータイFlashでテキスト入力フォームを作ろう