Hatena::ブログ(Diary)

$php→rails (rails に憧れる phper のブログ)

2007-09-25

ブログ移転しました

ちょっと思うところあってドメイン取りました。

せっかくなので、ブログもそっちに移します。

http://pm.11op.net/

こんなブログを購読してくれてて今後も購読してくれる

ステキな方はお手数ですが上記 URL への変更をよろしくお願いします。


でわ。

[][]手動でロケールを変更する方法

スクリプト内に以下記述を行うことでロケールの変更が可能。

        Configure::write('Config.language', 'ja');

参考サイトの記述を元に bootstrap.php

define('DEFAULT_LANGUAGE', 'en'); 

とかしても上手くいかないので、そんな時は手動で設定すればよい。

2007-09-18

[][]CakePHP の多言語対応でハマリ中

このサイトを参考に

http://bakery.cakephp.org/articles/view/p28n-the-top-to-bottom-persistent-internationalization-tutorial

extract コマンドで po ファイルを生成するところまではいけたけど、

言語の切り替えが上手くいかなくてハマリ中。


どうやっても日本語になってしまう。

まあいいけど。


あと、最初に生成されるファイルが default.pot で、それをそのまま

local/jpn/LC_MESSAGES にコピーしたら動かなくてハマった。


default.pot → default.po に改名しなきゃなのね。


※僕の cake は 1.2.0.5427alpha。

2007-09-17

[]ビリーズブートキャンプ入隊

今さら今さらだけど、ビリーズブートキャンプ始めてみた。

ビリ始め。


自分の場合、減量目的ではなくてむしろ増量目的だったりする。

スタート地点は 47 kg。


1日目は基本プログラムで脱落。

もちろん、チューブとかなし。

エアで。エアビリーで。


次回は1週間後の予定。それって意味ねえのかな。

2007-09-09

[]簡単に特定IPからのアクセス以外ならメンテナンス画面を出してみる

ウノウラボさんのエントリ、メンテナンス画面を簡単に出してみるを参考に、以下を .htaccess だけで実現してみる

  • 特定 IP からのアクセスは認証下で普通にサイト閲覧が可能
  • それ以外の IP からのアクセスなら、メンテナンス画面を表示


  1. まず、こういうことらしいので、何も考えずに 503 エラーを吐く 503.php を用意。
    mod_rewriteでは300番系のエラーを出すことができますが、503のエラーは出せないようなので メンテナンス画面を簡単に出してみる
  2. 次に、ドメイン下全てを 503 へ Rewrite してやる。
  3. その時に、「自分の IP 以外は」を付ける
  4. そのままでは不安なので、さらに自分の IP のみ、認証下に置く

以上を実現してみたのが、以下。

PHP の部分は丸パクリ。すいませんすいません。

503/503.php

<?php
    header ('HTTP/1.0 503 Service Temporarily Unavailable');
    include(dirname(__FILE__) . '/maintenance.html');
?>

503/maintenance.html

<html>
<body>
<h1>メンテナンス中ですよ</h1>
</body>
</html>

.htaccess

{*.*.*.*} のとこに、自分の IP を、 {path} のとこにパスワードファイルへの絶対 path を入れる

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REMOTE_ADDR} !{*.*.*.*}
    RewriteCond %{REQUEST_FILENAME} !503.php
    RewriteRule ^.*$ /503/503.php [L]
</IfModule>

AuthType Basic
AuthName "Restricted Area"
AuthUserFile /{path}/.htpasswd
require valid-user

Satisfy Any
Order Allow,Deny
Allow from all
Deny from {*.*.*.*}

.htaccess がややこしいけど、こんなことが起きてる(と思う)

  • IP 以外からのアクセスの場合
    1. 503/503.php に飛ばされる
    2. Satisfy Any の 「Allow from all」により認証は必要ないので、そのままメンテナンス画面が表示される
  • IP からのアクセスの場合
    1. 503/503.php には飛ばされない
    2. Satisfy Any の 「Deny from {*.*.*.*}」に該当するので、「require valid-user」を満たす必要がある
    3. パスワードを聞かれる

