php:ORMもどきの実装

2008年2月6日 (水曜日) - 23:12:45 by decama

php5に限定したvalidator/filterクラスの実装が終わったので、Modelコントローラを書く。
同じくphp5に限定して、ORMっぽい動きをさせてみる。とりあえず1レコードのCRUDを簡単に出来るようにしてみよう。

php:フィルタ関数

- 14:31:42 by decama

これまで使ってた汎用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)が近かったので、とりあえず良しとしようかな・・・

php:formのValidate

2008年2月4日 (月曜日) - 23:11:53 by decama

いろんなフレームワークを触ってみてるけど、配列で送られて来たフォームをきちんとバリデートしてくれるフレームワークがあんまり無いことに驚かされてしまう。
配列で送られてくるようなフォームを書くからいけないのかな?
配列で送らないようにすると、フォームを作るときの手間がとんでもないことになるよなぁ。

他の人たちはどうやってこの問題を解決してるんだろう?

とりあえず自分は、自分なりのValidateクラスを書いてみよう。
(これを誰かがやってると思ってフレームワークに走ったのになぁ。)

サーバーサイドでValidateするか、クライアントサイドでValidateするか、そこの問題もあるよなぁ。

php:関数に変数をバインドしたい

2008年2月2日 (土曜日) - 3:38:00 by decama

prototype.jsを使うようになって、bindがとても便利なことに気づかされたんだけれども、これと同様のことをphpでやろうと思った時に、どうすればいいのか考えなきゃならなくなった。

Smartyが使えるかどうかわからないサーバに、テンプレートを使わなきゃいけないような実装をしなければならなかったので、
preg_replace_callbackを使って変数をパースさせようとしてみた。コールバック関数側でアサイン用の配列を参照してパースすればいいじゃん、と思って組んでみた。
ところが、コールバック関数には、正規表現にマッチした文字列が配列で投げられるだけで、他に参照用の配列を渡せない。
コールバック関数側で、参照用配列をglobalでアクセスすればいいんだけど、これだと美しくない。
で、こうしてみた。

PHP:
  1. class Binder
  2. {
  3.     var $bind;
  4.  
  5.     function __construct($arg = NULL)
  6.     {
  7.         if (!is_null($arg)) $this->bind = $arg;
  8.     }
  9.  
  10.     function __call($foo, $args)
  11.     {
  12.         array_unshift($args, $this->bind);
  13.         return call_user_func_array($foo, $args);
  14.     }
  15. }

コールバック関数が呼ばれる前に、

PHP:
  1. $bind = new Binder($assigned);

みたいにバインドさせる変数を事前に渡しておいてから、コールバック関数を

PHP:
  1. array($bind, "myfunc")

で呼び出せば、バインド用に渡しておいた変数を一緒に投げてくれる。
無理やりな解決策だったけど、これはもうちょっと考えてあげれば面白いかもしれないのでとりあえずのメモ。

wp-mixipublisher:テスト

2008年1月24日 (木曜日) - 20:01:31 by decama

この記事がポストされれば問題ないはず。

ならば修正もされるはず。

どちらもOK。

久しぶりにここを更新するようになって、気がついたらmixiへの書き込みが出来なくなってた。どうやらmixi側の修正にプラグインが対応できてかったのが問題みたいだったけど、その修正対応版でもなぜか動かない。
ソースを追っかけてみて、post_idを直接指定してプラグインファイルを実行させれば書き込めることは確認取れたので(前3件の記事をmixiに投稿してみた)、要はpublishToMixiに記事IDを渡してやればいいはず。
saveHandler, publishHandler からの executePublishToMixi が publishToMixi を呼び出してるのかと思ったらそうじゃなかった。
どうやら、executePublishToMixi でチェックさせた後で、 mixipublisher_isEnableSelfExecute から publishToMixiを呼んでる。
ところが、現行のWordPress(2.3.2)はpost_idをgetで投げてないから、 ここでコケる。
post_idをpostedに修正したら動くかな?と思ったけど、新規投稿はいけるけど、投稿済み記事の更新がダメだった。
なので、 executePublishToMixi から直接 publishToMixi を呼び出すように修正。

