PHP在变量中不需要(或支持)显式类型定义 宣言;变量的类型取决于上下文 使用变量。
var_dump((string)[]);
输出:
NOTICE Array to string conversion on line number 3
string(5) "Array"
var_dump(substr([], 1));
输出:
WARNING substr() expects parameter 1 to be string, array given on line number 5
NULL
答案 0 :(得分:1)
substr
是一个内置函数,并进行类型检查internally。由于它期望一个字符串(Z_PARAM_STR(str)
),因此会引发警告,并且该函数将立即返回null
,而在类型检查之后不执行任何操作。
如果您希望获得与第一个示例相同的行为,也可以手动进行类型转换。
var_dump(substr((string)[], 1));
请记住,从数组到字符串的转换仍然是“无效”的,并会发出通知。甚至有一个rfc想要完全弃用这种行为。
答案 1 :(得分:1)
TL; DR
在解析类型参数时,PHP不会将数组变型成字符串。
长版
首先,将某些内容转换为字符串由函数_convert_to_string
处理,而将数组转换为字符串则由代码处理:
case IS_ARRAY:
zend_error(E_NOTICE, "Array to string conversion");
zval_ptr_dtor(op);
ZVAL_NEW_STR(op, zend_string_init("Array", sizeof("Array")-1, 0));
break;
这是将数组转换为字符串,但还会发出通知,提示数组到字符串转换(此处的重要信息)。
我找不到明确的文档,但它似乎与以下事实有关:
1)zend_types.h处的源定义了以下类型常量:
#define IS_UNDEF 0
#define IS_NULL 1
#define IS_FALSE 2
#define IS_TRUE 3
#define IS_LONG 4
#define IS_DOUBLE 5
#define IS_STRING 6
#define IS_ARRAY 7
还有更多,但它们并不相关。
2)PHP内部使用Z_PARAM_STR
读取字符串参数,那里的代码来回多了,但是归结为调用zend_parse_arg_str_weak
3)应该负责类型变戏法,但有以下几行:
if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) {
convert_to_string(arg);
*dest = Z_STR_P(arg);
}
这意味着如果类型标识符小于字符串标识符,它将不调用convert_to_string
(依次调用上述的_convert_to_string
)。数组的类型标识符为7,大于字符串的6,因此不会发生类型变化。没有发出数组到字符串转换通知的事实也表明了这一点,这意味着根本不会调用类型转换代码。
对象将在函数zend_parse_arg_str_weak
中得到特殊处理,该函数主要是调用对象具有的任何特殊字符串转换函数(例如__toString
)。
答案 2 :(得分:0)
它返回rray
,您只需要将(string)[]
传递给substr而不是数组
$a = [];
$b = (string)$a;
echo substr($b, 1);
此代码的结果:https://3v4l.org/UqRqq
substr
不会在内部 cast 变量进行内部字符串转换,因为它需要将string作为第一个参数并在字符串上进行操作,因此您必须在传递之前手动对其进行强制转换,否则它将只是说这不是字符串,它可能是一种帮助发现代码错误的机制,以防万一您无意将array
或object
传递给substr
答案 3 :(得分:0)
因为在substr函数中使用时它不是类型转换,因为substr以字符串作为参数并给出了数组。如果使用了
var_dump(substr((string)[], 1));
它将返回“ rray”;
答案 4 :(得分:0)
可能任何内置函数都可以拥有自己的强制类型算法。
因此,某些不触发[]
到"Array"
转换的功能没什么特别的。
我只是推测,但是在C语言中,字符串和字符数组之间没有区别。因此(字符的)空数组的子字符串为null或空数组。
看起来substr
将该行为泄露给了PHP。
答案 5 :(得分:0)
类型变戏法实验:
var_dump(substr("Hello" , 1));
Output : string(4) "ello"
var_dump(substr(Hello , 1));
Output : string(4) "ello"
var_dump(substr(10000 , 1));
Output : string(4) "0000"
var_dump((string)[]);
Output : Array
var_dump(substr((string)[], 1));
Output : rray
var_dump(substr(false , 1));
Output : bool(false)
var_dump(substr(1 , 1));
Output : bool(false)
var_dump(substr(array() , 1));
Output : string(5) "Array" NULL substr() expects parameter 1 to be string, array given on line 6
var_dump(substr(&&& , 1));
Output : syntax error, unexpected '&&' (T_BOOLEAN_AND)
var_dump(substr(class , 1));
output : syntax error, unexpected 'class' (T_CLASS)
var_dump(substr(BREAK , 1));
syntax error, unexpected 'break' (T_BREAK)
结论(基于上述示例集):仅当PHP类型substr()不是保留字符串时,才将其转换为字符串。