で、携帯片手に 503 になってることを確認しつつ、PC から設定作業を行うと。


うちは業務では FTP オンリーのレンタルサーバーを使用することがほとんどなので、

システムの入れ替え時にどうしてもサイトを落とす必要が発生してしまう。

設定途中のサイトにアクセスされるとまずいけど、誰もアクセスしないような深夜作業なんていやだしね。

(そもそも、問題の解決方法として間違ってると思うし)

ってことで考えたのがこの方法。

2007-09-05

[][][]CakePHP と asido を使った任意の画像を url の変更だけで任意のサイズで書き出す web アプリ

php の画像処理ライブラリasidoが便利そうだったのでひどい web アプリを作ってみた。

url でサイズと画像を指定したら、そのサイズでその画像を出力するアプリ

まず、元画像 500x334

これを、以下のような url でアクセスした時の画像


動作の説明がめんどいので、さらっと。

  • 元画像は ドキュメントルートからの絶対パス指定でも、http:// から始まる絶対パスでもok
  • url で指定されたサイズにリサイズする
  • 縦横比が異なる場合は、リサイズした上で画像の中心から指定サイズ分トリミングする
  • 元画像より大きいサイズを指定した場合は無視される
  • 本来は一度生成した画像はこの辺に書き出される→ http://pm11op.xii.jp/pm11op/anysizenizer/img/thumbs/test/100x100/
    • けど、借りてるサーバに得体の知れない画像が生成されるのは嫌なので、表示直後に unlink する富豪っぷり。
  • 中身は CakePHP と asido で動いてますよと。

一番下からダウンロードできますが、

実際に使用した際に発生したいかなる不利益も自己責任で処理してください。


ちょっと考えただけでも以下の問題点・改善すべき点があります。

まるっと一式 downlowd

2007-08-29

[]はてなダイアリーJavaScript eval ちょっと待って

盛り上がってるところ*1に水を差すようですが、

気になって仕事が手につきません。

さっき前の席の人に「なんでニヤニヤ*2してるんですか?」って聞かれました。

そろそろお昼なのに、食事も喉を通らないかもしれないので、

書いてしまいます。


はてダJavascript を実行するという件について。

先日、自分のはてなダイアリーブログパーツを設置できるようになったので、事実上の JavaScript 解禁になりました。

ということで、JavaScript の eval を貼り付けるガジェットGoogle Gadgets で作ってみました。

てっく煮ブログ - はてなダイアリーで JavaScript eval

やりたくなる気持ちはわかります。

僕も id:amachang さん(面識も本題に関係もないのに名前出してすいません)とかのスクリプトとか、その場で実行したいです。

でも、外部から来た変数に eval したらいかんと思うのですよ。


↓例えばこんなことできちゃう

http://gmodules.com/ig/ifr?url=http://nitoyon.googlepages.com/js_eval.xml&up_eval=alert(’bad%20script’)&synd=open&w=320&h=50


いきなりこんな画面でボタン押す方がおかしいですが、

このガジェットを使用することで


「任意の人が自分の手を汚さずに(リンクを張るだけで)任意のコードを

実行させることができる」


んじゃないかと思います。

自動実行とかもやろうと思えばきっとできちゃうわけですからね。


代案があまり思いつかないですが、

  • 任意の人が
  • リンクを張るだけで

の部分を何とか出来そうな気がします。

トークンとセットじゃないと eval しないとか。


個人的には、外部から来た変数への eval は御法度だと思ってるんですが、

実際のところはどうなんでしょうね。

*1はてブ http://b.hatena.ne.jp/entry/http%3A//d.hatena.ne.jp/nitoyon/20070820/javascript_eval_on_hatena_diary

