Zend_ViewでSmartyをラップする

これを知るまで、Contorollerで、Smartyクラスを生成して使っていたけど、
Zend_Viewのドキュメントに記載されていた、Smartyをラップする
Zend_Viewクラス(ex Zend_View_Smarty)を作成して、これを利用することで、
Smartyの便利さはそのままに、テンプレートへの値の設定がさらに楽に!!!

簡単に言うと、$key っていう変数に、$valueを設定しようとした場合、
$this->_smarty->assign($key, $value);
と書いていたのが、
$this->_view->$key = $value;
ってかけるようになるんです。
assignの記述で、よくスペルミスしていた私には、重宝する機能です。

smartyの設定(delimiterとか)も、連想配列にして、Zend_View_Smartyクラスの
生成時に、第2パラメタとして渡したら有効になります。
テンプレートへのパスも、setScriptPathではなく、生成時に設定した方が楽です。

すでに、Zendで、Smartyを使っている方でも、変更量は少なくてすみますので、
試す価値有りと思った方は、ぜひおためしくださーい。

この方法を採用していると、テンプレートエンジンを変更しようとおもった際の
ソースの改修もラッパークラスを変更するだけですみます。
テンプレートは大幅な改修になることは、避けられませんが。

DB操作にしても、変数に代入するイメージで、設定できるっていう
Zendの特徴を生かしたSmartyとの連携方法だと思います。

これをやったら、既存のZend_Viewのように、Zend Frameworkが、
Zend_View_Smartyを生成して、テンプレート特定して、画面表示までを
やってくれないかなーという欲がでてきました。
Zend_Controller_Actionを継承して、initViewあたりを再定義したら、
できそうだけど、他にもっと楽な方法がないか探して見ます。

存在しない、URLが指定された場合、action名の方は任意の処理を
入れれる方法がわかっているのですが、controller名が存在しない場合は、
エラーになるだけなので、ここをどうにかしたいところです。

Front Controllerを継承したクラスを作るのはちょっとおっくうなので、他の方法で。

Zend_Config_Iniの使い道

Zend_Config_Iniは、設定値や固定のプルダウンメニューリストを定義するのに便利です。

まずは、iniファイルを定義します。

[default] ←ブロック名

database.adaptor         = Pdo_Mysql
database.config.host     = localhost
database.config.username = user
database.config.password = password
database.config.dbname   = test

menu.0        = menu0
menu.1        = menu1
menu.2        = menu2

それをプログラムにて、Zend_Config_Iniクラスを生成する際に読み込みます。

$config = new Zend_Config_Ini(iniファイル名(パス含む), 'default');

$config->database->adaptor

で、”Pdo_Mysql”にアクセスできます。
また、$config->database->config->toArray()とすると、

array(
'host' => localhost,
'username' => user,
'password' => password,
'dbname'   => test
);

が取得できます。

また、menuの例だと、
$cofig->menu->0
とアクセスすると、エラーになります。
数字1文字は変数名として認められないようです。
しかし、$config->menu->toArray()は有効になるので、
添え字が数字の固定配列を定義するのには使えます。
これは、結構便利なんじゃないかと思います。

今は、Zend_Validateクラスを試しています。
自分で入力チェックするのと手間はあんまり変わりませんが、
バリデータチェインは便利ですね。

今回のドキュメントは、こちらです。

Zend_ControllerとRequestクラス

Actionコントローラーの中で、
$this->getRequest()
と書くと、リクエストオブジェクトが取得できる。

$_POST、$_GETの情報も、Controller名、Action名もこの中。

$this->getRequest()->getPost();
$this->getRequest()->getQuery();
$this->getRequest()->getControllerName();
$this->getRequest()->getActionName();

$_GETは、ちょっとメソッド名がイメージしづらいけど、ここは覚えるのみ。
getPost()、getQuery()は、パラメタにキーを渡すと、キーに対応する値を取得してくれる。

それ以外にも、setParam($key, $value)で、リクエストオブジェクトに値を設定可能。
これは、いつでもgetParam($key)で取得可能。
getParam()だと、$_POST、$_GETのパラメタも取得可能ですが、
getUserParam()だと、setParam()で設定した値のみが取得可能。
ここは使い分けた方が、プログラムの可読性が増すかなと思います。

あと、発見だったのが、Zendでは、
http://test.com/controller名/Action名/key/value/ 【1】
というようにパラメタを渡せます。
http://test.com/controller名/Action名/?key=value 【2】
としても渡せます。

この場合、【1】の場合は、keyはsetParamで設定したものと同じように扱われおり、
【2】の場合は、$_GETに設定されています。
パラメタの記述方法で、保存される場所が変わるので、気をつける必要があります。

次回は、便利だなと思った。Zend_Config_Iniについて書こうかなと思います。

