ZendFramework の Zend_Formを利用する時にZend_Elementを利用するが、その際にSelectやRadioを利用するとMultiOptionsを指定して利用する。
この時にちょっとした落とし穴があって、本来このMultiOptionsを指定すると自動的にInArrayというValidateが追加されるこれはこの連想配列に含まれるキーに該当するかをチェックしてくれるバリデートなのだが、このキーに0が含まれる場合、つまり 0=>いいえ, 1=>はい といった場合です。
この場合InArrayは自動的にセットされない。
これが何を目的としてこうなっているのかは解らないがリファレンスにもそれらしい事は書かれているので、何かのためにあえてそうなっているようだ。。。
対処方法としては自動的にセットしてくれないので、自分でValidateにInArrayをしてやればいいんだろうと思ったけどダメみたい。。。
って、やっと解った。。。
PHPでは結構型の扱いというのが曖昧なせいで、こんな歪を発見。
in_array で
$res = in_array('aaa', array(
1,
2,
0,
));
var_dump($res);
とすると結果は TRUE となる。
なぜ?
これは'aaa'をIntにキャストすると0になってその0が入っているからTRUEとなる。。。
Zend_Validate_InArray でもこの現象が発生しているのです。。。
一応このin_arrayにはこの現象を回避するために第2引数にStrictが用意されており、ここをTRUEにすれば解消されるのですが、問題は Zend_Validate_InArray では指定できるようになっているけどElementでselectなどのMulti系を指定する時は指定できないのです。。。
なので、仕方ないので、
'validators' => array(
array (
'breakChainOnFailure' => true,
'validator' => 'InArray',
'options' => array((array)$arrayHoge, true),
),
),
として自動で入れたものをStrictをTRUEで上書きしてやるしかないのです。
また、この時に型まで見るようになるためりフォームから受け取った値はStringなので、このままだとどんな値でもエラーになります。。。
なので、今度はFilterでIntを指定してフォームの値をキャストしてやりましょう。
これで解決ですね。。。
あ~ハマった。。。