*2:ニヤニヤしてたのは、やらしいことを考えていたからです

2007-08-25

[][][][]helper は正直 form くらいにしか使わない

CakePHP をいきなり実践投入して2ヶ月程たった。

最近は Web アプリ作る時に当たり前のように Ajax 使うし、

それを当たり前のように要求される。

(要求されるのはほとんどがアニメーションとかの部分であって、特に ajax ではないけど。)


で、それを当たり前のようにこなすに当たり、CakePHP は便利なんだけど、

何が便利かっていうと、 決して php から Ajax コードを記述する、

Ajax helper があるからではない。


せっかくだから Ajax helper を何度か使おうとしたけど、

結局全く使わなかった。(使えなかった)


php から javascript を記述しようとすると、痒いところが多すぎる。

じゃあ CakePHP は何が便利かっていうと、

controller 内 の action で、

$this->layout = '';

こうするだけで、簡単に layout なしの HTML パーツを生成できるから便利。

それを javascritp で受け取って表示するコードなんて、すぐ書ける。


  • HTML の生成は PHP が行う
  • javascript はそれを受け取って表示する
  • それ以外のアニメーションを含む HTML の加工は javascript が行う

それって当たり前のことなんだけど、改めてそう決めておけばメンテナンス性が落ちることもない。ハズ。

下手に Ajax helperを使ってしまうと、

どうしてもある部分では PHPで、ある部分は javascript に書かれてて、

しかもその境界があいまいになっちゃったりする。

関係ないけど javascript HTML テンプレートとか使い出したらいよいよ危ない。


html helper もいろいろあるけど、

html タグを書きたくない病の人向けすぎる。 form 関連だけで十分。

div タグとか img タグとか、そんなもん手で書けばよいと思う。


最近のデザイナーさんは smarty 混じりの html くらいなら普通に手を入れてくれるし。

僕のまわりのデザイナーさんが優秀なだけかもしれんけど。


それが smarty じゃなくて php コードだったらまた話は違ってくると思う。

確かめたわけじゃないけど。

なんでかっていうと、 「<?」これとか「?>」これとかが ぱっと見で html タグと区別しづらいから。

僕自身、PHP 混じり HTML 文見るとイラっとするし。

だから、PHP プログラマはできるだけ HTML 書きたくない病にかかったりするんだと思ってる。

2007-08-14

[][][] 作った testCase を全部まとめて実行する方法

※僕の cake は 1.2.0.5146

CakePHP で /app/tests/cases/ 以下に testCase を作成すると、

App Test Cases でテストの一覧を表示してくれる。


勝手に表示してくれるのはありがたいが、

でもどうせだったら全部まとめて実行したい。


勝手に表示してくれるくらいだから、

全部まとめて取得するメソッドあるんだろうと思ったら、やっぱりあった。


こんな group test を作ると、App Test Groups のところに表示されて、

testCase 全部まとめて実行してくれる。重いけど。

/app/tests/groups/app_all.group.php

class AppAllGroupTest extends GroupTest {
	var $label = 'run all app test';

	function AppAllGroupTest() {
		TestManager::addTestCasesFromDirectory($this, APP_TEST_CASES . DS );
	}
}

2007-08-09

[][]任意の url で任意の controller, action を実行する方法(静的 html との共存編)

前エントリで書いた、任意の url で任意の controller, action を実行する方法で、

例外が一つある。

url と controller, action のマッピングメモ


それは、既に存在するディレクトリ名を含むマッピングができないという点である。


例えば、既に /blog ディレクトリが存在する場合、

いくら routes.php にこう書いても、 /blog/ へのアクセスで

BlogController は実行されない。

Router::connect ('/blog/:action/*', array('controller'=>'Blog', 'action'=>'index'));

これは、ドキュメントルート直下の .htaccess で以下のように記述されているためである。

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>

リクエストに該当するファイルやディレクトリが無い場合に限り、

index.php に Rewrite されるのだ。

