开发者

Why do Multidimentional Arrays replace the first letter of the first key value?

I have a multidimensional array that is behaving unexpectedly and I would like to know why this is, and if there is a work around. It seems that if I set something in first key of the array, it will replace the first letter of it when I declare a value in it's second key. (I'm not sure how to properly describe the behavior but this code should help somewhat:

<?php
//Declare Array with first key and value
    $test['hello'] = "Hello There";

//Echo Value
    echo "HELLO TEST: ". $test['hello'] ;

//Declare Multidimensional Array using the first array key and a new key
    $test['hello']['jerk'] = "JERK!";

//Echo Values
    echo "<br/>HELLO TEST: ". $test['hello'] ;
    echo "<br/>JERK TEST : ". $test['hello']['jerk'];
?>

That code outputs as follows:

HELLO TEST: Hello There

HELLO TEST: Jello There

JERK TEST : J

I expect to see

HELLO TEST: Hello There

HEL开发者_如何学CLO TEST: Hello There

JERK TEST : JERK!


Doing this :

$test['hello'] = "Hello There";

You declare that $test['hello'] contains a string.


Then, doing this :

$test['hello']['jerk'] = "JERK!";

You declare that $test['hello'] contains an array ; and no longer a string.


Your $test['hello'] can only contain one thing.



Actually, when you are doing this :

$test['hello']['jerk'] = "JERK!";

As $test['hello'] contains a string (and not an array), I think PHP will try to access this entry : $test['hello'][0]
With 0 being the jerk string converted to an integer.

And $test['hello'][0] means the first character of the string that's in $test['hello']
See String access and modification by character in the manual, about that.

There, now, you're trying to put a whole string ("JERK!") where there can be only one character -- the first one of the existing string. And that one get overriden by the first character of the string "JERK!".



EDIT a while after : and here are the full explanations, with commented code :

// Assign a string to $test['hello']
$test['hello'] = "Hello There";

//Echo Value
var_dump($test['hello']);

// Try to assign a string to $test['hello']['jerk']
$test['hello']['jerk'] = "JERK!";
// But $test['hello'] is a string, so PHP tries to make a string-access to one character
// see http://fr.php.net/manual/en/language.types.string.php#language.types.string.substr
// As 'jerk' is a string, it gets converted to an integer ; which is 0
// So, you're really trying to do this, here :
$test['hello'][0] = "JERK!";
// And, as you can only put ONE character where ($test['hello'][0]) there is space for only one ,
// only the first character of "JERK!" is kept.
// Which means that what's actually done is :
$test['hello'][0] = "J";

// Still echo the whole string, with the first character that's been overriden
var_dump($test['hello']);

// Same as before : here, you're only accessing $test['hello'][0]
// (which is the first character of the string -- the one that's been overriden)
var_dump($test['hello']['jerk']);
// Same as this :
var_dump($test['hello'][0]);


Because it isn't an array. It's a string.

$test['hello'] = array();
$test['hello']['jerk'] = "JERK!"

You're trying to treat the string stored in $test['hello'] as an array. You're not going to be able to make $test['hello'] hold both a string ("Hello There") and another array.


From http://ca2.php.net/language.types.string.

Characters within strings may be accessed and modified by specifying the zero-based offset of the desired character after the string using square array brackets, as in $str[42]... Non-integer [indexes] are converted to integer... only the first character of an assigned string is used.

So, to answer your question. $test['hello'] is a string, so the rules of indexing strings will apply. Therefore, $test['hello']['jerk'] = "JERK!"; is equivalent to $test['hello'][0] = "J"; because the intval of 'jerk' is 0 and only the first character "J" of the assigned string "JERK!" will be used.

After, when echoing $test['hello'], you will be referring to the whole string, which now has its first character replaced by a J. Echoing $test['hello']['jerk'] is again equivalent to echoing $test['hello'][0] because the intval of 'jerk' is 0, and by the rules of indexing strings, $test['hello'][0] will return the first character of $test['hello'].

In interpretation of what you meant to do, perhaps you wanted this.

$test['hello'] = "Hello There";
$test['jerk'] = "JERK!";
print_r($test); // array('hello' => "Hello There", 'jerk' => "JERK!")

Or, to have something multidimensional...

$test['message']['hello'] = "Hello There";
$test['message']['jerk'] = "JERK!";
print_r($test);
// array('message' => array('hello' => "Hello There", 'jerk' => "JERK!"))


You are trying to declare $test['hello'] as two things: a string and an array. It can only be one or the other.


It is worth pointing out that what is happening in the code example given.

A string can be accessed like an index-based array. When you attempt to set the second level of the "array" what it is actually doing is this (since the first level is a string):

$array['levelOne'] = 'Hello.';
$array['levelOne'][(int)'jerk'];

Basically this gives (or sets) the first character of the string since 'jerk' cast as an integer is 0. If your string could have cast to a different integer then it would have returned (or set) a different character of the string.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