FlexとPHPでチャットを作る
いまFlexをいじっているんだけど、サーバサイドはJavaなので手軽じゃない(レンタルサーバで動かない)
で、サーバサイドをPHPにしてチャットを作りたいなー、と思ったんだけど、ぐぐってもこれぞというのがひっかからないので自分で作ることにした
表題の通り、クライアントサイドをFlexで、サーバサイドをPHPで実装する
サーバ構築
PHPは初めていじるので、Apacheのインストール 初心者用PHP入門を参考にまずはサーバを用意する
ほぼ手順通りでできたけど、一カ所だけ手順通りにできなかった
次に、c:\WINDOWSディレクトリ内にあるphp.iniをメモ帳などで開き「doc_root = 」を次のように追加して修正します。
自分の環境がVistaだから?かもしれないけど、c:\windowsにはphp.iniはなかったので、phpのインストールディレクトリにあるphp.ini-distをコピーして作成した
PHPが動作する環境ができた!\(=ω=.)/
Flex実装
適当に作る
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:VBox> <mx:Label text="Chat" width="1024"/> <mx:TabNavigator width="1024"> <mx:VBox label="CHAT"> <mx:HBox> <mx:TextInput id="handleName" width="120"/> <mx:TextInput id="content" width="640"/> <mx:Button id="submit" label="投稿"/> </mx:HBox> <mx:DataGrid id="chatLog"> <mx:columns> <mx:DataGridColumn headerText="投稿者" dataField="handleName" width="120"/> <mx:DataGridColumn headerText="投稿日時" dataField="time" width="120"/> <mx:DataGridColumn headerText="内容" dataField="content" width="640"/> </mx:columns> </mx:DataGrid> </mx:VBox> </mx:TabNavigator> </mx:VBox> </mx:Application>
できた\(=ω=.)/
FlexとPHPのデータ連係
FlexはできるけどPHPは触ったことすらないのでここからが怖い
そもそもFlexとPHPのデータのやりとりはどうやるんだろう、とぐぐっていたらAdobe公式のドキュメントを見つけた
JSONを使用したFlexおよびPHP間のデータ送信
ここに習ってFlexとPHPの連携にはJSONを使うことにした
Flexの修正
上記URLに従ってcorelibをダウンロードする
解凍すると出てくるswcファイルをFlexプロジェクトのライブラリパスに設定する
これでFlexからJSONが扱える
というわけで修正
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" paddingTop="5" paddingBottom="5" paddingRight="5" paddingLeft="5" horizontalAlign="left" verticalAlign="top" > <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.controls.Alert; import mx.rpc.events.ResultEvent; import com.adobe.serialization.json.JSON; private function chatResult(event:ResultEvent):void { var rawData:String = String(event.result); var post:Object =JSON.decode(rawData); var posts:Array = post as Array; var postCollection:ArrayCollection = new ArrayCollection(posts); chatLog.dataProvider = postCollection; } ]]> </mx:Script> <mx:HTTPService id="chatRequest" url="./chat.php" useProxy="false" method="GET" resultFormat="text" result="chatResult(event)"> <mx:request xmlns=""> <getPost>true</getPost> </mx:request> </mx:HTTPService> <mx:VBox> <mx:Label text="\(=ω=.)/"/> <mx:TabNavigator> <mx:VBox label="CHAT" height="600" width="800" paddingLeft="5" paddingRight="5"> <mx:HBox> <mx:TextInput id="handleName" width="120"/> <mx:TextInput id="content" width="600"/> <mx:Button id="submit" label="投稿" click="chatRequest.send()"/> </mx:HBox> <mx:DataGrid id="chatLog" height="540" width="780"> <mx:columns> <mx:DataGridColumn headerText="投稿者" dataField="handleName" width="120"/> <mx:DataGridColumn headerText="投稿日時" dataField="time" width="160"/> <mx:DataGridColumn headerText="内容" dataField="content" width="500"/> </mx:columns> </mx:DataGrid> </mx:VBox> </mx:TabNavigator> </mx:VBox> </mx:Application>
HTTPServiceとmx:Scriptを追加
投稿ボタンを押したときにHTTPServiceのインスタンスの関数を呼び出すようにする
あとデザインを少し修正
とりあえず投稿ボタンを押すと、PHPでログファイルを読み込んできて、DataGridに出す感じで作る
PHPの実装
まずはログのモックを作る
konata#2008/08/02 20:47:12#test1 kagami#2008/08/02 20:47:13#test2 tsukasa#2008/08/02 20:47:14#test3 miwiki#2008/08/02 20:47:15#test4
<?php class Post { public $handleName; public $time; public $content; } if(isset($_GET['getPost'])) { // ファイルをオープン. $file = fopen('log.txt', 'r'); $posts = array(); // ログファイルを読み込む. while(!feof($file)) { $line = fgets($file); $post = new Post(); $items = explode("#", $line); $post->handleName = $items[0]; $post->time = $items[1]; $post->content = $items[2]; array_push($posts, $post); } echo json_encode( $posts ); } ?>
メモ1
- JavaScriptで言うsplit()関数は、PHPではexplode()関数
- オブジェクト指向が分かれば普通にいけそう
- 配列にオブジェクトを追加する関数を調べるのに5分位かかった自分は低脳
PHPの修正
読みこみにしか対応してなかったので書き込みに対応する
<?php class Post { public $handleName; public $time; public $content; } // 投稿. if(isset($_POST['doPost'])) { // readwriteでファイルをオープン. $file = fopen('log.txt', 'a'); $asOfDate = date("Y/m/d H:i:s"); $line = $_POST['handleName']."#".$asOfDate."#".$_POST['content']."\n"; fputs($file, $line); fclose(file); } // 更新. if(isset($_GET['doGet'])) { // ファイルをオープン. $file = fopen('log.txt', 'r'); $posts = array(); // ログファイルを読み込む. while(!feof($file)) { $line = fgets($file); $post = new Post(); $items = explode("#", $line); $post->handleName = $items[0]; $post->time = $items[1]; $post->content = $items[2]; array_push($posts, $post); } echo json_encode( $posts ); } ?>
リクエストがあったらサーバ側で時間を取得、フォーマットしてログに出力する
Flexの修正
リロードと投稿で動作を分ける
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" paddingTop="5" paddingBottom="5" paddingRight="5" paddingLeft="5" horizontalAlign="left" verticalAlign="top" > <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.controls.Alert; import mx.rpc.events.ResultEvent; import com.adobe.serialization.json.JSON; private function chatResult(event:ResultEvent):void { var rawData:String = String(event.result); var post:Object =JSON.decode(rawData); var posts:Array = post as Array; var postCollection:ArrayCollection = new ArrayCollection(posts); chatLog.dataProvider = postCollection; } private function post(event:Event = null):void { // 内容が入力されている場合投稿、空の場合は更新する. if(handleName.text != "" && content.text != "") { // 投稿 postRequest.send(); reloadRequest.send(); } else { // 更新 reloadRequest.send(); } } ]]> </mx:Script> <mx:HTTPService id="postRequest" url="./chat.php" useProxy="false" method="POST" resultFormat="text"> <mx:request xmlns=""> <doPost>true</doPost> <handleName>{handleName.text}</handleName> <content>{content.text}</content> </mx:request> </mx:HTTPService> <mx:HTTPService id="reloadRequest" url="./chat.php" useProxy="false" method="GET" resultFormat="text" result="chatResult(event)"> <mx:request xmlns=""> <doGet>true</doGet> </mx:request> </mx:HTTPService> <mx:VBox> <mx:Label text="\(=ω=.)/"/> <mx:TabNavigator> <mx:VBox label="CHAT" height="600" width="800" paddingLeft="5" paddingRight="5"> <mx:HBox> <mx:TextInput id="handleName" width="120"/> <mx:TextInput id="content" width="600"/> <mx:Button id="submit" label="投稿" click="post()"/> </mx:HBox> <mx:DataGrid id="chatLog" height="540" width="780"> <mx:columns> <mx:DataGridColumn headerText="投稿者" dataField="handleName" width="120"/> <mx:DataGridColumn headerText="投稿日時" dataField="time" width="160"/> <mx:DataGridColumn headerText="内容" dataField="content" width="500"/> </mx:columns> </mx:DataGrid> </mx:VBox> </mx:TabNavigator> </mx:VBox> </mx:Application>
参考
- http://ponk.jp/php_file/index.php?page=2
- http://php.benscom.com/manual/ja/language.types.string.php
- http://nyx.pu1.net/function/filesystem/fwrite.html
- http://www.geocities.jp/takuji_kawata/reports/report_use_httpservice2.htm
- http://livedocs.adobe.com/flex/3_jp/html/help.html?content=data_access_2.html#473538
- POSTの仕方はここを見た