242

I get a strange PHP error after updating my php version to 5.4.0-3.

I have this array:

Array
(
    [host] => 127.0.0.1
    [port] => 11211
)

When I try to access it like this I get strange warnings

 print $memcachedConfig['host'];
 print $memcachedConfig['port'];


 Warning: Illegal string offset 'host' in ....
 Warning: Illegal string offset 'port' in ...

I really don't want to just edit my php.ini and re-set the error level.

Bharata
  • 13,509
  • 6
  • 36
  • 50
thesonix
  • 3,200
  • 4
  • 20
  • 19
  • 22
    Obviously `$memcachedConfig` is not that array. Show `var_dump($memcachedConfig);` – zerkms Mar 26 '12 at 08:56
  • just a guess, but have you tried using actual strings as keys? I mean, `['host'] => '127.0.0.1'` – maialithar Mar 26 '12 at 08:57
  • Shouldn't it be `['host'] => '127.0.0.1'` etc. ? – luukes Mar 26 '12 at 08:58
  • use `var_dump()` not `print_r()` and you will see what `$memcachedConfig` really is. – Vytautas Mar 26 '12 at 08:58
  • 1
    It means the keys does not exist. Check your variable with `var_export($memcachedConfig)` just before the "print". – Skrol29 Mar 26 '12 at 08:59
  • I believe the latest version of php (like many language updates throughout the web) are trying to deprecate loose key references, i.e., without quotes. I would (as h4b0) mentioned try adding the quotes during declaration. Otherwise it might be creating random values in memory that are no longer accessible via prior techniques. I sympathize, trust me. – Mark Löwe Mar 26 '12 at 09:00
  • 12
    What most people missed is this doesn't exactly mean the index doesn't exist -- that produces "undefined index" message. This is a different error. – grantwparks Jul 19 '14 at 06:24
  • 8
    http://stackoverflow.com/a/20271518/2898712 is the correct answer here. – wedi Jun 19 '15 at 20:18
  • 26
    Attention anyone viewing this question: Correct answer to this question is _not_ the one marked; correct is Kzqai's below – Aaron Jan 29 '16 at 19:33

17 Answers17

388

The error Illegal string offset 'whatever' in... generally means: you're trying to use a string as a full array.

That is actually possible since strings are able to be treated as arrays of single characters in php. So you're thinking the $var is an array with a key, but it's just a string with standard numeric keys, for example:

$fruit_counts = array('apples'=>2, 'oranges'=>5, 'pears'=>0);
echo $fruit_counts['oranges']; // echoes 5
$fruit_counts = "an unexpected string assignment";
echo $fruit_counts['oranges']; // causes illegal string offset error

You can see this in action here: http://ideone.com/fMhmkR

For those who come to this question trying to translate the vagueness of the error into something to do about it, as I was.

Kzqai
  • 22,588
  • 25
  • 105
  • 137
  • 11
    I bet it can be shown this was the reason the original problem happened. Most comments incorrectly assume "undefined index" was the error. – grantwparks Jul 19 '14 at 06:28
  • 3
    Sometimes this error may occur when attempting to grab the wrong node of a multidimensional array, i.e. going "too deep", you need the selection's parent instead – zoltar Mar 28 '18 at 09:23
  • This is correct, I used `fetchAll(PDO::FETCH_ASSOC)` instead `fetch(PDO::FETCH_ASSOC)` and worked perfectly. – MNN Jul 25 '18 at 17:42
  • 1
    Accidentially I have been using the same `$variablename = [];` twice, at another part of my code with `$variablename = "test";` which caused the error message. – Avatar Sep 26 '19 at 14:25
  • With this error, look backwards where your variable is defined. In my case the error was using $tables = array_fill_keys( $keys, '' ), followed by $tables[$key]['name'] = 'something' - which is sloppy as $table[$key] isn't an array but a string. – Herbert Van-Vliet Jul 01 '20 at 08:01
102

You're trying to access a string as if it were an array, with a key that's a string. string will not understand that. In code we can see the problem:

"hello"["hello"];
// PHP Warning:  Illegal string offset 'hello' in php shell code on line 1

"hello"[0];
// No errors.

array("hello" => "val")["hello"];
// No errors. This is *probably* what you wanted.