今回書いたことは大体、ZendFrameworkのドキュメントに書いてあります。
ドキュメントは、こちらです。

ZendとcakePHP

Zendで、メール送受信と、DBアクセスができるようになったから、
cakePHPで同じことをやるにはどうするんだろうと、cakePHPガイドブックを読んだ。

cakePHPには、メール送信用のコンポーネントがない。1.2で追加される予定だそうだ。
DBアクセスのところを見たら、cakePHPの方クラスをnewする必要がなく、
利用するクラスとして宣言したら、$this->クラス名として呼び出せるという違いくらい。

ZendのコンポーネントをcakePHPからも利用できるから、cakePHP+Zendという
選択肢もあるし、cakePHPを利用するなら必須になると思う。

DBアクセスのための関数は、cakePHPの方が種類が多い。
DBアクセスについては、好みの問題になるんじゃないかと思う。
私は、今のところZendのDBアクセスの方が好きだ。

機能面の充実をとるならZend、ソースの自動生成(scaffloIdやbake等)に
魅力を感じるなら、cakePHPだと思う。
scaffloIdは、かなり強力な魅力だ、公開しないページならこれで十分なときもあるだろう。
まだView部分をどちらも見ていないから、そこで差がでてくるのかもしれない。
クラス設計は、cakePHPの方がユーザがカスタムすることを前提で、空クラスが
準備されているから、どこをいじればいいのかがわかりやすい印象。
Zendでも自分で、共通クラスを生成したら、差はないと感じた。

Zendを引き続き使いながら、不便だな、便利だなと思った点がでたら、
cakePHPではどのようになっているかを調べるという方法ですすんでいこうかと思う。

Zend_DateとZend_Localeの罠

罠というほどではないのかもしれないが、今回は罠ってことにさせてもらう。
このために、3時間くらいの時間を使ってしまったから。

Zend_Dateクラスを引数なしで生成した場合、つまり
$date = new Zend_Date();
って記述した場合。

この場合は、内部でZend_Localeが呼び出され、
ブラウザ->サーバ設定->フレームワーク設定の順で、Locale設定を検索する。
Locale設定とは、日付に関する表現方法が各地で違うため、どの地域表現方法で、
表示するかを決める設定。日本語だと、1月、2月だけど、英語では、Jan、Febみたいな。
そして、現在時刻を設定したZend_Dateクラスが作成される。

今回罠に落ちたのはバッチ処理用のphpプログラムにZend_Dateコンポーネントを
利用して作成しようとして起こったのです。
バッチってことは、主にcronで呼び出され、ブラウザ経由では起動されません。
サーバ設定からLocale設定が取得できればいいのですが、試した結果、
サーバによっては、設定されていなくて、取得できない場合があるようです。
hetemlは、phpがcgi版のためか取得できてませんでした。
(ブラウザでphpのsetlocale関数の戻り値をdumpして確認しました)
フレームワーク設定は、デフォルト状態では、何も設定されていません。

Zendのソースをおったり、ネットで調べたりしてたどり着いた解決策は2つ。

メールの送信(Zend_Mail)

hetemlのメールサーバを使ってメールを送信してみた。
プログラムのサンプルはこんな感じ。

require_once('Zend/Loader.php');
Zend_Loader::loadClass('Zend_Mail');
Zend_Loader::loadClass('Zend_Mail_Transport_Smtp');
Zend_Loader::loadClass('Zend_Date');

$date = new Zend_date();

$config = array('auth'     => 'login',
       'username' => 'ユーザ名',
       'password' => 'パスワード');

$transport = new Zend_Mail_Transport_Smtp('メールサーバ名', $config);

$mailSmtp = new Zend_Mail('UTF-8');
$mailSmtp->setBodyText('本文');
$mailSmtp->setSubject('件名');
$mailSmtp->setFrom('Fromアドレス', 'From名');
$mailSmtp->addTo('Toアドレス');
$mailSmtp->addHeader('Date', $date->now()->get(Zend_Date::RFC_2822));
$mailSmtp->send($transport);

ほとんど、ドキュメントのサンプルソースを参考にしたら動いたが、ひっかかった点が以下の2点。
・日本語の文字化け
・送信日時が設定されない

日本語の文字化けは、使用している文字コードを Zend_Mailの生成時に
パラメタとして渡すことで化けなくなった。
生成時にISO-2022-JPをパラメタとし、本文と件名をmb_convert_encodingで、
ISO-2022-JPにエンコードしてから渡しても文字化けしないことも確認しました。
UTF-8としたのは、プログラムファイルの文字コードをUTF-8としているためです。

