【CakePHP/KtaiLibrary】複数submit設置でセッションキーが消える!?

icon_ktaisession.use_trans_sidがらみでまた問題が確認されました。

これは大変に不思議なことなのですが、フォーム内に複数のsubmitを設置したい場合があると思うのですが、この場合にどちらか片方(おそらく最後にあるもの「以外」のもの)を押した場合、クエリストリング中のセッションキーが消えてしまう、という現象に遭遇しています。submitが一つだけ存在する場合、もしくは最後のsubmitを押した場合は問題がないのです。

つまり、携帯サイトの場合、docomo携帯で一部フォームで正常に動かなくなる事態に遭遇する、というわけです。

いろいろなケースで試してみたのですが、結局分からず。
最終手段として、「url_rewriter.tags」を変更することで、セッションキーが継続され、問題解決ができました。
具体的には、Ktai Libraryの「app/config/ktai_session.php」の末尾にある設定箇所を変更します。


//formの場合の設定を変更
//    ini_set('url_rewriter.tags', 'a=href,area=href,frame=src,input=src,form=fakeentry,fieldset=');
ini_set('url_rewriter.tags', 'a=href,area=href,frame=src,input=src,form=action,fieldset=');

ところで、「fakeentry」というパラメータはなんなんでしょうかね?
これはデフォルトのPHP設定なのですが。
なぜ「action」ではないのか、私には分かりません。

この件に関しては、ライブラリの修正はちょっと待って、しばらく様子を見ようと思います。
ちょっと変更することによる影響が分かりませんので。
問題ないようなら更新したいと思います。

【KtaiLibrary】バージョン0.1.0公開!

icon_ktaiお待たせいたしました!
Ktai Library 0.1.0の公開を開始しました。
上記タブ「Ktai Library for CakePHP」からダウンロードできます。

繰り返しになりますが、構築済みサイトにKtai Libraryを適用する場合は、app_controllerを上書きしないように、特に気をつけてください。バックアップをとることをお薦めいたします。

今後のバージョンアップについてですが、現在 app_controllerに書いているリダイレクト対応を、将来的にはコンポーネント中で行うようにしたいと考えています。他の記事でも書いていますが、現在のCakePHPで実装されています「beforeRedirectコールバック」が想定していない実装になっているためで、チケットを投げている最中です(regenさんありがとうございます)。修正されたら、Ktai Libraryも修正を行い、さらに手間のかからない導入が出来るようにしたいと考えています。
機能的なバージョンアップは、後は細々としたものになりそうです。GPS対応とか、そういったものになりそうです。また、現在い携帯SCOについて勉強を始めたところでして(遅すぎ?)、そういったものも興味あります。もしアイデアなどありましたら是非お寄せください。

【追記】
ダウンロードページの0.1.0のファイルリンクが間違っていました。
0.0.2版がダウンロードされてしまった方は再度ダウンロードし直してください。
申し訳ございません。

【KtaiLibrary】0.1.0RC1に移行しました

icon_ktaiバージョンを0.1.0RC1とし、問題がなければリリースしたいと考えています。
特にDoCoMoをお持ちの方にセッション関連のテストをしていただけると嬉しいです。

今回は、今更になってしまうのですがiMODEシミュレータ(II)を導入しまして、こちらでも軽いiMODEチェックが出来るようになりましたので、セッション周りは一通り試しました。beta版は全然ダメでしたが、修正が入ってとりあえず正しく動くようになったかと思います。また、namedパラメータ付きのテストが入っていなかったので、追加しました。

そして、肝心のリダイレクト実装に関してですが…
一晩悩み、結局はapp_controller.phpを添付する方向で実装することにしました。リダイレクトはauthだけでなくscaffoldやsecurityでも使っていますので、外部でどうこうするのはやはり無理があるという結論です。
なので、新しく制作する場合はapp_controller.phpをまずコピーしてもらい、制作中のサイトで既にapp_controllerがある場合はredirect関数の部分をペーストしていただくことになります。

一桁(?)の時はライブラリの丸ごとコピーで動作したのでとても簡単でしたが、今回からは、このapp_controller.phpの件と、それからroutes.phpのnamedセパレータの修正が必要になりますので、是非注意していただきたいと思います。

app_controllerといえば、ちょっとはまってしまったのでご紹介。
初めてapp_controllerを設置する場合は、tmp/cache/persistent内をフラッシュしないと、更新されないので注意。何故かというと、App::import(というかtreeかも)でパスをキャッシュしているんですよね。フラッシュしないとcake/libs/controllers/app_controller.phpを読み続けます。
これはapp_controllerの他に、app_modelとか、デフォルトがあるものは全部が対象になるかと思います。

【KtaiLibrary】次バージョン(0.1.0)をGW明けに公開予定!

