53

I'm trying to simulate this error with a sample php code but haven't been successful. Any help would be great.

"Cannot use string offset as an array"

0

10 Answers 10

67

For PHP4

...this reproduced the error:

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

For PHP5

...this reproduced the error:

$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';

(From bugs.php.net actually)

Edit,

so why doesn't the error appear in the first if condition even though it is a string.

Because PHP is a very forgiving programming language, I'd guess. I'll illustrate with code of what I think is going on:

$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
Sign up to request clarification or add additional context in comments.

3 Comments

so why doesn't the error appear in the first if condition even though it is a string.
"why doesn't the error appear in the first if condition"? here is your answer: when using bracket syntax on strings, you are defining an offset, not a key. because it's expecting an offset, whatever is passed within the brackets is immediately cast to an integer. if you take the string "bar" and cast it to an integer, the result will be integer with a value of 0. this means 0 is being passed as the offset. at offset 0 of the string we have the letter "b", so "b" is returned. if you use an additional set of brackets, PHP treats that bracket access as an array, hence your error being displayed.
It appears that PHP5.4 will no longer throw an error on echo $foo['bar']['bar']
37

I was able to reproduce this once I upgraded to PHP 7. It breaks when you try to force array elements into a string.

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

After changing:

$params = '';

to:

$params = array();

I stopped getting the error. I found the solution in this bug report thread. I hope this helps.

2 Comments

This should be the answer, I think. I made this mistake too...
Simplest answer on this thread. I've fixed this error a thousand times and I always realize it's because someone was trying to force indexes on a non-array variable.
4

I was fighting a similar problem, so documenting here in case useful.

In a __get() method I was using the given argument as a property, as in (simplified example):

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

...i.e. $obj->fred would access the private/protected fred property of the class.

I found that when I needed to reference an array structure within this property it generated the Cannot use String offset as array error. Here's what I did wrong and how to correct it:

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];
}

Explanation: in the wrong example, php is interpreting ['some key'] as a key to $prop (a string), whereas we need it to dereference $prop in place. In Perl you could do this by specifying with {} but I don't think this is possible in PHP.

Comments

4

I had this error for the first time ever while trying to debug some old legacy code, running now on PHP 7.30. The simplified code looked like this:

$testOK = true;

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

The simplest fix possible was to declare $x as array() before:

$x = array();

if ($testOK) {
    // same code
}

Comments

3

I was having this error and a was nuts

my code was

$aux_users='';

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

after changing $aux_users=''; to $aux_users=array();

it happen to my in php 7.2 (in production server!) but was working on php 5.6 and php 7.0.30 so be aware! and thanks to Young Michael, i hope it helps you too!

Comments

3

Since the release PHP 7.1+, is not more possible to assign a value for an array as follow:

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

because as of PHP 7.1.0, applying the empty index operator on a string throws a fatal error. Formerly, the string was silently converted to an array.

Comments

1

I just want to explain my solving for the same problem.

my code before(given same error):

$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>";
}

my code after and solved it:

$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>";
}

Thank's. Hope it's helped, and sorry if my english mess like boy's room :D

1 Comment

Just a small tip for people who like to use the above code. There is no need to count the $arrdata and $arr2 array elements over and over because they don't change during the loop. Use something like this instead: $counter = count($arrdata); for( $i = 2 ; $i < $counter ; $i++ ) {
1

When you directly print print_r(($value['<YOUR_ARRAY>']-><YOUR_OBJECT>)); then it shows this fatal error Cannot use string offset as an object in. If you print like this

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

You won't get the error!!

Comments

0

I believe what are you asking about is a variable interpolation in PHP.

Let's do a simple fixture:

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

Now we have an object, where:

print_r($obj);

Will give output:

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

        [property] => value
    )

And we have variable $var containing string "foo".

If you'll try to use:

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

Instead of:

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

You get "Cannot use string offset as an array [...]" error message as a result, because what you are trying to do, is in fact sending message $var[0] to object $obj. And - as you can see from fixture - there is no content of $var[0] defined. Variable $var is a string and not an array.

What you can do in this case is to use curly braces, which will assure that at first is called content of $var, and subsequently the rest of message-sent:

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

The result is "bar", as you would expect.

Comments

-1

The error occurs when:

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

Then

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

Solution

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

..

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.