PHP:
  1. function executePublishToMixi($postId, $isModify=false) {
  2.         if(in_array($postId, $this->_publishedId)) {
  3.             return false;   //falseを返すように修正
  4.         }
  5.         $settingVO = $this->getWpSetting();
  6.         if(!$settingVO->getParam('user_id')) {
  7.             return false;   //falseを返すように修正
  8.         }
  9.  
  10.         $post = get_post($postId);
  11.  
  12.         // 公開しない場合は終了
  13.         if($post->post_status != 'publish') {
  14.             return false;   //falseを返すように修正
  15.         }
  16.  
  17.         // 1.0.0 RC2: XML-RPCリクエストの場合ディフォルト設定を優先する
  18.         if(defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) {
  19.             // ディフォルト設定が有効でなければ終了
  20.             if($settingVO->getParam('default') != 1) {
  21.                 return false;   //falseを返すように修正
  22.             }
  23.             // すでにある投稿で、Mixiに投稿していなければ終了
  24.             if(!$post->mixi_diary_id && $isModify) {
  25.                 return false;   //falseを返すように修正
  26.             }
  27.         }else{
  28.             if($_POST['publish_mixi'] != 1) {
  29.                 return false;   //falseを返すように修正
  30.             }
  31.         }
  32.  
  33.         // 1.0.0 RC2: リクエストに利用するクッキーを既存のものからではなく、新しく作成する
  34.         $user = wp_get_current_user();
  35.         $cookies = USER_COOKIE.'='.urlencode($user->user_login).'; ';
  36.         $cookies.= PASS_COOKIE.'='.md5($user->user_pass);
  37.  
  38.         $relative_path = preg_replace('/^'.preg_quote(ABSPATH, '/').'/', '/', __FILE__);
  39.  
  40.         $ping_url = get_settings('siteurl') . $relative_path;
  41.         $parts = parse_url($ping_url);
  42.         $argyle = @ fsockopen(
  43.         $parts['host'],
  44.         $_SERVER['SERVER_PORT'],
  45.         $errno,
  46.         $errstr,
  47.         0.01);
  48.  
  49.         if ($argyle) {
  50.             fputs($argyle, "GET {$parts['path']}?" .
  51.             "post_id=" . $postId .
  52.             " HTTP/1.0\r\nHost: {$parts['host']}\r\nCookie: {$cookies}\r\n\r\n");
  53.         }
  54.         $this->_publishedId[] = $postId;
  55.         return $postId;
  56.     }
  57.  
  58.     function saveHandler($postId) {
  59.         if ($postId = $this->executePublishToMixi($postId, true))   //$postIDが戻された時だけmixi記事を更新
  60.             $this->publishToMixi($postId);
  61.     }
  62.  
  63.     function publishHandler($postId) {
  64.         if ($postId = $this->executePublishToMixi($postId))  //$postIDが戻された時だけmixiに記事を投稿
  65.             $this->publishToMixi($postId);
  66.     }

これで多分大丈夫だと思う。

Akelos:同時並行でサイト構築テスト中

2008年1月23日 (水曜日) - 1:33:48 by webmaster

CakePHPを始めたのはいいんだけど、いまいちキレイにまとまらない。深い階層の配列を書かなきゃいけないことが多いし、DBアクセスは楽かも知れないけれど、準備にかかる手間が多すぎて、「こんなんだったらSQL直接書いてスクラッチしたほうが早いんじゃ・・・」って思っちゃう。
メンテナンスの手間とかを考えたら、導入するメリットはあるんだろうけども。

CakePHPも「とりあえず触ってみないとわからんだろ」との勢いもあって始めてみたので、その勢いでもう一つ触ってみる。

Akelosってのがなんとなく気になったのでこれを使ってみようと思う。
インストール~チュートリアルでいきなりひっかかるし、Call-time pass-by-referenceのWarningの嵐でメゲそうだけど、まずは全体像が見えるまでやってみよう。

CakePHP:Smartyを使う

