Zend_Pagenatorを使う

http://framework.zend.com/manual/ja/zend.paginator.html

これを使ってみた。
マニュアル読んでもあまりピンとこず、サンプル見た方が早い。

Zendを使うときは、Zend_Viewではなく、Smartyを使っているので、
Zend_View_Smarty(Smartyを使うためのラッパー)に追加が必要になります。
http://framework.zend.com/manual/ja/zend.view.scripts.html#zend.view.scripts.templates

上記がZendのマニュアルにのっているZend_View_Smartyクラス。
これに、Zend_View_Abstractクラスから以下のメソッドをコピペしたら、
Zend_Pagenator等のZend_Viewヘルパー、プラグインが呼び出せます。
 ・__call
 ・getHelper
 ・getPlugin
 ・getPluginLoader
 ・getHelprPaths()

private変数なんかは、上記のメソッドで使ってるやつを適宜追加してください。

まだ、Zend_Pagenatorしか使ってないので、他のプラグイン、ヘルパーを
使うには抜けがあるかもしれません。

Zend_Pagenatorは、動いてみると楽でした。これ便利です。
ページャーはPEARのやつを組み合わせてたんですが、もう使わなくていいですね。

findManyToManyRowsetの盲点

findManyToManyRowset はとても便利なメソッドです。

以下の様なテーブル構成の場合

・テーブルA
・テーブルB (テーブルAの子テーブル)
・テーブルC (テーブルBの子テーブル)

findテーブルCViaテーブルB
または
findManyToManyRowset(‘テーブルC’ , ‘テーブルB’)
と書くことで、Cの情報を1行で取得することができます。

以前の記事でこの場合、テーブルBのデータも参照のみ可能な状態で、
Zend_Db_Table_Rowsetクラスに含まれていることを書きました。
しかし、テーブルCのデータを更新して、save()した後、テーブルBのデータは、オブジェクトの中から消えてしまいます。
もともとテーブルCのRowsetオブジェクトなので、理解できるのですが、
予想していない挙動だったので、ここにメモしておきます。

参照するなら、テーブルCの情報を更新する前に。ここ大事です。

続2Zend_Mailで日本語本文が文字化け

昨日書いた対処により、Mac OS9 Outlook Expressでは化けなくなったが、
他のメーラーではまだ化けることがあるようでした。

そんなときに、会社のメールサーバ等に詳しい方から情報をもらいました。
日本語メールの本文のエンコーディングは、7bitでないといけないということを。
メールヘッダのContent-Transfer-Encodingの部分です。

というわけで早速変更してみました。
以前、Zend_Mime::ENCODING_BASE64としていた部分を、
Zend_Mime::ENCODING_7BITに変更です。

$mail = new Zend_Mail(‘ISO-2022-JP’);

$mail->setBodyText($text, null, Zend_Mime::ENCODING_7BIT);

これで、文字化け問題から解放されることを望みます。
また新たなメーラーで問題がおこりませんよーにー。

続Zend_Mailで日本語本文が文字化け

以前https://life.co-hey.com/2008/09/zend-mail-6.htmlという記事を書きましたが、的外れだった可能性がでてきました。

メールヘッダーがbase64になっていたのに、printableで送信していたため、
この対処を入れて様子を見ていたのですが、まだ文字化けする場合がありました。

Mac OS9で、Outlook Expressをの場合に文字化けする現象がでました。
いろいろ試したところ、以下の対処で文字化けしなくなりました。

$mail = new Zend_Mail(‘ISO-2022-JP’);
$mail->setBodyText($text):

上記のように、base64の指定をしない形に戻す。

次に、メール本文の最後に改行を入れる。

これでMac OS9 Outlook Expressでも文字化けしなくなりました。
誤った情報を書いてしまったことをお詫び致します。

Zend_Mailで日本語本文が文字化け

今回、メーラーによっては、日本語の本文が文字化けするという現象を確認。

調査したところ、通常、本文はPrintableでエンコードされて送信されていました。
なので、ここをbase64にてエンコードするように修正して解決。

$mail = new Zend_Mail(‘ISO-2022-JP’);

$mail->setBodyText($text):

と書いていた部分を以下のようにエンコード形式を指定して設定します。

$mail = new Zend_Mail(‘ISO-2022-JP’);