/blog が既に存在する場合、 Rewrite はされない。


でもどうしてもどうしても /blog で BlogController を実行したい場合は、

/blog/index.php に、以下内容を記述すればよい。


<?php
$_GET['url'] = '/blog/';

// ドキュメントルート直下の index.php をインクルードする
require('/../index.php');
?>

因みにこのことは .htaccess の↓の行をコメントアウトしたら

実現しそうな気もするが、それは罠である。ムリ。

RewriteCond %{REQUEST_FILENAME} !-d


さらに言えば、静的 html も view ディレクトリ下に配置して、

Cakephp から(例えば pagesController)から呼び出すという方法もあるが、

全ファイルが php になってしまうので、時と場合を選ぶ。


Session を保持しつづけなければならないようなサイトでは、

その方法がよさそうだと思った。

2007-08-08

[][]url と controller, action のマッピングメモ

※CakePHP1.2 の話です。


CakePHP で既存の controller, action を任意の url で実行するには

/app/config/routes.phpマッピングを記述すればよい。


例えば、マニュアルには /blog/history/05/june という url

BlogController の history アクションに 05, june というパラメータ

渡す方法を書いてある。


次の例では、/blog のすべてのURLを、 BlogController に接続します。デフォルトのアクションは、 BlogController::index() になります。

例 4.3. Route の例

connect ('/blog/:action/*', array('controller'=>'Blog', 'action'=>'index'));

Routes の設定

でも実はこれ、特に設定しなくても普通に実行される。

何も設定しなくても、ディレクトリの第一階層は controller として扱われるし、

第二階層は action として扱われる。

そして、それ以下はパラメータになる。


マニュアルで言わんとしてるのは、これが任意の url で可能であるってことだ。

例えば、 /archive/05/june/ という url で上記と同じ action を実行するには、

以下のように記述するとよい。

    Router::connect('/archive/*', array('controller' => 'blog', 'action' => 'history'));

また、 /blog ではなく、 /cms 以下全ての url を BlogController に接続するには、以下のようにする。

    Router::connect('/cms/:action/*', array('controller' => 'blog', 'action' => 'index'));

ここまでがマニュアルに書いてあることだ。



試してみた限りでは、さらに /archives/something/category/ という url で、

BlogController の category アクションに、 "something" というパラメータを渡すことが可能だ。

こうする。

    Router::connect('/archives/:pass/:action/*', array('controller' => 'blog')); 

ただし、/archives/something/category/hoge/ としても、 hogeパラメータとして渡されない。

ぽい。

メモ。

2007-07-27

30過ぎて水筒にカルピス詰めて会社に持っていく男

会社に水筒持ってく時点でどうよって話はさておき、

おいしいよね、カルピス

2007-07-20

[]PHP 4のサポート終了につき

PHP 4 のサポートが年内で終了するとかで。

今のところそんなに思い当たる節が無いので

(いよいよ切羽詰ってからでも間に合うかな?くらいの心当たり)

愕然とするわけではないが、やはりめんどくさい話なわけで。

「われわれの見たところでは、積極的に開発を行っている人はみなすでに移行を済ませている。統計データの数値は、PHP 4ベースのレガシーアプリケーションがたくさんあるために歪められてしまっている。そういったアプリケーションは現状のまま稼働しているので、誰も変更したがらないからだ」とGutman氏は主張する。「PHP 4」のサポートが2007年末で終了へ

この言い分って、随分暴力的じゃないか。

統計データの数値は、PHP 4ベースのレガシーアプリケーションがたくさんある」ことを証明しているんじゃないのか。数値を歪めてるってなんだよ、それw

