php:__CLASS__とget_class
2008/02/18 月曜日 - 16:33:43 by decamaちょっとハマりかけたのでメモ。
__CLASS__は宣言時のクラス名を返す。
あるクラスのメソッドで__CLASS__を参照した場合、それを継承したクラスでそのメソッドをコールすると、親クラスのクラス名が参照される。なので、継承したクラス側でも自分自身のクラス名を参照させる場合は、get_class($this)を使う。
ちょっとハマりかけたのでメモ。
__CLASS__は宣言時のクラス名を返す。
あるクラスのメソッドで__CLASS__を参照した場合、それを継承したクラスでそのメソッドをコールすると、親クラスのクラス名が参照される。なので、継承したクラス側でも自分自身のクラス名を参照させる場合は、get_class($this)を使う。
どうせならホントはpear/Authじゃなくて独自の認証を実装すべきなんだけど、とりあえず一つテストを兼ねて社内用アプリを作る必要があったので、ORMもどきのModelコントローラ(PDOで構築)をコンテナにしてAuthを組み込んだ。
バリデータ/フィルタ、なんちゃってORM、認証系の実装が終わったので、システムを構築してみよう。
足りないものやら問題点やらがハッキリ見えてくるでしょ。
php5に限定したvalidator/filterクラスの実装が終わったので、Modelコントローラを書く。
同じくphp5に限定して、ORMっぽい動きをさせてみる。とりあえず1レコードのCRUDを簡単に出来るようにしてみよう。
これまで使ってた汎用validate/filterクラスを配列対応に刷新しようと書きながら、複数ファイルのアップロードを調べてたら新しいエラーコードが追加されてた。
UPLOAD_ERR_EXTENSION
値: 8; ファイルのアップロードが拡張モジュールによって停止されました。 PHP 5.2.0 で導入されました。
ってあったので、マニュアルサイトのアップデート情報を探してたら、なんと
新しい拡張モジュール
これらの拡張モジュールは、PHP 5.2.0 以降で (デフォルトで)新しく追加されました。
Filter - データの検証とフィルタリングを行います。ユーザの入力のように、安全でないデータを扱うときに使用することを考慮した設計になっています。この拡張モジュールはデフォルトで有効になります。デフォルトのモードである RAW は、入力データに一切手を加えません。
JSON - JavaScript Object Notation (JSON) データ交換フォーマットを実装します。この拡張モジュールはデフォルトで有効になります。
Zip - ZIP 圧縮されたアーカイブおよびその中のファイルを透過的に読み書きすることができます。
『やっとJSONを組み込むんだ・・・Filter?』
テストしながら「これでやっと先に進める?」とか思いながら、ここ数日やってたのに、こんなところにこんなモノがあるなんて・・・
ファイルアップロードには対応してないし、どうやらまだきちんと動かないみたいだから、とりあえず構築は最後まで終わらせよう。
自分の実装とこれ(Filter)が近かったので、とりあえず良しとしようかな・・・
いろんなフレームワークを触ってみてるけど、配列で送られて来たフォームをきちんとバリデートしてくれるフレームワークがあんまり無いことに驚かされてしまう。
配列で送られてくるようなフォームを書くからいけないのかな?
配列で送らないようにすると、フォームを作るときの手間がとんでもないことになるよなぁ。
他の人たちはどうやってこの問題を解決してるんだろう?
とりあえず自分は、自分なりのValidateクラスを書いてみよう。
(これを誰かがやってると思ってフレームワークに走ったのになぁ。)
サーバーサイドでValidateするか、クライアントサイドでValidateするか、そこの問題もあるよなぁ。
prototype.jsを使うようになって、bindがとても便利なことに気づかされたんだけれども、これと同様のことをphpでやろうと思った時に、どうすればいいのか考えなきゃならなくなった。
Smartyが使えるかどうかわからないサーバに、テンプレートを使わなきゃいけないような実装をしなければならなかったので、
preg_replace_callbackを使って変数をパースさせようとしてみた。コールバック関数側でアサイン用の配列を参照してパースすればいいじゃん、と思って組んでみた。
ところが、コールバック関数には、正規表現にマッチした文字列が配列で投げられるだけで、他に参照用の配列を渡せない。
コールバック関数側で、参照用配列をglobalでアクセスすればいいんだけど、これだと美しくない。
で、こうしてみた。
class Binder
{
var $bind;
function __construct($arg = NULL)
{
if (!is_null($arg)) $this->bind = $arg;
}
function __call($foo, $args)
{
array_unshift($args, $this->bind);
return call_user_func_array($foo, $args);
}
}
コールバック関数が呼ばれる前に、
$bind = new Binder($assigned);
みたいにバインドさせる変数を事前に渡しておいてから、コールバック関数を
array($bind, "myfunc")
で呼び出せば、バインド用に渡しておいた変数を一緒に投げてくれる。
無理やりな解決策だったけど、これはもうちょっと考えてあげれば面白いかもしれないのでとりあえずのメモ。
記事投稿時にgeocodingさせようと思っていろいろやってみたけれど、問題の回避方法が見つからない。
1. 記事投稿(フォーム送信ボタンをクリック)
↓
2. onsubmitイベントで処理開始
↓
3. geocodingして記事中の住所文字列に緯度経度情報を追加
↓
4. フォーム送信
という流れで処理をしたいのだけれど、
submitイベントを生かしておくとgoogleからの非同期通信が完了する前にフォーム送信されてしまうし、
イベントをキャンセル(preventDefault)してしまうとこんどは変換後のフォーム送信が出来ない。
うまい方法は無いのだろうか?
とりあえずの逃げとして、記事入力中にkeyupイベントで即時変換をかけたけれど。
記事中のコメントタグから住所を抽出してgooglemapで表示させるだけなら簡単に出来るのだけれど、どうせなら他の記事中のポイントも併せて表示したい。(そっちの方がいろんな使い方が出来そう。)
どのタイミングでgeocodingさせるかが悩みどころ。
地図表示時に登録済みの全住所を投げるのはスマートじゃないと思うので、出来れば投稿時にgeocodingまで済ませたいけれど、どう処理しよう?
記事投稿のonsubmitで処理すればいいのか。
簡単に出来そうだと思って始めたのはいいけれど、ちょっと面倒になってきた。
WordPressにGoogleMapを組み込もうと思っていろいろ実験中。
プラグイン化を目標。
Google Maps API リファレンス
geocodingがまだ日本国内で使えないのでGoogle AJAX Search APIを使って緯度経度情報を取得する必要がある。
面倒だなぁ、と思ったら本家にあるじゃん、便利に使えそうなのが。
Using the GSmapSearchControl Solution
これを組み込めばなんとかなりそう。
前回の記事に書いた「WordPressメルマガ発行」のメール配信部がテスト稼動した。
WordPress+MySQL+PEAR+Smartyで構築。
cronで設定した時刻に、当日発行の記事があったら、カテゴリ毎に登録された受信者に記事のタイトル、本文をメールのタイトル、本文にして配信。記事中の特定文字列置換にも対応。
あとは、受信者管理が出来れば正式運用出来るか。
ブログ記事からメール本文を取り出す際に、Smartyを使ってテーブルに登録してある特定文字列の置換を行ったのだけれど、動的にオブジェクトからテンプレートを生成してfetchする、ってのが簡単に出来るかと思ったら出来なかった。
sessionをリソースにするプラグインを書いたけど、他に何か簡単な方法って無いのかな?