$mail->setBodyText($text, null, Zend_Mime::ENCODING_BASE64);

文字化けってほんとやっかいです。

findManyToManyRowsetの取得データ

findManyToManyRowsetの説明は、こちらを読んでください。

つまり、例をあげると、

アカウント【Accounts】、ブログ記事【Articles】、コメント【Comments】
というテーブルクラスがあり、$account(Zend_Db_Table_Row)があった場合、
$account->findCommentsViaArticles();
とやると、コメント情報(Zend_Db_Table_Rowset)が取得できます。
リンク先のマニュアルに書いてあるのはここまでです。

今日、このメソッドを使っていて発見したこと。
このメソッドで取得される情報には、中間テーブル(今回はArticles)の
データも含まれていることです。Commentsの情報しかないと思っていたので意外。

データの更新は、Commentsのカラムしかできませんでした。
中間テーブルのデータは参照だけできます。更新しようとするとエラーになります。

どういうときに便利かはわかりませんが、忘れないようにメモ。

Zendのディレクトリ構成

前回の記事で以下のようなディレクトリ構成でやってますって書きました。

web/index.php
lib/models/xxxxModel.php
lib/validates/xxxxValidate.php
lib/dbs/xxxxxDb.php
lib/controllers/xxxxxController.php

そこにコメントをいただき、調べてみたところ、
以下の構成にしたら、Zend_Loader::registerAutoload()を生かせるのかなと思った。

web/index.php
lib/models/xxxx.php
lib/models/Dao/xxxxx.php
lib/models/Validate/xxxx.php
lib/controllers/xxxxxController.php

もともとmodelってのは処理クラスの集合体があることがイメージされているのかも。
そうだとしたら、私は勘違いしてた。
もうちょっと考えてみる。

_autoloadが便利

偶然見つけたメソッド __autoload。
最近までphp4ばかり使ってたので、マジックメソッドには疎いのです。

たまたま見つけたサイトで、マジックメソッドについて読んでみて、
早速__autoloadから試してみました。結果は便利です。

私は、phpでプログラムを新規で作る場合は、Zend Frameworkを利用していますが、
だいたいこんなディレクトリ構造です

web/index.php
lib/models/xxxxModel.php
lib/validates/xxxxValidate.php
lib/dbs/xxxxxDb.php
lib/controller/xxxxxController.php

小規模なものしか作っていないので、この階層分けでなんとかなってます。

そこでindex.phpに以下のように __autoloadを追加したら、
各ファイルで、Zend_Loader::loadClassや、require_onceを
記述する必要がなくなってとても楽です。

function __autoload($className)
{
  if (preg_match("/^Zend_/", $className)){
    Zend_Loader::loadClass($className);
    return;
  }

  if (preg_match("/Model$/", $className)){
    require_once('models/' . $className . '.php');
    return;
  }

  if (preg_match("/Db$/", $className)){
    require_once('dbs/' . $className . '.php');
    return;
  }

  if (preg_match("/Validate$/", $className)){
    require_once('validates/' . $className . '.php');
    return;
  }
}

Zend_Mailで日本語メールヘッダを扱う

以前、https://life.co-hey.com/2008/03/zend-mailfrom.htmlという記事を書きました。

ヘッダーをエンコーディングする際の処理を変更しようという内容でしたが、
今回追記しておいた方がいいなということあったので追記です。

mb_encode_mimeheaderでは、mb_internal_encodingの文字コードと、
mb_encode_mimeheaderの第2パラメタで指定した文字コードが一致しないと
正常に変換されない場合があるようです。

なので、以下ように書いておいた方が無難ですね

mb_encode_mimeheader('"'.$name.'"', 'ISO-2022-JP')

  ↓

$encode = mb_internal_encoding();
mb_internal_encoding('ISO-2022-JP');
mb_encode_mimeheader('"'.$name.'"', 'ISO-2022-JP');
mb_internal_encoding($encode);

今更findParent~

Zend FrameworkのDbテーブルリレーションを使って、初めて親テーブルの
データを取得したんですが、返り値ってZend_Db_Table_Rowなんですね。

子テーブルのデータをとってくるときと一緒で、Zend_Db_Table_Rowsetの
つもりで current() を呼び出してエラーになってしまっていました。

子は複数だけど、親は1つっていう考えになってるんですかね。

ほーって思ったので、メモしておきます。