しかも「誰も変更したがらない」ってわかってるやん。

  • 動いてるスクリプトはさわりたくないのが世の常
  • で、その動いたスクリプトを書いた人は往々にして多忙
    • 余裕のある人間は、そんなリスクを負うつもりのない人間
    • こういうやつは大抵「自分の」書いたプログラムは php4 でも php5 でも動きますとか、人の書いたプログラムは関係無いですとか言い切る
  • 予算が発生しない作業なのがそもそも問題
  • php4 と php5 を同じサーバ上で共存させるのが面倒(切り替えるのは簡単)な以上、 php4 と php5 で動作するスクリプトを書くのは困難
  • そもそも pear って php4 向きでしょ。pear な部分を作り変えるのは、さすがにちょっと。。。

まあそんなこんなで、php5 への移行はやっぱり進んでないと思う。

でも、何とかしなきゃならん状況なんでしょう。


じゃあ、どうするかって話だけど、

いよいよ困ってるような所は、クライアントリニューアルでも持ちかけりゃいいんじゃね?

予算が発生すれば、それなりに動く人は動くわけで。


php5 に作り変えなきゃいけないわけですが、

単に作り変えても意味無いので、どうせだったらリニュりましょかとか

言えばいんじゃない?(人ごと)


僕はなるべく意識しながら、CakePHP 使ってこうと思います。

実際問題してないけどね、意識。


↓意識するなら、これです。エライ!

http://www.1x1.jp/blog/2007/06/php_php4_to_php5.html

2007-07-16

サンダルズレテナー

前回ひどい目にあったサンダル履くために

親指と人差し指の間にばんそうこうを貼った。


さらになるべくそこに力がかからないように

親指だけに鼻緒を引っ掛けるようにして足を持ち上げ、

かかとから着地するとサンダルずれしないことに気づいた。


結果、サンダルずれはしなかったが、ものすごく疲れたし、

歩くたびにペタペタ音がした。

タラちゃんか。俺は、タラちゃんか。


デキの悪い道具を上手く使うための努力っていうのは

この世から無くなるべきだと思った。


何かを作ろうという人はすべからくこの気持ちを持つべきなんじゃないか。


イチかバチか「すべからく」って言葉を使ってみた。

2007-07-11

[] はてなスター

なんかはてダに変なの付いたと思って見てたらこういうことか。

http://d.hatena.ne.jp/hatenadiary/20070711/1184149817

これが、はてなネガティブブックマーク(ネガブ)に対する対策ってことだろう。


はてブに規制をかけるのではなく、

システム上プラスにしか働かないシステムで相殺しようっていう発想は好きだ。

なんか人気ないみたいだけど。


自分で間違ってつけたスターが消せないらしいけど、

システムの性質上、別にそれでよいんじゃないか。

間違うのは最初の数回くらいだろうし、

そのための追加コードは無意味だと思う。


僕は別に無くても困らないし、

そもそもこの追加機能自体、使うことも無いかもしれん。

[][]CakePHP

plugin の存在を完全にスルーしてた。

CakePHP | 13章 プラグイン

汎用的な controller は plugin として作るべきなのか。

しまった。component として作ってた。

2007-07-10

[]HTML_QuickForm よ永遠に

最初は感動するものの、使えば使うほど嫌いになっていく HTML_QuickForm がメンテナンス終了したとか何だとか。

とうとうHTML_QuickFormのメンテナンスが終了してしまった(正確に言うと追加開発が終わっただけでバグフィックスは継続しておこなわれる模様)。

</ppp> <ppp>PHPのテクメモ | HTML_QuickForm suspended


僕にとって、「昔の彼女が結婚しました」みたいな話だ。

あの時はありがとう、どうぞお幸せに。


みんな CakePHP に乗り換えればよいと思う。

こっちのがきっと幸せになれる。

[]CakePHP 1.2.0.5427alpha リリース

CakePHP 1.2.0.5427alpha がリリースされました。

まだ alpha


console 周りが結構変更されてます。

bake コマンドの元ファイルが template になったみたいですね。

妥当な流れだと思います。


とはいえ。

そのテンプレートの中身はこんなんなんですよ。

