Flex4とsymfonyを連携させて遊んでみた。
最近仕事で毎日PHP4と格闘している橋本です、こんにちは。
さて、4繋がりということで、今日は先日β版がリリースされたばかりのFlashBuilder4を使って、
Flex4とsymfonyを連携させて遊んでみました。
Asialブログの購読者の方々の中に「symfonyって何??」って方はいらっしゃらないと思いますが、「Flexって何??」って方は中にはいらっしゃるかもしれないので、 軽く説明。
Flexとは、Adobe社の提供するRIA(Rich Interface Application)開発のフレームワークです。
Adobeの得意分野であるFlashの技術をベースとしています。
インターフェースの作成には、MXMLというXMLを拡張した言語を用いて行います。
実行時には、MXMLファイルがswfファイルに変換され、クライアントのFlashPlayer上で実行されます。
Flexの開発キットのFlexSDKはAdobe社から配布されており無償でDL可能です。
(最新版:Adobe Flex4 SDK)
また、有償ですが、FlashBuilder4(旧称 FlexBuilder)というEclipseベースのIDEを利用することも可能です。
(ちなみに、一個前のバージョンのFlexBuilder3は、学生の方ならば無料で利用することができます。こちら。学生さん、うらやましすぎです。)
今回はこのFlashBuilder4を使ってアプリ作成を進めていきたいと思います。
まず、FlashBuilder4をDL&インストールしましょう。
30日間は無料で使えます。
ちなみに、FlexBuilder3のライセンスを持っている場合は、β期間中は30日を超えても利用可能みたいです。)
次にsymfonyのインストールです。
と、言いたいところですが、既にsymfonyをお使いになっておられる方が多いかと思いますので、割愛。
今回はsymfony-1.2.8-DEVを使って進めていきます。
始める前に、そもそもどうやってFlashとPHPでデータをやりとりするのかという話になるかと思いますので、軽く説明。
FlashとPHPでデータのやりとりをする際には、AMF(ActionScript Messaging Format)と いうファイル形式を利用します。他にもXMLだったり、JSONだったりでやりとりすることも可能ですが、AMFはバイナリ形式でやりとりが可能なため、他の二つの方法よりも高速にデータのやりとりを行うことができます。
(少し古いデータですが、三つのデータ形式を利用した結果が載ってるページがありました。こちら)
PHPでAMFを利用するためのライブラリとして主に、amfphp、WebOrb、SabreAMFの三つがありますが、今回はSabreAMFを利用します。
SabreAMFを使うのは、SabreAMFを利用したsymfonyのpluginが公開されていた、という単純な理由からです。
今回はこのpluginを使ってすすめていきたいと思います。
では、まず、symfonyプロジェクトを作成します。
symfony generate:project amf_sample
symfony generate:app frontend
次に、sfAmfPluginをインストールします。キャッシュのクリアもお忘れなく。
symfony plugin:install sfAmfPlugin
symfony cc
プラグインを使って、AMF-Serviceを作成します。
symfony amf:create-service --package=frontend.user Register
symfony cc
引数としてパッケージ名を渡していますが、これは渡しても渡さなくても大丈夫です。
パッケージ名を渡さなかった場合には、lib/services以下に、パッケージ名を渡した場合は、lib/services/パッケージ名にAMF-Serviceクラスのファイルが作成されます。
上記の例では、lib/services/frontend/user/RegisterServices.class.phpが作成されます。
次に、このサービスの中継役をするモジュールを作成します。
symfonyの場合は、モジュールとアクションを作ってやればOKです。
symfony generate:module amfgateway
symfony cc
apps/frontend/modules/amfgateway/actions/actions.class.php
class amfgatewayActions extends sfActions
{
public function executeAmf(sfWebRequest $request) {
$this->setLayout(false);
$gateway = new sfAmfGateway();
$response = sfContext::GetInstance()->getResponse();
$response->setContent($gateway->service());
return sfView::NONE;
}
}
次に、サービスの中身を作っていきます。
といっても今日は簡単なことしかしません。
Flex側で取得した値をDoctrineに渡して保存するのみ。
DBはこんな感じの簡単なものを用意しました。
User:
tableName: user
columns:
id:
type: integer(4)
primary: true
autoincrement: true
name: string(255)
email: string(255)
phone: string(255)
created_at: timestamp(25)
updated_at: timestamp(25)
actAs:
Timestampable: { }
記述の仕方は普通にDoctrineを使用する場合と同じです。
lib/services/frontend/user/RegisterService.class.php
class RegisterService extends sfAmfService {
// ユーザデータを保存する
public function createUserData($user_data) {
$user = new User();
$user->fromArray($user_data);
$user->save();
return 'OK';
}
}
次にFlexを使ってクライアント側をつくります。
外観はデザインモードにして、適当に作成。
スクリプト部分をソースモードにして、 これまた適当に作成します。
デザインモードで適当に作ったため、座標の値が中途半端なのですが、ご愛嬌ってことで見逃してください。(す、すみません。)
ソースはこんな感じ。
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.events.CloseEvent;
import mx.rpc.remoting.RemoteObject;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
private function createUserData():void {
var userData:Array = new Array();
userData['name'] = userName.text;
userData['email'] = email.text;
userData['phone'] =