FILTER_CALLBACKで受け取る変数は常に文字列になるでコード見たので、せっかくなので、自己解釈のコメントを入れてみたのを書いておきます。
フィルタリング関数に渡す前に、文字列に変換してる
/* #49274, fatal error with object without a toString method
Fails nicely instead of getting a recovarable fatal error. */
/* https://bugs.php.net/bug.php?id=49274 */
/* オブジェクトの場合は、文字列に変換できないかもしれないので、
convert_to_string()の直前で確認する。
*/
if (Z_TYPE_P(value) == IS_OBJECT) {
zend_class_entry *ce; /* たぶん、Class Entry の略 */
ce = Z_OBJCE_P(value);
if (!ce->__tostring) {
/* なんでrefcounterをデクリメントしてるのかはわからない */
zval_ptr_dtor(value);
/* #67167: doesn't return null on failure for objects */
/* https://bugs.php.net/bug.php?id=67167 */
if (flags & FILTER_NULL_ON_FAILURE) {
ZVAL_NULL(value);
} else {
ZVAL_FALSE(value);
}
/* 文字列に変換できない場合は、convert_to_stringを通したくない。 */
goto handle_default;
}
}
/* Here be strings */
/* 事前にStringにしてから、各filter関数を適用する */
convert_to_string(value);
filter_func.function(value, flags, options, charset);
/* 「フィルタが失敗した場合に返す値」を指定するオプション の処理
http://jp2.php.net/manual/ja/filter.filters.validate.php
*/
/* 文字列に変換できなかった場合に、ここまで飛んでこれるようにしたいので、ラベル */
handle_default:
/* 中身のコードはif文の条件式のネストが深くて厄介なので、次のコードの方に分ける */
handle_defaultラベルの中身
if (
/* オプション(PHPのfilter関数の第3引数)が指定されてて */
options
&&
/* そのオプションが配列orオブジェクトで指定されてて(≒optionの型のValidate) */
(
Z_TYPE_P(options) == IS_ARRAY
|| Z_TYPE_P(options) == IS_OBJECT
)
&&
/* フィルタリングに失敗していて */
(
(
flags & FILTER_NULL_ON_FAILURE
&& Z_TYPE_P(value) == IS_NULL
)
||
(
!(flags & FILTER_NULL_ON_FAILURE)
&& Z_TYPE_P(value) == IS_FALSE
)
)
&&
/* 「デフォルト値」の設定がある */
zend_hash_str_exists(HASH_OF(options), "default", sizeof("default") - 1)
) {
zval *tmp;
if ((tmp = zend_hash_str_find(HASH_OF(options), "default", sizeof("default") - 1)) != NULL) {
ZVAL_COPY(value, tmp);
}
}
goto使って無理やり経路追加してるあたり、良くも悪くもC言語っぽい感じしますね(笑)。php_zval_filter
だと、プリミティブ型なやつとそれ以外(オブジェクトと配列)が混ざるし、あんまよくないのかなぁとか思います。
laruence氏が最後にリファクタしたのが2014年5月7日なので、気になるんならPR投げつけてもいいかなぁとも思ったりしました。しらんけど。