【问题标题】:Cannot use string offset as an array in php不能在php中使用字符串偏移作为数组
【发布时间】:2009-12-09 13:41:08
【问题描述】:

我正在尝试使用示例 php 代码来模拟此错误,但没有成功。任何帮助都会很棒。

"不能使用字符串偏移作为数组"

【问题讨论】:

    标签: php


    【解决方案1】:

    对于 PHP4

    ...这重现了错误:

    $foo    = 'bar';
    $foo[0] = 'bar';
    

    对于 PHP5

    ...这重现了错误:

    $foo = 'bar';
    
    if (is_array($foo['bar']))
        echo 'bar-array';
    if (is_array($foo['bar']['foo']))
        echo 'bar-foo-array';
    if (is_array($foo['bar']['foo']['bar']))
        echo 'bar-foo-bar-array';
    

    (实际上来自bugs.php.net

    编辑,

    那么为什么错误没有出现在 第一个 if 条件,即使它是 字符串。

    我猜是因为 PHP 是一种非常宽容的编程语言。我将用代码说明我认为发生了什么:

    $foo = 'bar';
    // $foo is now equal to "bar"
    
    $foo['bar'] = 'foo';
    // $foo['bar'] doesn't exists - use first index instead (0)
    // $foo['bar'] is equal to using $foo[0]
    // $foo['bar'] points to a character so the string "foo" won't fit
    // $foo['bar'] will instead be set to the first index
    // of the string/array "foo", i.e 'f'
    
    echo $foo['bar'];
    // output will be "f"
    
    echo $foo;
    // output will be "far"
    
    echo $foo['bar']['bar'];
    // $foo['bar'][0] is equal calling to $foo['bar']['bar']
    // $foo['bar'] points to a character
    // characters can not be represented as an array,
    // so we cannot reach anything at position 0 of a character
    // --> fatal error
    

    【讨论】:

    • 那么为什么错误不会出现在第一个if条件中,即使它是一个字符串。
    • “为什么第一个if条件没有出现错误”?这是您的答案:在字符串上使用括号语法时,您定义的是偏移量,而不是键。因为它需要一个偏移量,所以括号内传递的任何内容都会立即转换为整数。如果您将字符串“bar”转换为整数,则结果将是值为 0 的整数。这意味着 0 作为偏移量传递。在字符串的偏移量 0 处,我们有字母“b”,因此返回“b”。如果您使用一组额外的括号,PHP 会将括号访问视为一个数组,因此会显示您的错误。
    • 看来PHP5.4不会再对echo $foo['bar']['bar']抛出错误了
    【解决方案2】:

    升级到 PHP 7 后,我能够重现此问题。当您尝试将数组元素强制转换为字符串时,它会中断。

    $params = '';
    foreach ($foo) {
      $index = 0;
      $params[$index]['keyName'] = $name . '.' . $fileExt;
    }
    

    更改后:

    $params = '';
    

    到:

    $params = array();
    

    我停止收到错误消息。我在bug report thread 中找到了解决方案。我希望这会有所帮助。

    【讨论】:

    • 我想这应该是答案。我也犯了这个错误……
    • 是的,这应该是答案。谢谢!
    • 此线程上的最简单答案。我已经修复了这个错误一千次,我总是意识到这是因为有人试图在非数组变量上强制索引。
    【解决方案3】:

    我遇到了类似的问题,所以在这里记录以备不时之需。

    __get() 方法中,我使用给定参数作为属性,如(简化示例):

    function __get($prop) {
         return $this->$prop;
    }
    

    ...即$obj->fred 将访问该类的私有/受保护的 fred 属性。

    我发现当我需要在这个属性中引用一个数组结构时,它会产生不能使用字符串偏移作为数组错误。这是我做错了什么以及如何纠正它:

    function __get($prop) {
         // this is wrong, generates the error
         return $this->$prop['some key'][0];
    }
    
    function __get($prop) {
         // this is correct
         $ref = & $this->$prop;
         return $ref['some key'][0];
    }
    

    解释:在错误的示例中,php 将['some key'] 解释为$prop(字符串)的键,而我们需要它来取消引用$prop。在 Perl 中,您可以通过使用 {} 指定来做到这一点,但我认为这在 PHP 中是不可能的。

    【讨论】:

      【解决方案4】:

      我在尝试调试一些现在在 PHP 7.30 上运行的旧代码时第一次遇到此错误。简化后的代码如下所示:

      $testOK = true;
      
      if ($testOK) {
          $x['error'][] = 0;
          $x['size'][] = 10;
          $x['type'][] = 'file';
          $x['tmp_name'][] = 'path/to/file/';
      }
      

      最简单的解决办法是在之前将 $x 声明为 array():

      $x = array();
      
      if ($testOK) {
          // same code
      }
      

      【讨论】:

        【解决方案5】:

        我遇到了这个错误,很疯狂

        我的代码是

        $aux_users='';
        
        foreach ($usuarios['a'] as $iterador) { 
        #code
        if ( is_numeric($consultores[0]->ganancia) ) {
            $aux_users[$iterador]['ganancia']=round($consultores[0]->ganancia,2);
          }
        }
        

        $aux_users=''; 更改为$aux_users=array();

        它发生在我的 php 7.2 中(在生产服务器中!)但正在使用 php 5.6 和 php 7.0.30,所以请注意!感谢年轻的迈克尔,我希望它也能帮助到你!

        【讨论】:

          【解决方案6】:

          自 PHP 7.1+ 发布以来,不可能为数组赋值,如下所示:

          $foo = ""; 
          $foo['key'] = $foo2; 
          

          因为从 PHP 7.1.0 开始,对字符串应用空索引运算符会引发致命错误。以前,字符串被静默转换为数组。

          【讨论】:

            【解决方案7】:

            我只是想解释一下我解决相同问题的方法。

            我之前的代码(同样的错误):

            $arr2= ""; // this is the problem and solve by replace this $arr2 = array();
            for($i=2;$i<count($arrdata);$i++){
                $rowx = explode(" ",$arrdata[$i]);
                $arr1= ""; // and this is too
                for($x=0;$x<count($rowx);$x++){
                    if($rowx[$x]!=""){
                        $arr1[] = $rowx[$x];
                    }
                }
                $arr2[] = $arr1;
            }
            for($i=0;$i<count($arr2);$i++){
                $td .="<tr>";
                for($j=0;$j<count($hcol)-1;$j++){
                    $td .= "<td style='border-right:0px solid #000'>".$arr2[$i][$j]."</td>"; //and it's($arr2[$i][$j]) give an error: Cannot use string offset as an array
                }
                $td .="</tr>";
            }
            

            我的代码之后并解决了它:

            $arr2= array(); //change this from $arr2="";
            for($i=2;$i<count($arrdata);$i++){
                $rowx = explode(" ",$arrdata[$i]);
                $arr1=array(); //and this
                for($x=0;$x<count($rowx);$x++){
                    if($rowx[$x]!=""){
                        $arr1[] = $rowx[$x];
                    }
                }
                $arr2[] = $arr1;
            }
            for($i=0;$i<count($arr2);$i++){
                $td .="<tr>";
                for($j=0;$j<count($hcol)-1;$j++){
                    $td .= "<td style='border-right:0px solid #000'>".$arr2[$i][$j]."</td>";
                }
                $td .="</tr>";
            }
            

            谢谢。 希望它有所帮助,如果我的英语像男孩的房间一样混乱,我很抱歉:D

            【讨论】:

            • 只是给喜欢使用上述代码的人的一个小提示。无需一遍又一遍地计算 $arrdata$arr2 数组元素,因为它们在循环期间不会改变。改用这样的东西:$counter = count($arrdata); for( $i = 2 ; $i &lt; $counter ; $i++ ) {
            【解决方案8】:

            当您直接打印print_r(($value['&lt;YOUR_ARRAY&gt;']-&gt;&lt;YOUR_OBJECT&gt;)); 时,它会显示此致命错误Cannot use string offset as an object in。 如果你这样打印

            $var = $value['#node']-><YOU_OBJECT>; print_r($var);

            你不会得到错误的!!

            【讨论】:

              【解决方案9】:

              我相信您要问的是 PHP 中的变量插值。

              让我们做一个简单的夹具:

              $obj = (object) array('foo' => array('bar'), 'property' => 'value');
              $var = 'foo';
              

              现在我们有了一个对象,其中:

              print_r($obj);
              

              会给出输出:

              stdClass Object
                  (
                      [foo] => Array
                          (
                              [0] => bar
                          )
              
                      [property] => value
                  )
              

              我们有包含字符串“foo”的变量$var

              如果您尝试使用:

              $give_me_foo = $obj->$var[0];
              

              代替:

              $give_me_foo = $obj->foo[0];
              

              您会收到“不能将字符串偏移量用作数组 [...]”的错误消息,因为您正在尝试做的实际上是将消息 $var[0] 发送到对象 $obj。而且 - 正如您从夹具中看到的 - 没有定义 $var[0] 的内容。变量$var是一个字符串并且不是一个数组

              在这种情况下你可以做的是使用花括号,这将确保首先被称为$var 的内容,然后是消息发送的其余部分:

              $give_me_foo = $obj->{$var}[0];
              

              结果是"bar",正如您所料。

              【讨论】:

                【解决方案10】:

                错误发生在:

                $a = array(); 
                $a['text1'] = array();
                $a['text1']['text2'] = 'sometext';
                

                然后

                echo $a['text1']['text2'];     //Error!!
                

                解决方案

                $b = $a['text1'];
                echo $b['text2'];    // prints: sometext
                

                ..

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-02-21
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-10-04
                  • 1970-01-01
                  相关资源
                  最近更新 更多