[mootools&PHP] Ajax.Request でファイルの読み書きをする

Step5.投稿日時を付け加えて整形

前のステップの段階で既にデータを受け取るところまで出来てるので、

if($_POST["mode"] == "post"){
  print $_POST["comment"];
}

この$_POST[“comment”]の中身をファイルに書き込めばいいわけです。
値があるときだけ実行するようにしたいので、sample.phpのif文に条件を追加して空送信では無効になるようにしときます。

if($_POST["mode"] == "post" && $_POST["comment"] != "")

保存するデータが送信された値だけではちょっと寂しいので、送信日時も付け足すことにします。
date関数とtime関数についてはマニュアルとか見てください。

sample.php

if($_POST["mode"] == "post" && $_POST["comment"] != ""){
 $savedata = $_POST["comment"].",".date("Y/m/d H:i:s",time());
 print $savedata;
}

保存されるときに送信された内容と送信日時をカンマで区切るようにしています。
この時点で実行したときに、保存される形式がそのまま出力されたらOK。
ああああ,2009/03/10 01:31:20

Step6.送信されたデータの保存

保存はファイルシステム関数の組み合わせなんですが、説明面倒なのでサンプルの保存関数をそのままコピペしてください。
簡単に流れをコメントで書いてあります。

まずsample.phpの先頭に以下の定数を追加

define("FILE","data.txt");//保存先のファイル名

次に保存関数。場所は上でも下でもどこでもいいです。

sample.php