icon_ktaiお待たせしていましたKtai Libraryの次バージョンをGW明けに公開しようと思っています。

仕組み部分のソースコードは結構前から準備していたのですが、半分は仕事関連で忙しかったこと、もう半分は先日にお騒がせしていたnamedパラメータのセパレータ問題で方針が決まっていなかった事があります。セパレータを直さない方向でも模索していましたが、やはりリスクが大きいため、「携帯対応にはセパレータ変更が必須」という事にはなってしまいますがこの方向で実装を決定することにしました。

上記問題があったとはいえ、セッション対応が完了することでようやく携帯サイトに関する最低限の機能をひとまとめに出来たことになり、とりあえずはライブラリを組み込むだけで各キャリア対応のサイトが出来ることになると思います。まだまだいろいろやり足りない部分はあるのですが、それは追々増やしていこうと思っています。

明日あたりからテストサイトの方で準備をし始め、新機能に関する情報を追加していく予定です。
おたのしみに。

【CakePHP】namedパラメータのセパレータについて皆さんにお聞きしたいこと

cake-logoはい、恥ずかしい文章でCakePHPのバグチケットを投げたのは私です(^^:::::::。
現在形と過去形が入り乱れ、しかも後で読み返したら凄い文章になっていました。フォーラムの投稿と違って、一度書いたら消せないので、超恥ずかしい… 全然ダメダメですね(;^;)。

さて本題なのですが…
namedパラメータでsession.use_trans_sidが動作をしない件は、前回の記事で書いたとおりなのですが、それを回避するKtai Libraryでの実装方法について大変に悩んでいます。実は、先日生け贄になっていただいた方にもご相談し、Router::named[‘separator’]を別の文字にすることで回避しようと決めたのですが、それが実は半分しかうまくいっていないことに気がつき、また迷宮入りしているところです。

実装に関する今までの経緯を簡単に説明すると、session.use_trans_sidを有効とするところまではうまくいったのですが、テストで制作するサイトに載せるとセッションキーを更新しないため、あれこれやっていました。iMODE端末を持っていないため、とりあえずブラウザのセキュリティをいじり、クッキーを用いない設定でアクセスすると、セッションは一向に保存されません。

このとき、制作しているサイトの関係でnamedパラメータ付きのURLで試していたのですが、このパラメータを取ってみたところ問題なく動作し、さらにnamedパラメータのセパレータを「:」から「~」に変更したところ、正しい動きをするようになりました。そこで RFC を確認したところ、「:」は予約されたキャラクターと書かれていたため、これが原因ではないかと確信した次第です。

router.phpを眺めてみたところ、urlを作成している部分はstartup処理内で行っているようなので、それより前の処理として、componentのinitializeで設定すれば間に合うんじゃないかと思い、ktai.php内で書いてみたところ、URLが正しく処理され、想定していたsid付きのURLとなりました。

この方向で実装をしようと方針を決め、リリース寸前まで来ていたのですが、新たに問題が発生! 確かにURLは作られ、一見動作しているように感じたのですが、そのURLが次のレスポンスでnamedパラメータとしてパースされないことが分かりました。何故かというと、argsを取り出しているのがdispatcher内部で、initializeより前にnamedを取り出す処理が完了してしまっていたからです。いろいろ模索をしてみたのですが、タイミング的にrouter.php内のソースを変更する以外に方法は見あたらず、ライブラリとしてこの値をどうにかする方法が採れないことが分かったのです。

ここで問題になるのは2つの事柄です。
まず一つは「namedセパレータを変えることがそもそも受け入れられるのか?」ということです。おそらく以前のバージョンからずっとこのルールの筈ですから、もう世界中に浸透してしまっているURLです。それを「Ktai Libraryでは変えてください」というルールがまかり通るか、ということなのです。
もう一つは「router.phpを直接変更する作業が必要」ということで、ライブラリ化できない部分(つまりインストールするだけでは済まなくなった)点についてどう思われるか、ということです。私的には、この繁雑な作業はバグを生み出す元となる可能性があるため、出来れば避けたいのです。

じゃあ、そもそもnamedセパレータを変えずに、さらにsession.use_trans_sidすらも使わない方法で、手動でsidを埋め込めば? という話になるのですが、それも大変に困難です。何故ならpaginateで必ずHtmlHelper::link()を使っていて、ここに及ばせる方法がないのです。この問題さえなければ、Ktai::link()を必ず使ってもらう方向で進められるのですが、paginateに対応できないとなると、魅力が薄れてしまいます。また、完全対応するためにはHtmlHelperもしくはPaginateにパッチを当てたものをcakeディレクトリにコピーしてもらうことになりかねないため、Cakeのバージョンが上がった場合に不具合を生みかねないという問題もあります。

一応、もう1つの逃げ道は考えられ、app/config/dispatcher.phpで設定してしまう、という方法もアルにはあります。しかしこの段階でRouterはロードされていないため、importする必要が出てきます。つまり、Dispatcher内でRouteは二重に読み込まれることになり、ただでさえ悪名高いimportを重複して使いたくないという思いもあります。でも、今のところライブラリ化出来る唯一の方法かもしれません。

まあ早い話、CakePHPの方でセパレータ文字を別の文字にしてくれれば、何も考えずにsession.use_trans_sidを有効にするだけでセッション問題は解決できるため、これが一番スマートなので、とりあえずチケットを投げたのですが、たぶん無理でしょう。今まで制作したサイトで不具合が出るでしょうから。「RFCの予約文字」と言う点だけが唯一の頼みの綱なのですが…

というわけで、皆さんはどうやったら一番良い方法で解決できると思われるか、是非ご意見を聞きたいです。よろしくお願いいたします。

【CakePHP】session.use_trans_sid=1をCakePHPで使う場合の注意

cake-logo「Ktai Library」をバージョンアップする際の研究で分かったことがあります。
「session.use_trans_sid=1」でクッキーが使えないブラウザ(例えばiMODE)でもセッションを使う対処をしたい場合、一部ページでセッションが切れる場合があります。
検索するとまず出てくるのが「リダイレクトをした場合」で、これはまだ一般的だと思いますが、実はそれ以外でも発生することが分かりました。

paginateを使っていない方には縁がないのかもしれませんが、CakePHPではGETパラメータを使わずにパラメータを挿入する機能があり ます。それは「/hoge/fuga/param:value」のようにコロンで区切ることで、パラメータを挿入することが出来ます。
ところが、この場合、PHP側で「別サイトへのリンク」と誤認識するようで、セッションキーをくっつけないのです。

例えば、次のようにテストをすることが出来ます。

<?php echo $html->link('これはOKな例です', array('controller' => 'hoge', 'action' => 'fuga')); ?>
<?php echo $html->link('これはNGな例です', array('controller' => 'hoge', 'action' => 'fuga'), 'param' => 'value'); ?>

いろいろなTipsを参考にしてKtaiLibraryに組み込んでみたのですが、全く想定した動作にならず、まる2日悩みました。まさかこんなオチがあったとは…
というわけで、「session.use_trans_sid」を用いてセッションを解決しようとしている場合は気をつけましょう。
基本的に、linkタグにセッションキーを手動で貼り付けるか、Router::named[‘separator’]の文字列を変更する以外の解決方法はなさそうです。
困ったなぁ…

【追記】
こちらの方で詳細を書きました。是非ご意見をお寄せください。

▼【CakePHP】namedパラメータのセパレータについて皆さんにお聞きしたいこと
http://blog.ecworks.jp/archives/531

【Ktai Library】とか言いながらもう次バージョンの話

icon_ktaiまたお騒がせすることになるかもしれません。

先日発表しました「Ktai Library 0.0.2」ですが、今度こそバージョンアップを行い、そしてしばらく打ち止めにして次のプロジェクト(?)に移るつもりでいます。
昨日の一件で、ご迷惑をおかけしたため近日中のバージョンアップは行わないつもりでいたのですが、先ほど片手間に作ってみたものがうまくいったのと、やはり緊急で解決しておいたほうがいいだろうという、先延ばしにしていた機能を搭載したものを追加してリリースすることで、念願だったマイナーバージョンのカウントアップをしようと考えています。

まず「片手間」の方ですが、携帯サイトへの誘導に不可欠な「QRコード生成」に対応します。携帯サイトとしてはあまり意味のない機能ですが、ソース量もとても小さいためメモリの負担もありません。その秘密は「Google chart API」! この素晴らしいAPIのおかげで、一からコーディングしなくて済みました(笑)。そしてこれもあまり意味がないですが、例のストレッチ対応もしております。

それから、これは皆さんも待望されているかと思うのですが、「DoCoMoのセッション対応」を正式に組み込む予定です。実は仕組みを「一般化する」のが難しいと考えていたために逃げていた所があったのですが、解決できそうな手法をひらめいたため、早速実装を進めているところです。ちなみに、セッションスタート時の処理に加え、redirect対応も盛り込みます。
それに伴い、キャリア判別の挙動が少し変わる予定です。普通にお使いの分には変わらないと思うので問題ないとは思いますが、今のところの構想では、プラス若干使い勝手が良くなる予定です。実装が不可能の場合は、もう一つ別の手法を考えていますが、あまりスマートな実装ではないためちょっと考え中です。

ちなみに、打ち止めとは言っていますが、当ライブラリは機種情報のデータをライブラリ内に持っていますので、新機種が発売されたときなどのタイミングで定期的に更新はしていく予定です。その点はご安心ください。