/cake/console/libs/templates/views/view.ctp より一部抜粋。

$i = 0;
foreach ($fields as $field) {
	$class = null;
	if ($i++ % 2 == 0) {
		$class = ' class="altrow"';
	}

	if (in_array($field['name'], array_keys($foreignKeys))) {
		$otherModelClass = $foreignKeys[$field['name']][1];
		$otherModelKey = Inflector::underscore($otherModelClass);
		$otherControllerName = Inflector::pluralize($otherModelClass);
		$otherControllerPath = Inflector::underscore($otherControllerName);
		if (isset($foreignKeys[$field['name']][2])) {
			$otherModelClass = $foreignKeys[$field['name']][2];
		}
		$otherSingularVar = Inflector::variable($otherModelClass);
		$otherModelObj =& ClassRegistry::getObject($otherModelKey);
		$otherPrimaryKey = $otherModelObj->primaryKey;
		$otherDisplayField = $otherModelObj->displayField;
		echo "\t\t<dt{$class}>".Inflector::humanize($otherModelClass)."</dt>\n";
		echo "\t\t<dd{$class}>\n\t\t\t<?php echo \$html->link(\${$singularVar}['{$otherModelClass}']['{$otherDisplayField}'], array('controller'=> '{$otherControllerPath}', 'action'=>'view', \${$singularVar}['{$otherModelClass}']['{$otherPrimaryKey}'])); ?>\n\t\t\t&nbsp;\n\t\t</dd>\n";
	} else {
		echo "\t\t<dt{$class}>".Inflector::humanize($field['name'])."</dt>\n";
		echo "\t\t<dd{$class}>\n\t\t\t<?php echo \${$singularVar}['{$modelClass}']['{$field['name']}']?>\n\t\t\t&nbsp;\n\t\t</dd>\n";
	}
}
?>
	</dl>
</div>


だめだ、やっぱりなじめない。。。


cake_smarty の対応はどうしよっかな。

今回はスルーして、ベータ版出てからにしよっかな。

2007-07-09

靴ずれた

買ったばかりのサンダル履いて会社行ったらおもっきり靴ずれした。

親指と人差し指の間の鼻緒的なものが当たる個所がベローンってなった。


まあ、試着した時からその予感はあったんだけど。


サンダルずれしないように、鼻緒の部分をやさしくコーティング

してくれるような商品はこの世にないもんだろうか。


あるとすれば、商品名は「サンダルズレナーイ」以外に考えられなかったので、

それで検索してみたら、ヒットしなかった。


誰か作ったらよいのにと思う。

でも、誰か作っても、商品名が「サンダルズレナーイ」じゃなかったら

潜在顧客を逃すことになるので注意すること。


追記

「サンダルズレテナーイ」でも可。

2007-07-06

[][][][]PHP におけるクロージャの用途

PHPでクロージャ

作ってみたものの、実はあんまり用途が思い浮かんでない。

なんとなく、 array_walk がキーワードに浮かんでは来るけど。


てことで、とりあえず smarty で使ってみようと思う。


CakePHP完全 smarty 化してみたものの、

smarty 内での配列の扱いが微妙だ。

↓事の顛末はこの辺に。

http://d.hatena.ne.jp/am11op/20070614/1181837256

要は、php ならこう書くべきところを

<?php echo $html->link('Edit', array('action'=>'edit', 2));?>

smarty では view に変なメソッド作った上でこう書く必要があった。

{$html->link('Edit', $view->_array('action=>edit', 2))}

まあ、これでもよいんだけど、せっかくなんで closure (的なもの)を使ってみる。

Closure はこんなの。

class Closure {
    var $_args;
    var $_func;
    /**
     * @private
     */
    function Closure($func=null, $args=null) {
        if ($func) {
            $this->_args = $args;
            $func = ereg_replace("^function\([^\)]*\) *\{", "", $func);
            $func = ereg_replace("\}$", "", $func);
            $this->_func = $func;
        }
    }
    
