3

The easiest way for me to explain this is to show an example ... Here's a replication of the problem code:

<?php
 $test=array();
 $test['one']='hello';
 if(isset($test['one']['two'][0])) {
 echo 'Apparently it is set ...';
 echo $test['one']['two'][0];
 }
?>

This returns as:

Apparently it is set ...

Warning: Illegal string offset 'two' in C:\test.php on line 6

h

Is this because there are mixed key types? It's just a little anomaly I came across and was wondering if someone could shed some light on it ...

asked Nov 28, 2014 at 4:06
1
  • This behaviour changed in 5.4, 3v4l results. Commented Nov 28, 2014 at 4:22

3 Answers 3

4

The reason is that, when you dereference a string, it will return a string comprising a single character (assuming the index doesn't exceed the length); the resulting string can be dereferenced again (starting from 5.4 onwards).

For example - link:

$s = 'hello';
$s[0]; // "h"
$s[0][0]; // "h"
// etc. etc.

Illegal indices such as 'two' will cause a notice but it's treated as index 0, except when used inside isset().

Another example:

$s[0][1]; // ""
$s[0][1][0]; // notice: uninitialised string offset: 0

If you don't know beforehand whether a string or array is passed and this is important to you, additional type checks need to take place in between each path.

answered Nov 28, 2014 at 4:27
Sign up to request clarification or add additional context in comments.

4 Comments

Now that makes sense. But isn't the older one the correct expected result?
@bansi What do you mean by "the older one"? You mean prior to 5.4? I've added a link that shows the two behaviours; you're free to make up your own mind which makes more sense, but personally I would say that the current behaviour is more logical.
in my point of view $test['one']['two'][0] is never set so it should return false instead of true. and in your example $s[0] = h is correct, but $s[0][0] should throw warning. This is just my personal view.
@bansi I would agree that an illegal index should yield null when applied to a string.
0

You should check your all your array keys exist before you try and use them, i.e. all the way up the chain. isset() accepts multiple parameters so you don't need to keep rewriting it and can keep DRY principles going a little more:

$test = array();
$test['one'] = 'hello';
if (isset($test['one'], $test['one']['two'], $test['one']['two'][0])) {
 echo 'Apparently it is set ...';
 echo $test['one']['two'][0];
}
answered Nov 28, 2014 at 4:08

3 Comments

Scratch that, no it doesnt :D
But, why does my first example think that the key exists? It only happens when using the [0] key. if I replace the [0] with a string (['string']) it doesnt throw the error
@Stretch it's pass in isset cause it's checking $test['one'] and found true so goes in
-1

isset returns odd and unexpected results when you pass it a string instead of an array.

It is good practice to pair an an is_array check with an isset check.

answered Nov 28, 2014 at 4:16

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.