在PHP中,您可以使用数组语法来访问字符串索引。以下程序
<?php
$foo = "Hello";
echo $foo[0],"\n";
?>
回声
H
但是,如果您访问零长度字符串的第一个字符
<?php
$bar = "";
$bar[0] = "test";
var_dump($bar);
?>
PHP将您的字符串转换为数组。上面的代码生成
array(1) {
[0] =>
string(4) "test"
}
即。我的零长度字符串被强制转换为数组。类似&#34;访问字符串的未定义索引&#34;例子不会产生这种铸造行为。
$bar = " ";
$bar[1] = "test";
var_dump($bar);
生成字符串t
。即$bar
仍然是一个字符串,并且不会转换为数组。
当语言需要推断和/或自动为你投射变量时,我得到这些不直观的边缘情况是不可避免的,但是有谁知道这里幕后发生了什么?
即。为了实现这一点,PHP中的C / C ++级别发生了什么。为什么我的变量变成了一个数组。
PHP 5.6,如果重要的话。
答案 0 :(得分:12)
在C级别,当使用[]运算符完成赋值时,变量将转换为数组。当然,当它是一个字符串时,长度为0并且不是未设置的调用类型(例如,未设置($ test [0]))。
var distance = 100;
var angle = 4; // angle in radians
var x = Math.cos(angle) * distance;
var y = Math.sin(angle) * distance;
https://github.com/php/php-src/blob/PHP-5.6.0/Zend/zend_execute.c#L1156
布尔值为false时会发生相同的转换。
case IS_STRING: {
zval tmp;
if (type != BP_VAR_UNSET && Z_STRLEN_P(container)==0) {
goto convert_to_array;
}
使用测试确认:
case IS_BOOL:
if (type != BP_VAR_UNSET && Z_LVAL_P(container)==0) {
goto convert_to_array;
}
输出:
<?php
$bar = false;
$bar[0] = "test";
var_dump($bar);
使用true时:
array(1) { [0]=> string(4) "test" }
输出:
<?php
$bar = true;
$bar[0] = "test";
var_dump($bar);
https://github.com/php/php-src/blob/PHP-5.6.0/Zend/zend_execute.c#L1249
当值为bool类型且值为true时,将执行以下代码:
WARNING Cannot use a scalar value as an array on line number 3
bool(true)
PHP 5.6版使用ZEND版本2.6.0
答案 1 :(得分:4)
我怀疑“”被视为未设置,然后被转换为数组。通常“”!= null!=未设置,但是,就此而言,php是一个小问题。
php > $a="test"; $a[0] = "yourmom"; var_dump( $a );
string(4) "yest"
php > $a=""; $a[0] = "yourmom"; var_dump( $a );
array(1) {
[0]=>
string(7) "yourmom"
}
php > var_dump((bool) "" == null);
bool(true)
php > var_dump((bool) $f == null);
PHP Notice: Undefined variable: f in php shell code on line 1
PHP Stack trace:
PHP 1. {main}() php shell code:0
Notice: Undefined variable: f in php shell code on line 1
Call Stack:
470.6157 225848 1. {main}() php shell code:0
bool(true)
答案 2 :(得分:1)
我试图找到PHP源代码中发生的情况。我对PHP内部的经验有限,而且一般来说是C,所以如果我错了,请有人纠正我。
我认为这发生在zend_fetch_dimension_address:
if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) {
zval_ptr_dtor_nogc(container);
convert_to_array:
ZVAL_NEW_ARR(container);
zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0);
goto fetch_from_array;
}
如果容器是一个零长度的字符串,它会在它对它执行任何操作之前将其转换为数组。
答案 3 :(得分:0)
在空字符串上使用数组语法时将其更改为数组的原因是因为索引0未定义,并且在该点没有类型。这是一种案例研究。
<?php
$foo = "Hello"; // $foo[0] is a string "H"
echo $foo[0],"\n"; // H
$foo[0] = "same?"; // $foo[0] is still a string, "s" note that only the s is kept.
echo $foo,"\n"; // sello
echo $foo[0],"\n"; // s
$foo[1] = "b"; // $foo[1] is a string "b"
echo $foo,"\n"; // sbllo
$bar = ""; // nothing defined at position 0
$bar[0] = "t"; // array syntax creates an array with a string as the first index
var_dump($bar); // array(1) { [0] => string(1) "t" }