<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>へびにっき &#187; PHP</title>
	<atom:link href="http://wp.serpere.info/archives/tag/php/feed" rel="self" type="application/rss+xml" />
	<link>http://wp.serpere.info</link>
	<description>樹上で暮らすヘビのように生きたい</description>
	<lastBuildDate>Thu, 09 Feb 2012 11:35:51 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>CakePHPのデータベース情報を使ってmysqlコマンドで接続する</title>
		<link>http://wp.serpere.info/archives/1745</link>
		<comments>http://wp.serpere.info/archives/1745#comments</comments>
		<pubDate>Fri, 03 Sep 2010 08:36:50 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1745</guid>
		<description><![CDATA[環境: CakePHP 1.3 CakePHPでの開発中、コマンドラインから直接SQLを実行したいことがままあるので、CakePHPのdatabase.phpから情報を取得してmysqlコマンドで接続するためのシェルスクリプトを作った（要CLI版php）。 connect_db.sh 何もオプションを指定しなければそのままmysqlのインタラクティブシェルに入る。 ./connect_db.sh コマンドライン引数はそのままmysqlコマンドに渡されるので、例えば -e オプションを使うとそのままSQLを実行できる。 ./connect_db.sh -e 'select * from users' 標準では default 接続が使われる。その他の接続設定を使いたい場合は connect_db.sh に対して connect_db_{接続名} という名前でシンボリックリンクを作る。 # DATABASE_CONFIG-&#62;test に接続 ln -s connect_db.sh connect_db_test ./connect_db_test 私の場合 app と同じ階層に bin というディレクトリを作ってそこにシェルスクリプトを置いているので、パスもそれに合わせてある。異なるディレクトリ構成で使う場合は最初のAPPの定義を適宜書き換える。]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1745%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2F9wndsM%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22CakePHP%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E6%83%85%E5%A0%B1%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6mysql%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B%22%20%7D);"></div>
<p>
環境: CakePHP 1.3
</p>
<p>
CakePHPでの開発中、コマンドラインから直接SQLを実行したいことがままあるので、CakePHPのdatabase.phpから情報を取得してmysqlコマンドで接続するためのシェルスクリプトを作った（要CLI版php）。
</p>
<p><a href="http://gist.github.com/563613">connect_db.sh</a></p>
<p>
何もオプションを指定しなければそのままmysqlのインタラクティブシェルに入る。
</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>connect_db.sh</pre></div></div>



<p>
コマンドライン引数はそのままmysqlコマンドに渡されるので、例えば -e オプションを使うとそのままSQLを実行できる。
</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>connect_db.sh <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'select * from users'</span></pre></div></div>



<p>
標準では default 接続が使われる。その他の接続設定を使いたい場合は connect_db.sh に対して connect_db_{接続名} という名前でシンボリックリンクを作る。
</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># DATABASE_CONFIG-&gt;test に接続</span>
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> connect_db.sh connect_db_test
.<span style="color: #000000; font-weight: bold;">/</span>connect_db_test</pre></div></div>



<p>
私の場合 app と同じ階層に bin というディレクトリを作ってそこにシェルスクリプトを置いているので、パスもそれに合わせてある。異なるディレクトリ構成で使う場合は最初のAPPの定義を適宜書き換える。
</p>
]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1745/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>フィールドの値をシリアライズするSerializableビヘイビア</title>
		<link>http://wp.serpere.info/archives/1727</link>
		<comments>http://wp.serpere.info/archives/1727#comments</comments>
		<pubDate>Fri, 20 Aug 2010 09:03:18 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1727</guid>
		<description><![CDATA[環境: CakePHP 1.3 特定のフィールドの値をシリアライズしてから保存する Serializable ビヘイビアを作りました。配列などの構造を持つデータを、ひとつのフィールドに保存することができます。 serializable.php &#8211; gist （いずれ正式なリポジトリに移すかもしれない） fields オプションに指定したフィールドがsave時にJSONでエンコードして保存され、find時には自動的にデコードされます（PHP標準の serialize ではなくJSONを使用するのは互換性を重視しているため）。 var $actsAs = array&#40;'Serializable' =&#62; array&#40;'fields' =&#62; array&#40;'field1', 'field2'&#41;&#41;&#41;; &#160; // 保存する前に自動的にJSONエンコードされる $Model-&#62;save&#40;array&#40; 'field1' =&#62; array&#40;1,2,3&#41;, 'field2' =&#62; array&#40;'assoc' =&#62; 'data'&#41; &#41;&#41;; &#160; // find時に自動でデコードされる $values = $Model-&#62;find&#40;'first'&#41;; // field1 == array(1,2,3) // field2 == array('assoc' =&#62; 'data') この種のフィールド・シリアライズには様々なバリエーションが考えられます： JSON以外の形式でエンコードする 複数のフィールドの値をひとつにまとめて保存する [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1727%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FbZKiOc%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%81%AE%E5%80%A4%E3%82%92%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3%82%BA%E3%81%99%E3%82%8BSerializable%E3%83%93%E3%83%98%E3%82%A4%E3%83%93%E3%82%A2%22%20%7D);"></div>
<p>環境: CakePHP 1.3</p>
<p>
特定のフィールドの値をシリアライズしてから保存する Serializable ビヘイビアを作りました。配列などの構造を持つデータを、ひとつのフィールドに保存することができます。
</p>
<p>
<a href="http://gist.github.com/539919">serializable.php</a> &#8211; gist<br />
（いずれ正式なリポジトリに移すかもしれない）
</p>
<p>
fields オプションに指定したフィールドがsave時にJSONでエンコードして保存され、find時には自動的にデコードされます（PHP標準の serialize ではなくJSONを使用するのは互換性を重視しているため）。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$actsAs</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Serializable'</span>
  <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'fields'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'field1'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'field2'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// 保存する前に自動的にJSONエンコードされる</span>
<span style="color: #000088;">$Model</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
  <span style="color: #0000ff;">'field1'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'field2'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'assoc'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'data'</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// find時に自動でデコードされる</span>
<span style="color: #000088;">$values</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$Model</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'first'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// field1 == array(1,2,3)</span>
<span style="color: #666666; font-style: italic;">// field2 == array('assoc' =&gt; 'data')</span></pre></div></div>



<p>
この種のフィールド・シリアライズには様々なバリエーションが考えられます：
</p>
<ul>
<li>JSON以外の形式でエンコードする</li>
<li>複数のフィールドの値をひとつにまとめて保存する</li>
<li>シリアライズしたフィールドを別のモデルにマップして、hasOne関連のように扱えるようにする</li>
</ul>
<p>
このbehaviorは最も単純な作りになっているので、適当なメソッドを上書きすれば上のような動作も実現できるのではないかと思います。
</p>

]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1727/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>動的にコールバックを設定するObservableビヘイビア</title>
		<link>http://wp.serpere.info/archives/1722</link>
		<comments>http://wp.serpere.info/archives/1722#comments</comments>
		<pubDate>Thu, 19 Aug 2010 13:31:10 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1722</guid>
		<description><![CDATA[環境: CakePHP 1.3 モデル用のコールバック関数を動的に登録/解除できるようにする Observable Behaviorを作りました。コールバックを使用するためだけにサブクラスを作ったりビヘイビアを作ったりする必要がなくなります。 observable.php &#8211; gist （いずれ正式なリポジトリに移すかもしれない） callable なオブジェクトなら何でもコールバックとして使用できますが、PHP 5.3のクロージャと組み合わせると特に便利です。 $actsAs = array&#40;'Observable'&#41;; &#160; // addObserver メソッドで登録。戻り値は一意なid $oid = $Model-&#62;addObserver&#40;'beforeSave', function&#40;$model&#41; &#123; &#160; // 第1引数はモデル、それ以後は通常のコールバック引数 $model-&#62;data&#91;$model-&#62;alias&#93; = ....; &#160; // false を返すとコールバックの実行が停止する // 何も返さなかった場合（null）は true を返したのと同じことになる //return false; &#125;&#41;; &#160; // 不要になったら取り除く $Model-&#62;removeObserver&#40;$oid&#41;; コメント中にもある通り、明示的に引数を返さなかった場合は true と見なされるので、 beforeSave や beforeValidate で戻り値を忘れてその後の処理が実行されない……といったことはありません。]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1722%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2Fbloyjb%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22%E5%8B%95%E7%9A%84%E3%81%AB%E3%82%B3%E3%83%BC%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8BObservable%E3%83%93%E3%83%98%E3%82%A4%E3%83%93%E3%82%A2%22%20%7D);"></div>
<p>環境: CakePHP 1.3</p>
<p>
モデル用のコールバック関数を動的に登録/解除できるようにする Observable Behaviorを作りました。コールバックを使用するためだけにサブクラスを作ったりビヘイビアを作ったりする必要がなくなります。
</p>
<p>
<a href="http://gist.github.com/537867">observable.php</a> &#8211; gist<br />
（いずれ正式なリポジトリに移すかもしれない）
</p>
<p>
callable なオブジェクトなら何でもコールバックとして使用できますが、PHP 5.3のクロージャと組み合わせると特に便利です。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$actsAs</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Observable'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// addObserver メソッドで登録。戻り値は一意なid</span>
<span style="color: #000088;">$oid</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$Model</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addObserver</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'beforeSave'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$model</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// 第1引数はモデル、それ以後は通常のコールバック引数</span>
    <span style="color: #000088;">$model</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">data</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$model</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">alias</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #339933;">....;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// false を返すとコールバックの実行が停止する</span>
    <span style="color: #666666; font-style: italic;">// 何も返さなかった場合（null）は true を返したのと同じことになる</span>
    <span style="color: #666666; font-style: italic;">//return false;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// 不要になったら取り除く</span>
<span style="color: #000088;">$Model</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">removeObserver</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$oid</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
コメント中にもある通り、明示的に引数を返さなかった場合は true と見なされるので、 beforeSave や beforeValidate で戻り値を忘れてその後の処理が実行されない……といったことはありません。
</p>
]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1722/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP 5.3で共通鍵暗号（openssl）を使用する</title>
		<link>http://wp.serpere.info/archives/1388</link>
		<comments>http://wp.serpere.info/archives/1388#comments</comments>
		<pubDate>Sun, 01 Aug 2010 13:13:36 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[暗号]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1388</guid>
		<description><![CDATA[5.2以前でも使用できるmcryptについてはこちら。 PHP 5.3でopensslモジュールの機能が拡張され、共通鍵暗号による暗号化が利用可能になった。同時に待望の疑似乱数生成器も用意された。これで今までmcryptが使用できなかったWindowsでも、暗号学的強度を持った乱数が生成できる（実際に試していないが、OpenSSLはWindowsのCryptAPIから乱数を得ている）。 まだマニュアルにも詳しい情報が載っていないので、ソースを読みながら使い方を探ってみた。以下はphp-5.3.3のソースに基づく。ただしコミットログを見る限り仕様も機能もまだ安定しているとは言いがたいので、実際に使用するにはもう少し様子を見た方が良いかもしれない。 暗号化する際に決めておくべきこと： 鍵（以下 KEY）… マニュアルでは $password と表記されているが、いわゆる「パスワード」ではない。暗号化に使用する鍵であり、十分にランダムでなければならない。 暗号アルゴリズム＋モード（以下 CIPHER）… 利用可能な一覧は openssl_get_cipher_methods から得られる。 暗号化/復号を行う関数 encrypt/decrypt は次のようになる。 //実際の暗号化/復号を行う補助関数 function _callOpenSSL&#40;$func, $msg, $iv&#41; &#123; $opensslFunc = &#34;openssl_{$func}&#34;; return $opensslFunc&#40;$msg, CIPHER, KEY, true, $iv&#41;; &#125;; &#160; /** * @param string 暗号化したいメッセージ * @return array (暗号文, 初期化ベクトル) の配列 */ function encrypt&#40;$msg&#41; &#123; //初期化ベクトルを生成 $ivSize = openssl_cipher_iv_length&#40;CIPHER&#41;; $iv [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1388%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2F9991Jz%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22PHP%205.3%E3%81%A7%E5%85%B1%E9%80%9A%E9%8D%B5%E6%9A%97%E5%8F%B7%EF%BC%88openssl%EF%BC%89%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%22%20%7D);"></div>
<p>
5.2以前でも使用できるmcryptについては<a href="http://wp.serpere.info/archives/379">こちら</a>。
</p><p>
PHP 5.3でopensslモジュールの機能が拡張され、共通鍵暗号による暗号化が利用可能になった。同時に待望の疑似乱数生成器も用意された。これで今までmcryptが使用できなかったWindowsでも、暗号学的強度を持った乱数が生成できる（実際に試していないが、OpenSSLはWindowsのCryptAPIから乱数を得ている）。
</p><p>
まだマニュアルにも詳しい情報が載っていないので、ソースを読みながら使い方を探ってみた。以下はphp-5.3.3のソースに基づく。ただしコミットログを見る限り仕様も機能もまだ安定しているとは言いがたいので、実際に使用するにはもう少し様子を見た方が良いかもしれない。
</p><p>
暗号化する際に決めておくべきこと：
</p>
<ul>
<li>鍵（以下 KEY）… マニュアルでは <code>$password</code> と表記されているが、いわゆる「パスワード」ではない。暗号化に使用する鍵であり、十分にランダムでなければならない。</li>
<li>暗号アルゴリズム＋モード（以下 CIPHER）… 利用可能な一覧は openssl_get_cipher_methods から得られる。</li>
</ul>
<p>
暗号化/復号を行う関数 encrypt/decrypt は次のようになる。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//実際の暗号化/復号を行う補助関数</span>
<span style="color: #000000; font-weight: bold;">function</span> _callOpenSSL<span style="color: #009900;">&#40;</span><span style="color: #000088;">$func</span><span style="color: #339933;">,</span> <span style="color: #000088;">$msg</span><span style="color: #339933;">,</span> <span style="color: #000088;">$iv</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$opensslFunc</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;openssl_<span style="color: #006699; font-weight: bold;">{$func}</span>&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$opensslFunc</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$msg</span><span style="color: #339933;">,</span> CIPHER<span style="color: #339933;">,</span> <span style="color: #990000;">KEY</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #000088;">$iv</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * @param string  暗号化したいメッセージ
 * @return array  (暗号文, 初期化ベクトル) の配列
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> encrypt<span style="color: #009900;">&#40;</span><span style="color: #000088;">$msg</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//初期化ベクトルを生成</span>
    <span style="color: #000088;">$ivSize</span> <span style="color: #339933;">=</span> openssl_cipher_iv_length<span style="color: #009900;">&#40;</span>CIPHER<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$iv</span> <span style="color: #339933;">=</span> openssl_random_pseudo_bytes<span style="color: #009900;">&#40;</span><span style="color: #000088;">$ivSize</span><span style="color: #339933;">,</span> <span style="color: #000088;">$cryptStrong</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$iv</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #000088;">$cryptStrong</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// 乱数生成失敗</span>
        <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//ダミーの初期化ベクトル</span>
    <span style="color: #000088;">$dummyIV</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_repeat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;x&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ivSize</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//メッセージの暗号化</span>
    <span style="color: #000088;">$cryptMsg</span> <span style="color: #339933;">=</span> _callOpenSSL<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'encrypt'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$msg</span><span style="color: #339933;">,</span> <span style="color: #000088;">$iv</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//初期化ベクトルの暗号化</span>
    <span style="color: #000088;">$cryptIV</span> <span style="color: #339933;">=</span> _callOpenSSL<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'encrypt'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$iv</span><span style="color: #339933;">,</span> <span style="color: #000088;">$dummyIV</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$cryptMsg</span><span style="color: #339933;">,</span> <span style="color: #000088;">$cryptIV</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * @param string  暗号文
 * @param string  初期化ベクトル
 * @return string  平文
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> decrypt<span style="color: #009900;">&#40;</span><span style="color: #000088;">$cryptMsg</span><span style="color: #339933;">,</span> <span style="color: #000088;">$cryptIV</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//ダミーの初期化ベクトルを生成</span>
    <span style="color: #000088;">$ivSize</span> <span style="color: #339933;">=</span> openssl_cipher_iv_length<span style="color: #009900;">&#40;</span>CIPHER<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$dummyIV</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_repeat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;x&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ivSize</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//初期化ベクトルの復号</span>
    <span style="color: #000088;">$iv</span> <span style="color: #339933;">=</span> _callOpenSSL<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'decrypt'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$cryptIV</span><span style="color: #339933;">,</span> <span style="color: #000088;">$dummyIV</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//メッセージの復号</span>
    <span style="color: #000088;">$msg</span> <span style="color: #339933;">=</span> _callOpenSSL<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'decrypt'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$cryptMsg</span><span style="color: #339933;">,</span> <span style="color: #000088;">$iv</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$msg</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>



実行：


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'CIPHER'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'aes-128-cbc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'KEY'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'...暗号化のキー...'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$msg</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;めっせーじ&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// 暗号化</span>
<span style="color: #000088;">$crypt</span> <span style="color: #339933;">=</span> encrypt<span style="color: #009900;">&#40;</span><span style="color: #000088;">$msg</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">bin2hex</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$crypt</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// 復号</span>
<span style="color: #000088;">$plain</span> <span style="color: #339933;">=</span> decrypt<span style="color: #009900;">&#40;</span><span style="color: #000088;">$crypt</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$crypt</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$plain</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
mcrytと違ってブロック長に合わせたパディング（PKCS#5パディング）はopensslが自動でやってくれるので、自前でbase64エンコードしたりする必要はない。
</p><p>
openssl_random_pseudo_bytes の戻り値は、乱数の生成に失敗した場合は真偽値の false になる。また十分なエントロピーが得られなかった場合は第二引数に指定した変数が false になる（ただ滅多に起こらないはずである:<a href="http://www.openssl.org/support/faq.html#USER1">OpenSSL FAQ</a>参照）。
</p><p>
ちなみに鍵の生成も openssl_random_pseudo_bytes で行えばいい。
</p>
<pre>
#コマンドラインにて16バイト=128ビットの乱数を生成
$ php -r 'echo base64_encode(openssl_random_pseudo_bytes(16));
bONq0KiSNIO5ww1ggwdFdQ==

//定数KEYの定義
define('KEY', base64_decode('bONq0KiSNIO5ww1ggwdFdQ=='));
</pre>
<p>
パスワードから鍵を生成する必要がある場合は、自分でPBKDFを実装する必要がある。『PHP PBKDF2』で検索するといくらか実装例が見つかるようだ。またRubyの pkcs5_keyivgen（openssl の EVP_BytesToKey）互換の機能が必要な場合は<a href="http://wp.serpere.info/archives/422">OpenSSL::Cipher::Cipher#pkcs5_keyivgen の中身</a>などを参照のこと。
</p>
<h2>openssl_random_pseudo_bytes の中身</h2>
<p>
実体はOpenSSLの RAND_pseudo_bytes(rand_lib.c) -> ssleay_rand_pseudo_bytes(md_rand.c) -> ssleay_rand_bytes(md_rand.c) で、そこから先は『<a href="http://wp.serpere.info/archives/512">暗号乱数インフラの初期化処理</a>』を参照のこと。
</p><p>
ssleay_rand_pseudo_bytes と ssleay_rand_bytes の違いは RAND_R_PRNG_NOT_SEEDED を見逃すか否か。エラーがあったこと自体は戻り値で判定できるので、$crypto_strong ではこれを利用している。
</p>

]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1388/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CakeのURLパラメータに特殊文字を使ってはいけない</title>
		<link>http://wp.serpere.info/archives/1367</link>
		<comments>http://wp.serpere.info/archives/1367#comments</comments>
		<pubDate>Fri, 09 Jul 2010 09:12:31 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1367</guid>
		<description><![CDATA[環境: CakePHP 1.3 CakePHPはURLパラメータのエンコードを一切行わないため、特殊な文字がパラメータに入り込むと容易にルーティングが破綻する。ここで言う「URLパラメータ」とはRoute中に埋め込まれたパラメータ、namedパラメータ、passパラメータのことを指す。 例えば以下のようなRouteがあったとする。 /controller/action/:keyword ここでパラメータkeywordに特殊な文字を与えると… keyword => '%' URL: /controller/action/% 結果: URLとして不正な形式なので"400 Bad Request"になる keyword => '?foo' URL: /controller/action/?foo 結果: ?以降はQueryStringと見なされてルーティングから除外され、Routeにマッチしなくなる keyword => 'a/b/c' URL: /controller/action/a/b/c 結果: /がそのままパラメータ区切りになるのでRouteにマッチしなくなる この問題は単純に rawurlencode/rawurldecode を使うだけでは回避できない。またCakeの設計上の問題なので、簡単な修正方法もない。よって任意の文字が含まれる可能性のあるパラメータをURLに埋め込んではいけない。最も簡単な回避策は、URLパラメータを諦めてQueryStringを使うことである。 Router::url&#40;array&#40;'?' =&#62; array&#40;'keyword' =&#62; $any_characters&#41;&#41;&#41;; 問題の原因と回避策の考察 なぜ rawurlencode で回避できないかというと、CakePHPが mod_rewrite 経由で $_GET['url'] から元のURLを取得しているからだ。 RewriteRule ^(.*)$ index.php?url=$1 [QSA,L] RewriteRuleの後方参照（$1の部分）では%エンコーディングのデコードが行われる。またQueryStringから $_GET に格納される際にもPHPによってデコードが行われる。つまりCakeのルーティングが実行される前に、既に2回のデコードが行われている。よってもしこの問題を rawurlencode で回避するなら、3重に [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1367%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FankpK2%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Cake%E3%81%AEURL%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%AB%E7%89%B9%E6%AE%8A%E6%96%87%E5%AD%97%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%AF%E3%81%84%E3%81%91%E3%81%AA%E3%81%84%22%20%7D);"></div>
<p>
環境: CakePHP 1.3
</p>
<p>
CakePHPはURLパラメータのエンコードを<strong>一切</strong>行わないため、特殊な文字がパラメータに入り込むと容易にルーティングが破綻する。ここで言う「URLパラメータ」とはRoute中に埋め込まれたパラメータ、namedパラメータ、passパラメータのことを指す。
</p>
<p>
例えば以下のようなRouteがあったとする。
</p>
<pre>
/controller/action/:keyword
</pre>
<p>
ここでパラメータkeywordに特殊な文字を与えると…
</p>
<pre>
keyword => '%'
URL: /controller/action/%
結果: URLとして不正な形式なので"400 Bad Request"になる
</pre>
<pre>
keyword => '?foo'
URL: /controller/action/?foo
結果: ?以降はQueryStringと見なされてルーティングから除外され、Routeにマッチしなくなる
</pre>
<pre>
keyword => 'a/b/c'
URL: /controller/action/a/b/c
結果: /がそのままパラメータ区切りになるのでRouteにマッチしなくなる
</pre>
<p>
この問題は単純に rawurlencode/rawurldecode を使うだけでは回避できない。またCakeの設計上の問題なので、簡単な修正方法もない。よって<strong>任意の文字が含まれる可能性のあるパラメータをURLに埋め込んではいけない</strong>。最も簡単な回避策は、URLパラメータを諦めてQueryStringを使うことである。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">Router<span style="color: #339933;">::</span><span style="color: #004000;">url</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'?'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'keyword'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$any_characters</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<h3>問題の原因と回避策の考察</h3>
<p>
なぜ rawurlencode で回避できないかというと、CakePHPが mod_rewrite 経由で <code>$_GET['url']</code> から元のURLを取得しているからだ。
</p>
<pre>
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</pre>
<p>
<a href="http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule">RewriteRule</a>の後方参照（$1の部分）では%エンコーディングのデコードが行われる。またQueryStringから $_GET に格納される際にもPHPによってデコードが行われる。つまりCakeのルーティングが実行される前に、既に2回のデコードが行われている。よってもしこの問題を rawurlencode で回避するなら、3重に rawurlencode した上で rawurldecode しなければならない、ということになる。
</p>
<p>
ちなみに RewriteRule の[B]オプションを指定することで後方参照のデコードを回避することができる。この場合は rawurlencode は2回で済む。しかしそれでもURLが汚くなることは変わりないし、検索エンジンのロボット等もURL中の文字列を認識してくれないだろう。
</p>
<pre>
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L,B]
</pre>
<p>
別の考え方として、%エンコーディング以外の安全なエンコーディングを用いる方法もある。例えば16進数のバイナリ表現に変換すれば、[a-f0-9]しか現れないので確実に安全である。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$encoded</span> <span style="color: #339933;">=</span> <span style="color: #990000;">bin2hex</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//[0-9a-f]しか含まれないことを事前にチェックしておくこと</span>
<span style="color: #000088;">$decoded</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pack</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'H*'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$encoded</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
ただしこの方法だと長さは元の文字列の2倍になるし、可読性も全く損なわれる。ここまでするくらいならやはりQueryStringを使った方が良いと思う。
</p>
]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1367/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>グローバル関数のMockを作る</title>
		<link>http://wp.serpere.info/archives/1315</link>
		<comments>http://wp.serpere.info/archives/1315#comments</comments>
		<pubDate>Thu, 10 Jun 2010 10:44:57 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1315</guid>
		<description><![CDATA[CakePHP 1.3 + SimpleTestでグローバル関数をMock化するためのラッパークラスを作ってみました。libs/ に置いて使用します。 global_function.php &#8211; gist 次のように任意の関数を呼び出せます。 //bootstrap.php 等で読み込んでおく App::import&#40;'Lib', 'GlobalFunction'&#41;; &#160; GlobalFunction&#40;&#41;-&#62;env&#40;'REMOTE_ADDR'&#41;; GlobalFunction&#40;&#41;-&#62;gethostbyname&#40;'example.com'&#41;; テストケースでMockを使用したいとき、GlobalFunction::registerMock を呼び出します。戻り値はMockオブジェクトです。 function testRegisterMock&#40;&#41; &#123; //使用する関数名を引数に渡す $mock = GlobalFunction::registerMock&#40;'env', 'gethostbyname'&#41;; &#160; //通常のmockと同様に使用できる $returnValue = '192.168.0.1'; $mock-&#62;expectOnce&#40;'env', array&#40;'REMOTE_ADDR'&#41;&#41;; $mock-&#62;setReturnValue&#40;'env', $returnValue, array&#40;'REMOTE_ADDR'&#41;&#41;; $mock-&#62;expectNever&#40;'gethostbyname'&#41;; &#160; $this-&#62;assertEqual&#40;$returnValue, GlobalFunction&#40;&#41;-&#62;env&#40;'REMOTE_ADDR'&#41;&#41;; &#160; //ClassRegistry::flush を呼び出せば元に戻る ClassRegistry::flush&#40;&#41;; &#160; //本物の関数envが呼ばれる $addr = GlobalFunction&#40;&#41;-&#62;env&#40;'REMOTE_ADDR'&#41;; &#125; 注意：参照を引数に取る関数（array_push など）は使用できません。]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1315%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2F91zy0d%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E9%96%A2%E6%95%B0%E3%81%AEMock%E3%82%92%E4%BD%9C%E3%82%8B%22%20%7D);"></div>
<p>
CakePHP 1.3 + SimpleTestでグローバル関数をMock化するためのラッパークラスを作ってみました。libs/ に置いて使用します。
</p>
<p><a href="http://gist.github.com/432809">global_function.php &#8211; gist</a></p>
<p>
次のように任意の関数を呼び出せます。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//bootstrap.php 等で読み込んでおく</span>
App<span style="color: #339933;">::</span><span style="color: #004000;">import</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Lib'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'GlobalFunction'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
GlobalFunction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">env</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'REMOTE_ADDR'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
GlobalFunction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">gethostbyname</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'example.com'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
テストケースでMockを使用したいとき、GlobalFunction::registerMock を呼び出します。戻り値はMockオブジェクトです。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> testRegisterMock<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//使用する関数名を引数に渡す</span>
    <span style="color: #000088;">$mock</span> <span style="color: #339933;">=</span> GlobalFunction<span style="color: #339933;">::</span><span style="color: #004000;">registerMock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'env'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gethostbyname'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//通常のmockと同様に使用できる</span>
    <span style="color: #000088;">$returnValue</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'192.168.0.1'</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">expectOnce</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'env'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'REMOTE_ADDR'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setReturnValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'env'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$returnValue</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'REMOTE_ADDR'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$mock</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">expectNever</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'gethostbyname'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEqual</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$returnValue</span><span style="color: #339933;">,</span> GlobalFunction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">env</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'REMOTE_ADDR'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//ClassRegistry::flush を呼び出せば元に戻る</span>
    ClassRegistry<span style="color: #339933;">::</span><span style="color: #990000;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//本物の関数envが呼ばれる</span>
    <span style="color: #000088;">$addr</span> <span style="color: #339933;">=</span> GlobalFunction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">env</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'REMOTE_ADDR'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>



<p>
注意：参照を引数に取る関数（array_push など）は使用できません。
</p>
]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1315/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>find(&#8216;list&#8217;) で集約関数を使用する方法</title>
		<link>http://wp.serpere.info/archives/1247</link>
		<comments>http://wp.serpere.info/archives/1247#comments</comments>
		<pubDate>Tue, 18 May 2010 12:14:11 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1247</guid>
		<description><![CDATA[単に field パラメータに指定するだけではうまく動作しないので、一旦 find(&#8216;all&#8217;) で結果を取得してから Set::combine を使って同等の構造を得る。 // user_id =&#62; 件数 $tmp = $Post-&#62;find&#40;'all', array&#40;'fields' =&#62; array&#40;'user_id', 'COUNT(*) AS posts_count'&#41;, 'group' =&#62; 'user_id'&#41;&#41;; return Set::combine&#40;$tmp, '{n}.Post.user_id', '{n}.0.posts_count'&#41;; Set::combine は恐ろしく多機能なので、find(&#8216;list&#8217;) をそのまま使うよりずっと多くの事ができる。例えば次のように、複数カラムで GROUP BY した結果をフラットな配列にまとめることができる。 // &#34;user_id:category_id&#34; =&#62; 件数 $tmp = $Post-&#62;find&#40;'all', array&#40;'fields' =&#62; array&#40;'user_id', 'category_id', 'COUNT(*) AS posts_count'&#41;, 'group' =&#62; array&#40;'user_id', 'category_id'&#41;&#41;&#41;; return Set::combine&#40;$tmp, array&#40;'{0}:{1}', '{n}.Post.user_id', [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1247%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FaKBNtb%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22find%28%27list%27%29%20%E3%81%A7%E9%9B%86%E7%B4%84%E9%96%A2%E6%95%B0%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%22%20%7D);"></div>
<p>
単に field パラメータに指定するだけではうまく動作しないので、一旦 find(&#8216;all&#8217;) で結果を取得してから <a href="http://book.cakephp.org/view/1492/combine">Set::combine</a> を使って同等の構造を得る。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// user_id =&gt; 件数</span>
<span style="color: #000088;">$tmp</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$Post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'all'</span><span style="color: #339933;">,</span>
                   <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'fields'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user_id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'COUNT(*) AS posts_count'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                         <span style="color: #0000ff;">'group'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'user_id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> Set<span style="color: #339933;">::</span><span style="color: #004000;">combine</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tmp</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'{n}.Post.user_id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'{n}.0.posts_count'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
Set::combine は恐ろしく多機能なので、find(&#8216;list&#8217;) をそのまま使うよりずっと多くの事ができる。例えば次のように、複数カラムで GROUP BY した結果をフラットな配列にまとめることができる。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// &quot;user_id:category_id&quot; =&gt; 件数</span>
<span style="color: #000088;">$tmp</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$Post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'all'</span><span style="color: #339933;">,</span>
                   <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'fields'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user_id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'category_id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'COUNT(*) AS posts_count'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                         <span style="color: #0000ff;">'group'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user_id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'category_id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> Set<span style="color: #339933;">::</span><span style="color: #004000;">combine</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tmp</span><span style="color: #339933;">,</span>
                    <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'{0}:{1}'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'{n}.Post.user_id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'{n}.Post.category_id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                    <span style="color: #0000ff;">'{n}.0.posts_count'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
値を連想配列にする事もできる。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// user_id =&gt; array(&quot;created_max&quot; =&gt; 最大値, &quot;created_min&quot; =&gt; 最小値)</span>
<span style="color: #000088;">$tmp</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$Post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'all'</span><span style="color: #339933;">,</span>
                   <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'fields'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user_id'</span><span style="color: #339933;">,</span>
                                           <span style="color: #0000ff;">'MAX(created) AS created_max'</span><span style="color: #339933;">,</span>
                                           <span style="color: #0000ff;">'MIN(created) AS created_min'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                         <span style="color: #0000ff;">'group'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'user_id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> Set<span style="color: #339933;">::</span><span style="color: #004000;">combine</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tmp</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'{n}.Post.user_id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'{n}.0'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>




]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1247/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>動的にコンポーネントを読み込むコンポーネント</title>
		<link>http://wp.serpere.info/archives/1138</link>
		<comments>http://wp.serpere.info/archives/1138#comments</comments>
		<pubDate>Tue, 06 Apr 2010 13:03:20 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1138</guid>
		<description><![CDATA[CakePHP1.3で動的にコンポーネントを読み込むためのコンポーネント DynamicComponent を作成しました。 cakephp-dynamic-component 注意: Cake本来の機能を超える機能を提供するため、Cakeコアのprivateなメソッドやプロパティにアクセスしています。Cakeのバージョンが上がると使用できなくなる可能性があります。十分ご注意ください。 このコンポーネントを使うと次のようなことが可能になります： admin プレフィクスが付いているときだけ Auth コンポーネントを読み込む debug > 0 のときだけ DebugKit を読み込む 読み込みはコントローラの _initialize メソッドで loadComponents メソッドを使って行います。 class AppController extends Controller &#123; var $components = array&#40;'DynamicComponent.Dynamic'&#41;; &#160; function _initialize&#40;&#41; &#123; if&#40;!empty&#40;$this-&#62;params&#91;&#34;prefix&#34;&#93;&#41; &#38;&#38; $this-&#62;params&#91;&#34;prefix&#34;&#93; == 'admin'&#41; &#123; $this-&#62;Dynamic-&#62;loadComponents&#40;'Auth'&#41;; &#125; if&#40;Configure::read&#40;'debug'&#41; &#62; 0&#41; &#123; $this-&#62;Dynamic-&#62;loadComponents&#40;'DebugKit.Toolbar'&#41;; &#125; &#125; &#125; この方法で読み込んだコンポーネントの initialize メソッドからは、さらに別のコンポーネントを読み込むことができます。そのためコントローラから直接 Auth [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1138%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FdyVwVz%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22%E5%8B%95%E7%9A%84%E3%81%AB%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%22%20%7D);"></div>
<p>
CakePHP1.3で動的にコンポーネントを読み込むためのコンポーネント DynamicComponent を作成しました。
</p>
<p><a href="http://github.com/tkyk/cakephp-dynamic-component">cakephp-dynamic-component</a></p>
<p>
<strong>注意:</strong> Cake本来の機能を超える機能を提供するため、Cakeコアのprivateなメソッドやプロパティにアクセスしています。Cakeのバージョンが上がると使用できなくなる可能性があります。十分ご注意ください。
</p>
<p>
このコンポーネントを使うと次のようなことが可能になります：
</p>
<ul>
<li>admin プレフィクスが付いているときだけ Auth コンポーネントを読み込む</li>
<li>debug > 0 のときだけ DebugKit を読み込む</li>
</ul>
<p>
読み込みはコントローラの _initialize メソッドで loadComponents メソッドを使って行います。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> AppController <span style="color: #000000; font-weight: bold;">extends</span> Controller
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$components</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DynamicComponent.Dynamic'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">function</span> _initialize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;prefix&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;prefix&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'admin'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Dynamic</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadComponents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Auth'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>Configure<span style="color: #339933;">::</span><span style="color: #004000;">read</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'debug'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Dynamic</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadComponents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DebugKit.Toolbar'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>



<p>
この方法で読み込んだコンポーネントの initialize メソッドからは、さらに別のコンポーネントを読み込むことができます。そのためコントローラから直接 Auth や DebugKit を読み込むよりは、状況に合わせた専用のコンポーネントを用意して、その中で Auth や DebugKit の読み込み・初期化を行うことをお勧めします。以下、Admin と Debug という2つのコンポーネントを作っています。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// app/controllers/components/admin.php</span>
<span style="color: #000000; font-weight: bold;">class</span> AdminComponent <span style="color: #000000; font-weight: bold;">extends</span> Object
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">function</span> initialize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$controller</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$controller</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Dynamic</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadComponents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Auth'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//Authコンポーネントのセットアップ</span>
    <span style="color: #000088;">$controller</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Auth</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loginAction</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #666666; font-style: italic;">/*...*/</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>





<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// app/controllers/components/debug.php</span>
<span style="color: #000000; font-weight: bold;">class</span> DebugComponent <span style="color: #000000; font-weight: bold;">extends</span> Object
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">function</span> initialize<span style="color: #009900;">&#40;</span><span style="color: #000088;">$controller</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$controller</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Dynamic</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadComponents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DebugKit.Toolbar'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//その他debugに有用な設定など</span>
    <span style="color: #000088;">$controller</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">...</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>



<p>
また prefix 名に応じた読み込みを行うオプションがあらかじめ用意されているので、コントローラの prefix 判定コードは省略できます。最終的に _initialize メソッドは次のようになります。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> AppController <span style="color: #000000; font-weight: bold;">extends</span> Controller
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$components</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DynamicComponent.Dynamic'</span>
                          <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'prefix'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">function</span> _initialize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>Configure<span style="color: #339933;">::</span><span style="color: #004000;">read</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'debug'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Dynamic</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadComponents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Debug'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>




]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1138/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP5.3の__callStaticをエミュレートする</title>
		<link>http://wp.serpere.info/archives/1115</link>
		<comments>http://wp.serpere.info/archives/1115#comments</comments>
		<pubDate>Fri, 05 Mar 2010 08:27:35 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1115</guid>
		<description><![CDATA[PHP 5.3.0 ではマジックメソッド __callStatic が追加された。グローバルに使用されるユーティリティクラスで、動的にメソッド名を生成したいときに便利。 class FooUtil &#123; static protected $_inc = array&#40;'test1' =&#62; 1, 'test2' =&#62; 2&#41;; &#160; public static function __callStatic&#40;$method, $args&#41; &#123; return isset&#40;static::$_inc&#91;$method&#93;&#41; ? static::$_inc&#91;$method&#93; + $args&#91;0&#93; : $args&#91;0&#93;; &#125; &#125; echo FooUtil::test1&#40;100&#41;; // =&#62; 101 echo FooUtil::test2&#40;100&#41;; // =&#62; 102 echo FooUtil::testxxx&#40;100&#41;; // =&#62; 100 同等の機能を PHP 5.2 より前の環境で再現したい場合、シングルトンパターンと __call [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1115%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FacGa4f%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22PHP5.3%E3%81%AE__callStatic%E3%82%92%E3%82%A8%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%22%20%7D);"></div>
<p>
PHP 5.3.0 ではマジックメソッド __callStatic が追加された。グローバルに使用されるユーティリティクラスで、動的にメソッド名を生成したいときに便利。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> FooUtil <span style="color: #009900;">&#123;</span>
  static <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$_inc</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'test1'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
				 <span style="color: #0000ff;">'test2'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> __callStatic<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span>static<span style="color: #339933;">::</span><span style="color: #000088;">$_inc</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
      ? static<span style="color: #339933;">::</span><span style="color: #000088;">$_inc</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>





<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> FooUtil<span style="color: #339933;">::</span><span style="color: #004000;">test1</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// =&gt; 101</span>
<span style="color: #b1b100;">echo</span> FooUtil<span style="color: #339933;">::</span><span style="color: #004000;">test2</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// =&gt; 102</span>
<span style="color: #b1b100;">echo</span> FooUtil<span style="color: #339933;">::</span><span style="color: #004000;">testxxx</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// =&gt; 100</span></pre></div></div>



<p>
同等の機能を PHP 5.2 より前の環境で再現したい場合、シングルトンパターンと __call を組み合わせるのが最も普通のやり方だと思う。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> FooUtil2 <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$_inc</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'test1'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
			  <span style="color: #0000ff;">'test2'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  static <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$__singleton</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> getInstance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$__singleton</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$__singleton</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$__singleton</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __call<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_inc<span style="color: #009900;">&#91;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
      ? <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_inc<span style="color: #009900;">&#91;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>





<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> FooUtil2<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">test1</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// =&gt; 101</span>
<span style="color: #b1b100;">echo</span> FooUtil2<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">test2</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// =&gt; 102</span>
<span style="color: #b1b100;">echo</span> FooUtil2<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">testxxx</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// =&gt; 100</span></pre></div></div>



<p>
この方法の欠点は「呼び出し時のコードが長い」ことである。そこで個人的にはクラス名と同じ名前の<strong>グローバル関数</strong>を使う方法を提案したい。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> FooUtil3<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  static <span style="color: #000088;">$singleton</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$singleton</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$singleton</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> FooUtil3<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #000088;">$singleton</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> FooUtil3 <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$_inc</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'test1'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
			  <span style="color: #0000ff;">'test2'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __call<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_inc<span style="color: #009900;">&#91;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
      ? <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_inc<span style="color: #009900;">&#91;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>





<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> FooUtil3<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">test1</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// =&gt; 101</span>
<span style="color: #b1b100;">echo</span> FooUtil3<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">test2</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// =&gt; 102</span>
<span style="color: #b1b100;">echo</span> FooUtil3<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">testxxx</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// =&gt; 100</span></pre></div></div>



<p>
この方法ならば __callStatic を使うのと比べて2文字長いだけだ。しかも他2つの方法よりもカプセル化の面では優れている。関数とクラスは「名前が同じ」というごく緩やかなつながりを持っているだけなので、静的な意味でも動的な意味でも、あとから自由に実装を切り替えられる。staticメソッドでなければならない、シングルトンでなければならない、といった制約はない。
</p><p>
これはグローバル変数や単純なレジストリ（CakePHPにおけるConfigureのような）を使うのとも違う。関数なので、どんな処理でも差し挟むことができる。関数の方がパラメータを持ってもいい。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">FooUtil4<span style="color: #009900;">&#40;</span><span style="color: #000088;">$context</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">test</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$parameters</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<p>
グローバル関数というと問題になるのは名前の衝突だが、関数名とクラス名では名前の傾向が異なるので、クラス名が衝突しないのであれば同じ名前の関数も衝突しない可能性が高いと考えられる。
</p>
<p>
あまり公のプロジェクトで採用する気にはならないが、内々に使うにはそれなりに便利なテクニックだと思う。
</p>
]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1115/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CakePHP 1.3RC1の新機能：プラグインdriver</title>
		<link>http://wp.serpere.info/archives/1114</link>
		<comments>http://wp.serpere.info/archives/1114#comments</comments>
		<pubDate>Tue, 02 Mar 2010 14:12:49 +0000</pubDate>
		<dc:creator>tkykmw</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://wp.serpere.info/?p=1114</guid>
		<description><![CDATA[せっかく私のpatchが採用されたので、ブログにも書いておきます。 CakePHP 1.3からはプラグイン内の DataSource が使えるようになりますが、1.3RC1からは DataSource の driver もプラグインから読み込めるようになりました。 たとえばGithubのCakePHP datasources pluginでは、Cakeコアに含まれない様々なデータベースに対するDboドライバが提供されていますが、RC1ではこれを次のようにして読み込むことができます。 class DATABASE_CONFIG &#123; var $sqlite3 = array&#40;'driver' =&#62; 'Datasources.DboSqlite3', ...&#41;; &#160; &#125; また driver を使用する DataSource をプラグインとして提供することも可能です。拙作のKeyValueSourceは次のように使用できます。 class DATABASE_CONFIG &#123; var $memcache = array&#40;'datasource' =&#62; 'KeyValueStore.KeyValueSource', 'driver' =&#62; 'KeyValueStore.KeyValueMemcache', ...&#41;; &#125; プラグインが読み込む driver を app/models/datasources 内に作ることもできます。たとえば memcache ドライバを拡張した my_memcache ドライバを作った場合、次のように読み込みます。 // app/models/datasources/key_value/key_value_my_memcache.php &#160; [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwp.serpere.info%252Farchives%252F1114%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2Fc5K3bh%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22CakePHP%201.3RC1%E3%81%AE%E6%96%B0%E6%A9%9F%E8%83%BD%EF%BC%9A%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3driver%22%20%7D);"></div>
<p>
せっかく私の<a href="http://cakephp.lighthouseapp.com/projects/42648/tickets/297-patchtest-plugin-datasource-drivers">patch</a>が採用されたので、ブログにも書いておきます。
</p>
<p>
CakePHP 1.3からはプラグイン内の DataSource が使えるようになりますが、1.3RC1からは DataSource の driver もプラグインから読み込めるようになりました。
</p>
<p>
たとえばGithubの<a href="http://github.com/cakephp/datasources">CakePHP datasources plugin</a>では、Cakeコアに含まれない様々なデータベースに対するDboドライバが提供されていますが、RC1ではこれを次のようにして読み込むことができます。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> DATABASE_CONFIG <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$sqlite3</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'driver'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Datasources.DboSqlite3'</span><span style="color: #339933;">,</span>
                       <span style="color: #339933;">...</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>



<p>
また driver を使用する DataSource をプラグインとして提供することも可能です。拙作の<a href="http://github.com/tkyk/cakephp-key-value-source">KeyValueSource</a>は次のように使用できます。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> DATABASE_CONFIG <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$memcache</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'datasource'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'KeyValueStore.KeyValueSource'</span><span style="color: #339933;">,</span>
                        <span style="color: #0000ff;">'driver'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'KeyValueStore.KeyValueMemcache'</span><span style="color: #339933;">,</span>
                        <span style="color: #339933;">...</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>



<p>
プラグインが読み込む driver を app/models/datasources 内に作ることもできます。たとえば memcache ドライバを拡張した my_memcache ドライバを作った場合、次のように読み込みます。
</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// app/models/datasources/key_value/key_value_my_memcache.php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> DATABASE_CONFIG <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$memcache</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'datasource'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'KeyValueStore.KeyValueSource'</span><span style="color: #339933;">,</span>
                        <span style="color: #0000ff;">'driver'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'my_memcache'</span><span style="color: #339933;">,</span>
                        <span style="color: #339933;">...</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>



]]></content:encoded>
			<wfw:commentRss>http://wp.serpere.info/archives/1114/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