あと、なぜかわかりませんが、普通に送信したら、送信日時が空欄で届きました。
そのため、メールヘッダの Date(送信日時)を自力で設定しています。
Zend_Dateを使って、現在日時を取得し、メールヘッダに利用される
Zend_Date::RFC_2822という型に変形したものを設定しています。

メールの受信(Zend_Mail)

Zend/Mail/Storage/Pop3クラスを使って、メールを受信してみた。
受信自体は、意外と簡単に受信できたが、fromアドレスを取るのに一工夫必要。

メーラーで、メールアドレスに名前を設定されている場合、
その名前とメールアドレスの両方が、”from”情報に設定されているため、
メールアドレスだけを抜き出す必要があります。

調べてみたところ、Pearのモジュールでありました。
Mail_RFC822::parseAddressList()
という関数です。

使い方は、以下です。

require_once('Zend/Mail/Storage/Pop3.php');
require_once('Mail/RFC822.php'); 

$config = array('host'      => 'メールホスト名',
       'user'      => 'ユーザ名',
        'password'  => 'パスワード');

$mail = new Zend_Mail_Storage_Pop3($config);

foreach ($mail as $num => $message){
  $tmp = Mail_RFC822::parseAddressList($message->from);
  $mail_address = $tmp[0]->mailbox . '@' . $tmp[0]->host;
  var_dump($mail_address);
}

私が使っているサーバ heteml なら、pearにパスが通してあるので、
ZendFrameworkさえ、自分で設置すれば、pearは requireするだけで使えました。

今日まで、初期費用無料キャンペーンをやってるので、
正月休みに、いろいろ実験してみようって方は、申し込んでみてはいかかでしょう。



htaccessに苦戦した

ZendFrameworをhetemlに設置した。

.htaccessをほとんど使ったことなかったので、そこでやたら手間取ったけど、
それ以外は特につまづくこともなく、”Hello World!!”が出力された。

http://co-hey.com/xxx/に設置したことで、RewriteBaseの正しい書き方がわからず、
ネットで検索しながら、1時間くらいかかってやっと正常に表示された。

書いた .htaccess はこれだけなのに。


AddHandler php5-script .php
RewriteEngine on
RewriteBase /xxx/
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php

http://xxx.co-hey.com というサブドメインを作成して、
http://co-hey.com/xxx/を参照するようにしたら、マニュアル通り


AddHandler php5-script .php
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php

でOKだった。

あー、サブドメインは設定するつもりだったから、最初から設定しておけば、
あの1時間は、他のことできていたのにーと思ったけど、これで、
.htacessを使ったmod_rewriteが多少理解できたからいいかとも思う。

さて、Zend_Mailコンポーネントの使い方を試したら、次はSmartyとの連携だ。

そういえば、使っているサーバ hetemlが2周年キャンペーンをやっている。
20日までの予定が、25日(クリスマス)まで延長されたみたい。
初期費用の4000円くらいが、無料になるからサーバ借りようかなーって人は、
これを機会に使ってみては?今のところ特に問題なく使えてますから、安心です。



zend framework

サポートが今後も期待できると言われている「zend framework」
今もっとも話題になっている「cakePHP」
どちらもPHPでシステム構築する際に用いるフレームワークです。

仕事でも、プライベートでもPHPでプログラムを作成していますが、
既存のフレームワークや、PEARもあまり使っていませんでした。

前職の経験から、何かあったときにブラックボックスな部分があると、
痛い目にあうというイメージがあったからです。

ですが、今の会社に転職して、初めて仕事でPHPを使うようになり、
前職よりシステム構築までの時間を短くすることが要求されていることを感じていました。

そこに着目すると、フレームワークはとても有意義なものに思えて、早速この本を買ったのです。

一通り目を通しましたが、使ってみようって気になります。
使い方のイメージもつかみやすく書いてありました。
個人的にはプログラム例がRSSリーダーだったのがイマイチでしたが。
ここは好き嫌いの問題なので、気にしないで下さい。
Chapter5を先に読んでから、Chapter4を読んだ方が分かりやすいです。

使って便利と思えるもの

そんなものを、1つ自分でも作ってみたいなと思っていた。
身の回りの人達が、あれあって助かってるよーとか、楽しんでるよーって思ってくれるもの。

何があったら日々の何かが楽になるとか、楽しくなるとか、便利になるとか。

ここ一ヶ月くらい、ぼんやりと考えてたんだけど、ヒントが見つかったと思う。
年末の休みに向けて準備して、作成していきたい。
その前に、やるべきことを全部終らせてから。

これで、cakePHPに初挑戦する。今さらかもしれないけど、興味あるところからとっかかる。
フォトショップとかイラストレーターも、もっと使えるようになりたい。

アイデアが浮かんだこと、身近な人に話をしたら、それ便利かも!!っていってくれたこと。
これのことを考えて作っていくことで、楽しさも知識も増えていきそうだ。