2008年1月21日 (月曜日) - 18:34:59 by webmaster

テンプレートで<?php echoとか書きたくなかったので、Smartyを使えるようにしたい。

Smarty View for 1.2

ここを参考にsmarty.phpを作成。htmlヘルパークラスやformヘルパークラスに配列でパラメータを渡さなきゃいけないときにどうするか、って問題があって、assign_assocっていうsmarty用のプラグインを使えばいいんだけど、配列を文字列で渡すのがちょっとキモチ悪い。直接渡せないかとおもってヘルパークラス(basics.phpからaとaaとprを持ってきた)を作ってみたけど、Smartyはオブジェクトのパラメータにオブジェクトがあるとパース出来なかった。
せっかくヘルパークラス作ったのでヘルパークラスメソッドをassignすることで自分としては納得するしかないかな。

CakePHP:モデルのバリデーション

- 17:54:33 by webmaster

何ヶ月ぶりかの更新だったりする・・・(笑)

CakePHPでサイト構築をしようと思って始めてみたので、自分用のメモ。
Modelのvalidateプロパティでバリデーションの指定が出来るけど、formヘルパークラスで出力してるエラーメッセージの指定もここで出来る。
ブログチュートリアルではこう書いてあるけど、

PHP:
  1. var $validate = array(
  2.     'title' => VALID_NOT_EMPTY,
  3.     'body' => VALID_NOT_EMPTY,
  4. );

こんな風にも書ける。

PHP:
  1. var $validate = array(
  2.     "title" => array(
  3.         "rule" => VALID_NOT_EMPTY,
  4.         "message" => "タイトルが未記入です。",
  5.     ),
  6.     "body" => array(
  7.         "rule" => VALID_NOT_EMPTY,
  8.         "message" => "本文が未記入です。",
  9.     ),
  10. );

$validation.phpで定義されているValidationクラスのメソッドでバリデーションすることも出来る。

PHP:
  1. var $validate = array(
  2.     "url" => array(
  3.         "rule" => "url",
  4.         "message" => "リンク先がURLとして認識できません。",
  5.     ),
  6. );

3ヶ月も・・・

2007年9月10日 (月曜日) - 21:11:44 by webmaster

気が付けば、前回の投稿からほぼ3ヶ月。

全体的になんだか煮詰まってしまってる感じ。
滞ってるというか。
停滞だな。

何とかしないと。

AIR:やっぱりalphaでしょ。

2007年6月15日 (金曜日) - 14:55:58 by webmaster

面白くなってきた。

次にやることといったら、alphaでしょ。半透明でしょ。(笑)
main-app.xml

XML:
  1. <rootContent systemChrome="none" transparent="true" visible="true">[SWF reference is generated]</rootContent>

main.mxml

XML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" borderStyle="outset" alpha="0.4" creationComplete="initApp();">
  3.     <mx:Script>
  4.         <![CDATA[
  5.             import flash.html.JavaScriptObject;
  6.             function changeFontFamily():void
  7.             {
  8.                 var doc:JavaScriptObject = html.javaScriptDocument.styleSheets;
  9.                 for (var i:int = 0; i <doc.length; i++) {
  10.                     for( var j:int = 0; j <doc[i].cssRules.length; j++) {
  11.                         doc[i].cssRules[j].style.fontFamily = "MS UI Gothic";
  12.                     }
  13.                 }
  14.             }
  15.             function initApp():void
  16.             {
  17.                 this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  18.             }
  19.             function onMouseDown(evt:Event):void
  20.             {
  21.                 stage.window.startMove();
  22.             }
  23.         ]]>
  24.     </mx:Script>
  25.     <mx:HBox>
  26.         <mx:TextInput id="textBox" width="225" text="http://" change="html.location = textBox.text"/>
  27.         <mx:Button label="移動" click="html.location = textBox.text;"/>
  28.     </mx:HBox>
  29.     <mx:HTML id="html" width="100%" height="100%" y="30" complete="changeFontFamily();" backgroundAlpha="0.4"/>
  30. </mx:Application>

んで、こうなる。
test3.gif

楽しいね。