In depth

Let's see that error:

Warning: Illegal string offset 'port' in ...

What does it say? It says we're trying to use the string 'port' as an offset for a string. Like this:

$a_string = "string";

// This is ok:
echo $a_string[0]; // s
echo $a_string[1]; // t
echo $a_string[2]; // r
// ...

// !! Not good:
echo $a_string['port'];
// !! Warning: Illegal string offset 'port' in ...

What causes this?

For some reason you expected an array, but you have a string. Just a mix-up. Maybe your variable was changed, maybe it never was an array, it's really not important.

What can be done?

If we know we should have an array, we should do some basic debugging to determine why we don't have an array. If we don't know if we'll have an array or string, things become a bit trickier.

What we can do is all sorts of checking to ensure we don't have notices, warnings or errors with things like is_array and isset or array_key_exists:

$a_string = "string";
$an_array = array('port' => 'the_port');

if (is_array($a_string) && isset($a_string['port'])) {
    // No problem, we'll never get here.
    echo $a_string['port'];
}

if (is_array($an_array) && isset($an_array['port'])) {
    // Ok!
    echo $an_array['port']; // the_port
}

if (is_array($an_array) && isset($an_array['unset_key'])) {
    // No problem again, we won't enter.
    echo $an_array['unset_key'];
}


// Similar, but with array_key_exists
if (is_array($an_array) && array_key_exists('port', $an_array)) {
    // Ok!
    echo $an_array['port']; // the_port
}

There are some subtle differences between isset and array_key_exists. For example, if the value of $array['key'] is null, isset returns false. array_key_exists will just check that, well, the key exists.

Community
  • 1
  • 1
Jon Surrell
  • 9,444
  • 8
  • 48
  • 54
37

Please try this way.... I have tested this code.... It works....

$memcachedConfig = array("host" => "127.0.0.1","port" => "11211");
print_r($memcachedConfig['host']);
letsnurture
  • 2,193
  • 1
  • 17
  • 20
  • 1
    Found it. Thanks for your help. var_dump helped. I loaded the array from a config file, which had the strage content like this. array(2) { ["host"]=> string(9) "127.0.0.1" ["port"]=> string(5) "11211" } string(5) "m_prefix" PHP 5.4 now $xx['host'] threw the warning correctly. – thesonix Mar 26 '12 at 09:17
  • I had the same error after an `include_once($file);`. The array has been built correctly (the debug info shows this), however it had to be copied manually into another array before having been usable without the PHP illegal stringoffset warning message. – Franz Holzinger Feb 06 '16 at 11:46
  • $sStartDate = date("Y-m-d",strtotime($feed['DTSTART']['value'])); $sEndDate = date("Y-m-d", strtotime($feed['DTEND']['value'])); How to fix the same error here Warning: Illegal string offset – J. Shabu Jun 15 '17 at 11:23
  • 7
    What about explaining why this works and why the OP's code doesn't? Answers like these are the main reason why people are sceptical of Stack Overflow, even though there are lots of people who are willing to explain every detail in their answers and actually create some useful and educational content. – egst Aug 10 '20 at 09:37
  • Try to understand the question, @egst . It's an associative array in a config file problem. I'm really sorry. I don't want to be this rude, but me, who has poor english skill and need more than 3 years to figure out what are class and object is in OOP can get the question. There are many of long explanation in Stackoverflow (another post) which I don't understand their answer – Enkracken Jul 14 '23 at 07:47
15

There are a lot of great answers here - but I found my issue was quite a bit more simple.

I was trying to run the following command:

$x['name']   = $j['name'];

and I was getting this illegal string error on $x['name'] because I hadn't defined the array first. So I put the following line of code in before trying to assign things to $x[]:

$x = array();

and it worked.

Brian Powell
  • 3,336
  • 4
  • 34
  • 60
  • 1
    I think this should be the answer. This must be the different between 5.4 (and the prior to 7) and 7. – sonnb Jan 25 '17 at 17:16
11

A little bit late to the question, but for others who are searching: I got this error by initializing with a wrong value (type):

$varName = '';
$varName["x"] = "test"; // causes: Illegal string offset

The right way is:

 $varName = array();
 $varName["x"] = "test"; // works
