内部的迭代变量,用于更改其值


iteration variable inside for changing its value

我面对的是我不理解的东西,我尝试了很多东西。奇怪的是,这种情况只发生在一些服务器上,而在其他服务器上则不会发生。我猜这与PHP配置有关。我有这样的代码:

$j = 0 ;
                    for($m = $days - 1; $m >= 0 ; $m--){
                        $time1 = strtotime('-'.$m.' DAY');
                        $date_day = date('Y-m-d', $time1) ;
                        $$items_var[$j] = new stdClass();
                        $j++;
                    }

$days值为7。这是for循环,其中$m从6到0。嗯. .应该是这样。开始的时候很好,6 5 4 3…然后它崩溃了。通常我得到的误差是可捕获的致命错误:类stdClass的对象无法转换为字符串

所以,在某个时刻(它看起来是随机的,因为在某些服务器中是在第二次迭代之后),$m变成了一个对象…!!

这在某种程度上与代码中的赋值有关:

$$items_var[$j] = new stdClass();

是的,那是双$$。我有一个变量$items_var值是"items"。因此,我试图在一个名为$items的数组中创建这个新的stdClass()。

这是什么搞乱了代码,但我不知道为什么。如果我去掉这个赋值,代码就可以工作了。$m从6到0。但是由于某种原因,一些PHP安装把它弄乱了,这行代码将$m的值更改为一个对象。

就是这样:

是的,那是双$$。我有一个变量$items_var,它的值是"items"。

这意味着你有:

$items_var = 'items';

你使用那个字符串作为数组:

$$items_var[$j] = new stdClass();

$j = 3时,您有效地运行

$m = new stdClass();

现在用对象覆盖了您的for循环变量。在NEXT迭代中,您最终会执行

stdClass() >= 0

并产生准确的错误。

这就是为什么你应该永远不要使用变量变量。你最终会得到像这样愚蠢的/难以调试的错误。


评论跟踪:

PHP允许将字符串视为字符数组:

$foo = 'abcdefgh';
echo $foo[3] // outputs 'd'

变量变量获取变量的内容,并将其用作其他变量的名称:

$bar = 'hi mom';
$foo = 'bar';
echo $foo;  // outputs 'bar'
echo $$foo; // outputs 'hi mom'

所以给定:

$items_vars = 'items';
$j = 3;

这个顺序发生:

$$items_vars[$j] = new stdClass();
 ^-------------^
        |
$   'items'[3]   = new stdClass();
        |
$       m        = new stdClass();
$m = new stdClass();

和boom,你在for($m=....)中使用的$m现在被废弃了。


代码解构。如果你把循环分开,手写出来:

$items_vars = 'items';
$j = 0;
for($m = $days - 1; $m >= 0 ; $m--){
    $$items_var[$j] = new stdClass();

你最终会这样做:

               $$items_vars[$j]     = new StdClass:
j = 0; m =6    ${'items'[0]}  -> $i = new stdClas();
j = 1; m = 5   ${'items'[1]}  -> $t = new stdClass();
j = 2; m = 4   ${'items'[2]}  -> $e = new stdClass();
j = 3; m = 3   ${'items'[3]}  -> $m // BOOM

您没有将新的stdClass对象放入数组中。您的可变变量正在构建单字母变量名,并将stdClass放入每个变量名中。如果希望将新类存储在数组中,则需要类似

这样的内容。
array_push($$items_var, new stdClass());

将执行为

array_push($items, new stdClass());