PEAR Pagerのトラブル回避
こんにちは、牧野です。今回はphpの軽めな話題です。
最近、小さなシステムの作り直しをやっていました。フレームワークは使わず、smartyとPEARを少し使った以外は全部自前で作ったのですが、そういうのも作っていて楽しかったりします。
その中でPEARのPagerを使いました。Pagerは便利なのですが、はまりやすいポイントがいくつかあると思います。今さらな感じもしますが、今回はそんな問題点とその回避方法を簡単にまとめました。
Pagerの使い方はどこか他のページを見て下さい、ということで。。。
Pagerのマニュアル
その1 post or get
factoryメソッドに渡す配列引数の中に「httpMethod」がありますが、通常はここで指定した方式のパラメータしか引き継いでくれません。いろいろなページからpagerのページに来る場合は注意する必要があります。僕は初めて使った時に失敗しました。
簡単に回避するには、factoryメソッド実行前に
$_GET = $_REQUEST; //httpMethodがgetの場合
$_POST = $_REQUEST; //httpMethodがpostの場合
としておくか、factoryメソッドに渡す配列引数の「importQuery」をfalseにして、「extraVars」を$_REQUESTまたは引き継がせたいパラメータ配列にしてやります。
importQueryはパラメータを自動で引き継ぐかどうかの設定で、デフォルトはtrueです。extraVarsに連想配列を指定すると、その配列がパラメータとして付け加えられます。
その2 パラメータの値に日本語が含まれている場合
パラメータの値に日本語のようなマルチバイト文字列が含まれていると、ページングのリンクがおかしくなる場合があります。
httpMethodがgetかpostか、内部エンコーディング、出力エンコーディングが何かによって対応が変わってきます。
getの場合
内部エンコーディングと出力エンコーディングが同じ場合は大丈夫です。
違う場合は、importQueryをfalseにし、extraVarsに渡すパラメータ配列を出力エンコーディングに直しておくのがよいと思います。
postの場合
postの場合は、内部、出力エンコーディングに関係なく問題が起こります。
postでもパラメータ文字列が全部urlencodeされて出力されてしまうからです。
一番簡単な対応は、Pager/Common.phpの930行目あたり、_generateFormOnClickHelper()メソッド内
// am I foreetting any dangerous whitespace?
// would a regex be faster?
// if it's already encoded, don't encode it again
if (!$this->_isEncoded($escapedData)) {
$escapedData = urlencode($escapedData);
}
$escapedData = htmlentities($escapedData, ENT_QUOTES, 'UTF-8');
の部分を
// am I foreetting any dangerous whitespace?
// would a regex be faster?
// if it's already encoded, don't encode it again
//if (!$this->_isEncoded($escapedData)) {
//$escapedData = urlencode($escapedData);
//}
$escapedData = htmlentities($escapedData, ENT_QUOTES, 'UTF-8');
のようにコメントアウトします。内部エンコーディングがUTF-8でない場合はhtmlentitiesの第3引数も直しておきます。
あとおまけですが、パラメータに「submit」という名前のものがあってhttpMethodがpostだと、Firefoxでは動きません。これはjavascriptの問題です。
内部エンコーディングと出力エンコーディングを同じにして、httpMethodをgetにしておけば、ほとんど問題は起こらなさそうです。