//保存
function new_save($data)
{
	//ファイルサイズをチェックして0でなければ内容を保存します
	if(filesize(FILE) != "0"){
		$contents = file(FILE);//配列形式で読み込む
	}
	$fp = fopen(FILE, "w");//ファイルオープン
	fwrite($fp, $data);//送信されたデータの書き込み
	if(is_array($contents)){
		for($i=0;$i < count($contents) ;$i++){
			fwrite($fp, $contents&#91;$i&#93;);//ログの書き込み
		}
	}
	fclose($fp);//ファイルクローズ
	return true;
}
&#91;/php&#93;
この関数は引数で渡された文字列をファイルに書き込むものです。
文字列は前のステップで作ってますので、関数の実行はprintの行の下になります。

<strong>sample.php</strong>
[php]
if($_POST["mode"] == "post" && $_POST["comment"] != ""){
 $savedata = $_POST["comment"].",".date("Y/m/d H:i:s",time());
 print $savedata;
 new_save($savedata."\n");
}

"\n"は改行コードです。これが無いと全部一行になってしまうので必須。

適当になんか送信して、data.txtに保存されていたらOK。

Step7. エフェクトをつけて表示する

今のところ表示されるのがただの文字列なので、Fxでエフェクトを付けていかにもAjaxしてますな感じにする。
クリックイベント内にあるRequestインスタンスのonSuccess()内を変更します。

まず、返ってきたデータをカンマで分割。

var data = txt.split(",");

変数dataは配列になり、data[0]には送信したテキスト、data[1]に送信日時が格納されます。

エフェクトはフェードインだけなので、ショートカットメソッドfade()で直接エレメントに追加して、初期を非表示状態にしときます。
ログを入れる要素はまあ段落でもリストでも何でもいいんですが、とりあえずpタグにして日時はspanに入れることにしました。
要素はnew Element()で作成します。

var element = new Element("p",{html:data[0]+"<span>["+data[1]+"]</span>"}).fade("hide").inject("pastlog","top");
element.fade("in");

inject()でdiv#pastlogの先頭に追加したあと、fade(“in”)する。

実行してフェードインして表示されればOK。

ここまでの動作の流れをまとめると次のようになります。

  1. button#submitをクリックする
  2. input#commentの値を取得する
  3. Requestクラスのインスタンスを作成する
  4. オプションで指定されたURLへデータを送信する
  5. 送信されたデータを受け取る(PHP)
  6. 送信日時を追加する(PHP)
  7. 送信データに日時を付け加えたデータを返す(PHP)
  8. 返された結果を出力
  9. ファイルに保存する(PHP)

Step8. ログを取得する

ここまでの段階だと過去ログが見れないので
ページを表示したりリロードした時にもログを表示するようにします。

新しいRequestクラスのインスタンスをwindow.addEvent(‘domready’)直下に追加します。
クリックイベントの前後どこでもいいです。

index.html

new Request({
	url:"sample.php",
	method:"get",
	data:"mode=load",
	onSuccess: function(txt) {
		$("pastlog").set('html',txt);
	},
    onFailure: function() {
       $("pastlog").set('html', 'エラーが発生しました');
    }
}).send();

methodはまあどっちでもいいんですが、GETにしときます。

PHPにログを取得する関数とif文を追加します。
これもまた説明が面倒なのでサンプルをコピペしてみてください。
まずはロードの関数。場所はどこでもいいです。

sample.php

//ロード
function get_data(){
	$logdata = file(FILE);
	print trim(implode("\t",$logdata));
}

file()は配列形式でファイルを読み込む関数です。
タブで配列をくっつけた後、文字列前後の改行コードを取り除くためにtrim関数を通して返します。

上記の関数をコピペしたら、実行するif文を追加します。
dataでmode=loadを渡しているので、if文の条件は次のようになります。

if($_GET["mode"] == "load"){
	get_data();
}

リロードしてずらーっと文字列が出ればOK。

Step9. ログのスタイリング

文字列じゃアレなので、送信したデータを表示した時みたいにタグで整形することにします。
手順はStep7と大体同じです。

onSuccess()で実行される関数のソースを変更します。
まずくっつけた文字列(タブ)で分割して配列に戻す。

var log = txt.split("\t");

変数logには保存されているログの行が配列形式で格納されます。

これをeach()で処理する。

log.each(function(item,i){
	var data = item.split(",");
	new Element("p",{html:data[0]+"<span>"+data[1]+"</span>"}).inject("pastlog");
});

カンマで分割したログをpタグにいれた後、inject()でdiv#pastlogに追加していく。

まとめると次のようになります。

new Request({
	url:"sample.php",
	method:"get",
	data:"mode=load",
	onSuccess: function(txt) {
		var log = txt.split("\t");
		log.each(function(item,i){
			var data = item.split(",");
			new Element("p",{html:data[0]+"<span>"+data[1]+"</span>"}).inject("pastlog");
		});
		},
    onFailure: function() {
       $("pastlog").set('html', 'エラーが発生しました');
    }
}).send();

Step10. ソースのまとめ

javascriptとphpの全文を以下に載せます。

index.php

window.addEvent('domready', function(){
	
	new Request({
		url:"sample.php",
		method:"get",
		data:"mode=load",
		onSuccess: function(txt) {
			var log = txt.split("\t");
			log.each(function(item,i){
				var data = item.split(",");
				new Element("p",{html:data[0]+"<span>"+data[1]+"</span>"}).inject("pastlog");
			});
			},
	    onFailure: function() {
	       $("pastlog").set('html', 'エラーが発生しました');
	    }
	}).send();

	$("submit").addEvent("click",function(e){
		e.stop();
		var comment = $("comment").value;
		new Request({
			url:"sample.php",
	      	method: 'post',
			data:{"mode":"post","comment":comment},
			onRequest:function(){
				$("comment").value ="";
			},
			onSuccess: function(txt) {
				
				var data = txt.split(",");
				var element = new Element("p",{html:data[0]+"<span>"+data[1]+"</span>"}).fade("hide").inject("pastlog","top");
				element.fade("in");

			},
	        onFailure: function() {
	           $("pastlog").set('html', 'エラーが発生しました');
	        }
  		}).send();
	});
});

sample.php

define(“FILE”,”data.txt”);

if($_POST[“mode”] == “post” && $_POST[“comment”] != “”){
$savedata = $_POST[“comment”].”,”.date(“Y/m/d H:i:s”,time());
print $savedata;
new_save($savedata.”\n”);
}

if($_GET[“mode”]==”load”){
get_data();
}
//ロード
function get_data(){
$logdata = file(FILE);
print trim(implode(“\t”,$logdata));
}
//保存
function new_save($data)
{
//ファイルサイズをチェックして0でなければ内容を保存します
if(filesize(FILE) != “0”){
$contents = file(FILE);//配列形式で読み込む
}
$fp = fopen(FILE, “w”);//ファイルオープン
fwrite($fp, $data);//送信されたデータの書き込み

if(is_array($contents)){
for($i=0;$i < count($contents) ;$i++){ fwrite($fp, $contents[$i]);//ログの書き込み } } fclose($fp);//ファイルクローズ return true; } [/php] Demo »
ダウンロード:[download#51#nohits]

なんとなくTwitterに似てますよね。
ローディングや完了メッセージとか付け足したら、似たような掲示板が作れると思います。
サンプル過ぎて実用には耐えないので、もうちょっと本格的にしたいなーという場合は
SlimBBSのPHPファイルを使うといいかもしれません。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください