convert_to_* と convert_to_*_ex の違い
convert_to_* は、zvalを指定の型に変換するもの。convert_to_*_ex は、zvalが既に指定した型だったら終わり。で、リファレンスだったら分離して、convert_to_* を呼び出すようになっている。
zend_operators.h
#define convert_to_boolean_ex(ppzv) convert_to_ex_master(ppzv, boolean, BOOL)
#define convert_to_long_ex(ppzv) convert_to_ex_master(ppzv, long, LONG)
#define convert_to_double_ex(ppzv) convert_to_ex_master(ppzv, double, DOUBLE)
#define convert_to_string_ex(ppzv) convert_to_ex_master(ppzv, string, STRING)
#define convert_to_array_ex(ppzv) convert_to_ex_master(ppzv, array, ARRAY)
#define convert_to_object_ex(ppzv) convert_to_ex_master(ppzv, object, OBJECT)
#define convert_to_null_ex(ppzv) convert_to_ex_master(ppzv, null, NULL)
#define convert_to_ex_master(ppzv, lower_type, upper_type) \
if ((*ppzv)->type!=IS_##upper_type) { \
if (!(*ppzv)->is_ref) { \
SEPARATE_ZVAL(ppzv); \
} \
convert_to_##lower_type(*ppzv); \
}自分でも、リファレンスがあやふやになってきたので、あとでちゃんと整理しようと思う。