    /**
     * @param $func string closure
     * @param $arg1 $mixed first object/var which is used in $func
     * @param $arg2 $mixed second object/var which is used in $func
     * ...
     */
    function bind() {
        $args = func_get_args();
        return new Closure(array_shift($args), $args);
    }

    /**
     * use this method to call closure 
     */    
    function call() {
        $func = create_function('$args', $this->_func);
        return $func($this->_args);
    }
    
    function func() {
        $args = func_get_args();
        $obj = new Closure(array_shift($args), $args);
    	return $obj->call();
    }
}

無駄にインスタンス量産してるのは、書き直すのが面倒だったから。

このクラスを closure という名前で assign_by_ref してやって、

smarty 内からこう使う。

{*$html->link('Edit', $view->_array('action=>edit', 2))*}
{$html->link('Edit', $closure->func("return array('action'=>'edit', 2);"))}

文字数増えてる!

ネタです!

まあ、ちょっと変数php で処理して何かのメソッドに渡したい時、

一回しか使わないような modifier をいちいち作らなくてよいので便利かも。

ただし、入力値に対して使う場合は任意のコードを実行されないように気をつけること(棒読み)。

2007-07-03

[][]validation 時、rule 別にエラーメッセージを切り替える方法

cake1.2の話

CakePHP では view で エラーメッセージを指定することで

任意のエラーメッセージを出力できます。

{$form->error('name', 'ちょwww名前wwwww')}

rule が一つの場合ならこれでも問題ないのですが、

メールアドレスの validation など、

入力が無い場合と入力値が不適切な場合で

違うエラーメッセージを表示したい場合には

view だけでは実現できません。


そんな時には

model の $validate を以下のように指定すれば OK です。

class User extends AppModel {

	var $name = 'User';
	var $validate = array(
		'name' => array(
			'rule'=>VALID_NOT_EMPTY, 
			'message'=>'名前を入力してください'
			),
		'email' => array(
			array(
				'rule'=>VALID_EMAIL, 
				'message'=>'メールアドレスが不適切です。'
				),
			array(
				'rule'=>VALID_NOT_EMPTY, 
				'message'=>'メールアドレスを入力してください'
				),
		),
		'comment' => array(
			'rule'=>VALID_NOT_EMPTY, 
			'message'=>'コメントを入力してください'
			),
	);

}

manual には書いてないけど、ソースには書いてありました。

よくありますね、こういうこと。

2007-07-02

[][]PHPクロージャ さっきまでの無し

http://d.hatena.ne.jp/am11op/20070702/1183376369

↑前エントリがただの劣化コピーだってことに電車の中で気が付いた。

てことで、勝手にリベンジ。


その前に、closure の定義自体はとりあえず置いておいて、

自分が作ろうとしてる(欲しい)のは何なのか。

  • 外側の変数を参照できる
  • 使うその場で定義できる

↓ていうか、これ。

http://itpro.nikkeibp.co.jp/article/COLUMN/20050930/221971/?ST=oss


これができないのは、ただの callback 関数なんじゃないかと思うわけです。


で作ったのがこれ。

/*
 * closure を実現するための class
 */
class Closure {
    var $_args;
    var $_func;
    /**
     * @private
     */
    function Closure($func, $args) {
        $this->_args = $args;
        $func = ereg_replace("^function\([^\)]*\) *\{", "", $func);
        $func = ereg_replace("\}$", "", $func);
        $this->_func = $func;
    }
    
    /**
     * @param $func string closure
     * @param $arg1 $mixed first object/var which is used in $func
     * @param $arg2 $mixed second object/var which is used in $func
     * ...
     */
    function bind() {
        $args = func_get_args();
        return new Closure(array_shift($args), $args);
    }

    /**
     * use this method to call closure 
     */    
    function call() {
        $func = create_function('$args', $this->_func);
        $func($this->_args);
    }
    
    
}

