ご機嫌いかがですか?CakeかわいいよCake。
確認ダイアログを自動生成してくれる confirm 属性
CakePHP Htmlヘルパーに搭載されている、第3引数に Confirm => ‘確認メッセージ’ を与えると、自動的に簡易確認窓を表示してくれるようになる機能。手抜きで確認プロセスを入れたいときには重宝する機能です。
echo $this->Html->link('削除' , '/infos/delete/' . $info['Info']['id'] , array('confirm' =>'本当にこのお知らせを削除しますか?') );
ところが、とあるシステムをリニューアルする案件でハマりました。
確認メッセージが [null] になってるですって!?
…orz わけがわからないよ。
吐き出されたソースを見てみる
<a onclick="if (confirm(null)) { return true; } return false;" href="******/infos/delete/250">削除</a>
なんでnullになってる!F*ck!
英語表記だと問題なし
「本当にこのお知らせを~?」を「are you ok?」みたいにアルファベットで書き直すとちゃんと表示されます。となると、思い当たる節は、文字コードしかない。
このシステムはEUCJPで書かれていたので、core.phpをチェック。
Configure::write('App.encoding', 'EUC-JP');
ok.
ViewのソースもちゃんとEUCになっている。なんでだ…
ライブラリを追う
\lib\Cake\View\Helper\HtmlHelper.php
function link 内
: if ($confirmMessage) { $options['onclick'] = $this->_confirm($confirmMessage, 'return true;', 'return false;', $options); } elseif (isset($options['default']) && !$options['default']) { :
特に…文字化けする要因が見当たらないなあとおもってライブラリ内にecho ($message)とか入れて簡易デバッグ。 ここでは $this->_confirmへ丸投げしているだけなのでここでは欠落しないはず
では、_confirmを見てみましょう。
ココで見つからなければ迷宮入り…!とおもいきや、原因は簡単に見つかりました。
\lib\Cake\View\Helper.php
protected function _confirm($message, $okCode, $cancelCode = '', $options = array()) { $message = json_encode($message); $confirm = "if (confirm({$message})) { {$okCode} } {$cancelCode}"; if (isset($options['escape']) && $options['escape'] === false) { $confirm = h($confirm); } return $confirm; }
参考:http://php.net/manual/ja/function.json-encode.php
PHP: json_encode – Manual
すべての文字列データは、UTF-8 エンコードされたいなければいけません。
公式マニュアルですら誤字を放置するような基本的な常識のようです。
それ以外の文字コードで処理しようとしたときの動作は保証されないということですね。
ということで、CakePHP の 簡易 confirm は UTF-8以外のシステムでは原則的に使えない機能のようです。というかそれ以外の文字コードは早く滅びて(´д`)
ここにわざわざ手を入れてまで使うより、自前でワンクッション置けるようにした方が早いですね(^_^;
未だに文字コードには泣かされます。いま泣いています。