Marco
  • 3,470
  • 4
  • 23
  • 35
  • Where $varName is initialised from a value that should be an array but may be an empty string, coercing the value can avoid this, eg: $varName = (array) $shouldBeArray – markdwhite Sep 25 '19 at 04:34
5

As from PHP 5.4 we need to pass the same datatype value that a function expects. For example:

function testimonial($id); // This function expects $id as an integer

When invoking this function, if a string value is provided like this:

$id = $array['id']; // $id is of string type
testimonial($id); // illegal offset warning

This will generate an illegal offset warning because of datatype mismatch. In order to solve this, you can use settype:

$id = settype($array['id'],"integer"); // $id now contains an integer instead of a string
testimonial($id); // now running smoothly
CPHPython
  • 12,379
  • 5
  • 59
  • 71
Anirudh Sood
  • 1,418
  • 12
  • 6
4

Before to check the array, do this:

if(!is_array($memcachedConfig))
     $memcachedConfig = array();
dlopezgonzalez
  • 4,217
  • 5
  • 31
  • 42
1

In my case i change mysql_fetch_assoc to mysql_fetch_array and solve. It takes 3 days to solve :-( and the other versions of my proyect run with fetch assoc.

Pichitron
  • 159
  • 5
1

In my case, I solved it when I changed in function that does sql query after: return json_encode($array) then: return $array

Saurabh Bhandari
  • 2,438
  • 4
  • 26
  • 33
1

It works to me:

Testing Code of mine:

$var2['data'] = array ('a'=>'21','b'=>'32','c'=>'55','d'=>'66','e'=>'77');
foreach($var2 as $result)
{  
    $test = $result['c'];
}
print_r($test);

Output: 55

Check it guys. Thanks

Y. Joy Ch. Singha
  • 3,056
  • 24
  • 26
1

just use

$memcachedConfig = array();

before

 print $memcachedConfig['host'];
 print $memcachedConfig['port'];


 Warning: Illegal string offset 'host' in ....
 Warning: Illegal string offset 'port' in ....

this is because you never define what is $memcachedConfig, so by default are treated by string not arrays..

chayankQ
  • 21
  • 3
1

I solved this problem by using trim() function. the issue was with space.

so lets try

$unit_size = []; //please declare the variable type 
$unit_size = exolode("x", $unit_size);
$width  = trim ($unit_size[1] );
$height = trim ($unit_size[2] );

I hope this will help you.

Jailendra Rajawat
  • 101
  • 1
  • 1
  • 9
1

i think the only reason for this message is because target Array is actually an array like string etc (JSON -> {"host": "127.0.0.1"}) variable

adnan ahmady
  • 770
  • 1
  • 7
  • 12
1

For PHP

//Setup Array like so
$memcachedConfig = array(
  "host" => "127.0.0.1",
  "port" => "11211"
);

//Always a good practice to check if empty

if(isset($memcachedConfig['host']) && isset($memcachedConfig['port'])){

    //Some codes

    print_r ($memcachedConfig['host']);
    print_r ($memcachedConfig['port']);

}

Just make sure to check that the value returning is not empty. So this example was for PHP so find out how to check if an array is empty in other languages.

Delorme Grant
  • 403
  • 5
  • 7
1

In my case: while fetching the database records in making sure to use result_array(); instead of row(); or row_array();

codelone
  • 604
  • 8
  • 17
0

Just incase it helps anyone, I was getting this error because I forgot to unserialize a serialized array. That's definitely something I would check if it applies to your case.

Marc
  • 746
  • 1
  • 12
  • 28
0

It's an old one but in case someone can benefit from this. You will also get this error if your array is empty.

In my case I had:

$buyers_array = array();
$buyers_array = tep_get_buyers_info($this_buyer_id); // returns an array
...
echo $buyers_array['firstname'] . ' ' . $buyers_array['lastname']; 

which I changed to:

$buyers_array = array();
$buyers_array = tep_get_buyers_info($this_buyer_id); // returns an array
...
if(is_array($buyers_array)) {
   echo $buyers_array['firstname'] . ' ' . $buyers_array['lastname']; 
} else {
   echo 'Buyers id ' . $this_buyer_id . ' not found';
}
Valor_
  • 3,461
  • 9
  • 60
  • 109