// 以下、使用例
class Test{
    function sayTest($int=0){
        return 'this is a test.';
    }
}
$obj = new Test;

function piyo($bool, $obj) {
    if ($bool) {
        $obj['onSuccess']->call();
    } else {
        $obj['onFailure']->call();
    }
}

$hoge = "you know, ";

$arr = array(
        'onSuccess'=>Closure::bind("function(\$args){echo '$hoge'.\$args[0]->sayTest();}", &$obj), 
        'onFailure'=>Closure::bind("function(\$args){echo 'fail!';"), 
);

echo piyo(true, $arr); // you know, this is a test.
echo piyo(false, $arr); // fail!


  • Closure::bind の第一引数に closure を渡す
    • closure 内の instance は全て $args とする
  • $args に対応する instance を第二引数以降に渡す
  • closure はダブルクォーテーションでくくる場合は、$args の前に「\」を付ける必要がある
  • closure の頭に「function(\$args){」、尻に「}」が付いているが、これは closure であることを明示するためである
    • どっちみち ereg_replace で削除されるので、はっきり言って必要ない

「\」がウザい場合は、クロージャをシングルクォーテーションで囲って、

普通の変数引数に渡してクロージャ内から $args[n] として参照すればよいです。


ちょっとは closure ぽくなったでしょか。

[][]PHPクロージャ失敗

http://d.hatena.ne.jp/am11op/20070702/1183376369

↑前エントリのクロージャもどきがものすごく使いたくならない理由がわかった。


function closure($str) {
	$str = ereg_replace("^function\(\) *\{", "", $str);
	$str = ereg_replace("\}$", "", $str);


	$func =create_function('', $str);
	$func();
}

class Test{
	function sayTest(){
		echo 'test';
	}
}
$obj = new Test;

function piyo($bool, $obj='') {
	if ($bool) {
		closure($obj['onSuccess']);
	} else {
		closure($obj['onFailure']);
	}
}

$arr1 = array(
		'onSuccess'=>'echo "OK!";',
		'onFailure'=>'echo "NG!";',
);

echo piyo(true, $arr1);	// OK!
echo piyo(false, $arr1);	// NG!

$arr2 = array(
		'onSuccess'=>'function(){echo $obj->sayTest();}', // この時点で syntax error
);

echo piyo(true, $arr2);

class とか instance 使った時点で閉じた空間じゃなくなるので、

こういうものはいくらそれっぽく作っても、

結局 closure とは呼べないだろうと思った。

結論
失敗例を増やしただけ

[][]PHPクロージャ

※これ失敗でした。↓にもちょっとマシなやつ書いてます

http://d.hatena.ne.jp/am11op/20070702/1183392610

CakePHP 使ってたら、ものすごく closure 使いたくなった。

ググったら途中までやってる方達がいたので、

それパクって作ってみた。


↓途中までやってる方達

http://blog.xole.net/article.php?id=419

http://p0t.jp/mt/archives/2007/04/1byte.html

要は create_function を使えばよいわけだ。

closure.php

function closure($str) {
	$str = ereg_replace("^function\(\) *\{", "", $str);
	$str = ereg_replace("\}$", "", $str);


	$func =create_function('', $str);
	$func();
}

function hoge($str, $func='') {
	echo $str;
	if ($func) {
		closure($func);
	}
}

echo hoge('こんにちわ。', "function() {echo 'クロージャだよ!';}");

実行結果

こんにちわ。クロージャだよ!

ものすごく使う気にならないのはなんでだ。

2007-06-26

あわせて読みたいフィードメーターをあわせて導入

あわせて読みたいフィードメーターを導入しました。


うちみたいな泡沫 blogあわせて読みたい blog が表示されるのか心配でしたが、

ちゃんと出ました。よかったー。


フィードメーターの方は、現時点で人気度1.3。

1が最低なんかな。


更新頻度の目安にしましょ。