php > pear

HTML_AJAX メモ

PHPでAJAXを利用するためのパッケージ。

まだ、開発中のようですが、お客さんの要望を実装するためにもちょいと必要になったため、導入したので、そのメモ。。

基本的なAJAXでの会話方法

HTML_AJAXをパスの通っているディレクトリに配置し、AJAX用のPHPファイルを用意します。

ajax.php

 require_once 'HTML/AJAX/Server.php';
 class test{
    function say_hello($name) {
        return "Hello $name !";
    }
 }

HTML側では

 <script type='text/javascript' src="/app/ajax.php?client=all"></script>
 <script type="text/javascript" src="/app/ajax.php?stub=test"></script>

1行目がAJAXで必要なJSライブラリをAJAX_HTMLを通して呼び出します。

2行目がtestクラスを呼び出しますよと指示してるようなものです。

ちなみに複数のクラスを利用するのであれば2行目を

  <script type="text/javascript" src="/app/ajax.php?stub=all"></script>

とすれば、わざわざ指定しなくても良いわけですが。。 あとは、 http://itpro.nikkeibp.co.jp/article/COLUMN/20051023/223253/ こちらのサンプル通りです。はい。

日本語のやりとりは?

内部エンコードは何でも構いませんが、AJAXで出力するデータはUTF-8でなければなりません。

というわけで、出力するために

 $hoge = mb_convert_encoding($hoge,"utf-8",mb_internal_encoding());

もしくは

 mb_http_output("utf-8");

としないと日本語出力が化けてしまいます。

フォームのPOST値をそのままAJAXで受け取る方法

ref:http://dozo.matrix.jp/pear/index.php?PEAR%2FHTML_AJAX%2Funescape を参考にさせていただきました。

formタグを

 <form onsubmit="return submit_form(this,'confirm');">
 ....
 </form>
 <div id="confirm"></div>

とし、受け側のJavaScriptを

 <script language="javascript">
 function submit_form(obj,mode){
  HTML_AJAX.formSubmit(obj, mode);
 }
 </script>

とすれば、フォーム内容をPHPで受け取り、出力結果をidがconfirmのdivタグへ出力します。

この場合に、日本語はUTF-8のためurl_decode() では駄目なんです。。というわけで、 http://www.php.net/manual/ja/function.utf8-encode.php にあるサンプルのお知恵を借り、次のように関数を用意しました。

	/**
	 * Function converts an Javascript escaped string back into a string with specified charset (default is UTF-8). 
	 * Modified function from http://pure-essence.net/stuff/code/utf8RawUrlDecode.phps
	 *
	 * @param string $source escaped with Javascript's escape() function
	 * @param string $iconv_to destination character set will be used as second paramether in the iconv function. Default is UTF-8.
	 * @return string 
	 */
	function unescape($source, $iconv_to = 'EUC-JP', $iconv_from = 'UTF-8') {
		$decodedStr = '';
		$pos = 0;
		$len = strlen ($source);
		while ($pos < $len) {
			$charAt = substr ($source, $pos, 1);
			if ($charAt == '%') {
				 $pos++;
				$charAt = substr ($source, $pos, 1);
				if ($charAt == 'u') {
					// we got a unicode character
					$pos++;
					$unicodeHexVal = substr ($source, $pos, 4);
					$unicode = hexdec ($unicodeHexVal);
					$decodedStr .= Slips::code2utf($unicode);
					$pos += 4;
				}
				else {
					// we have an escaped ascii character
					$hexVal = substr ($source, $pos, 2);
					$decodedStr .= chr (hexdec ($hexVal));
					$pos += 2;
				}
			}
			else {
				$decodedStr .= $charAt;
				$pos++;
			}
		}
		if ($iconv_to != "UTF-8") {
			$decodedStr = mb_convert_encoding($decodedStr, $iconv_to, $iconv_from);
		}
		return $decodedStr;
	}
 
	/**
	 * Function coverts number of utf char into that character.
	 * Function taken from: http://sk2.php.net/manual/en/function.utf8-encode.php#49336
	 *
	 * @param int $num
	 * @return utf8char
	 */
	function code2utf($num){
		if($num<128)return chr($num);
		if($num<2048)return chr(($num>>6)+192).chr(($num&63)+128);
		if($num<65536)return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
		if($num<2097152)return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128);
	return '';
	}

そして、この関数を再帰的に処理できるように。。。

	function ajax_conv($mix){
		if( is_array($mix) ):
			foreach($mix as $k => $v ):
				if( is_array($v) ):
					$mix[$k] = $this->ajax_conv($v);
				else:
					$mix[$k] = unescape($v);
				endif;
			endforeach;
			return $mix;
		else:
			return unescape($mix);
		endif;
	}

あとは、POSTされた値を

 $data = ajax_conv($data);

とすればOKと。 1)

エラーの処理ってどうするの?

JavaScriptなので、このあたりがIEだと確認するのが不便だったりしますが。 そこで、JavaScriptに次のように定義しておきます。

 HTML_AJAX.onError = function(e) 
 {
    alert(HTML_AJAX_Util.varDump(e));
    document.getElementById('HTML_AJAX_LOADING').style.display = "none";
    document.getElementById('alert').innerHTML = "<span class='alert'>処理中にエラーが発生しました。再度申請してください</span>";
 }

こうすることで、

  • エラーが発生したら、アラートポップアップに情報を表示してくれる
  • エラー時にLoading..文字が消えなくなってしまうのを強制的に消す
  • <div id=“alert”></div>を用意しておけば、エラーがあったことをユーザーに知らせる

ことができます。

トリッキーな部分もあったりしますが、開発してみるとその便利性は大きいです。 バックエンド開発などには今後積極的に導入する予定です。

# フロントエンド系はブラウザ検証や、スタイルシートによる画面遷移になるので、
# 正直厳しいかもなぁって感じですね。

1) サンプルの関数でもいいですが、再帰処理したいのとiconvが使われているので。。
php/pear/html_ajax.txt · 最終更新: 2008/04/24 00:11 (外部編集)
chimeric.de = chi`s home Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0