Почему многомерные массивы заменяют первую букву первого значения ключа? - PullRequest
4 голосов
/ 04 марта 2011

У меня есть многомерный массив, который ведет себя неожиданно, и я хотел бы знать, почему это так, и если есть обходной путь. Кажется, что если я установлю что-то в первом ключе массива, он заменит первую букву этого, когда я объявлю значение во втором ключе. (Я не уверен, как правильно описать поведение, но этот код должен несколько помочь:

<?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'];
?>

Этот код выводится следующим образом:

ПРИВЕТ ТЕСТ: Привет,
ПРИВЕТ ТЕСТ: Джелло Там
ДЖЕРК ТЕСТ: J

Я ожидаю увидеть

ПРИВЕТ ТЕСТ: Привет!
ПРИВЕТ ТЕСТ: Привет!
ДЖЕРК ТЕСТ: ДЖЕРК!

Ответы [ 5 ]

4 голосов
/ 04 марта 2011

Делаем это:

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

Вы заявляете, что $test['hello'] содержит строку.


Затем делаем это:

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

Вы заявляете, что $test['hello'] содержит массив; и больше не строка.


Ваш $test['hello'] может содержать только одну вещь.



На самом деле, когда вы делаете это:

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

Поскольку $test['hello'] содержит строку (а не массив) , я думаю, PHP попытается получить доступ к этой записи: $test['hello'][0]
Если 0 - строка jerk, преобразованная в целое число.

И $test['hello'][0] означает первый символ строки в $test['hello']
См. Доступ к строке и ее модификация с помощью символа в руководстве, об этом.

Теперь вы пытаетесь поместить целую строку ("JERK!"), где может быть только один символ - первый из существующей строки. И тот переопределяется первым символом строки "JERK!".



РЕДАКТИРОВАТЬ через некоторое время: и вот полные пояснения с комментарием кода:

// 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]);
3 голосов
/ 04 марта 2011

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

Символы в строках могут быть доступ и изменение путем указания смещение нуля желаемого символ после строки с помощью квадратные скобки, как в $ str [42] ... нецелые [индексы] конвертируется в целое число ... только первое символ назначенной строки б.

Итак, чтобы ответить на ваш вопрос. $test['hello'] является строкой, поэтому будут применяться правила индексации строк. Следовательно, $test['hello']['jerk'] = "JERK!"; эквивалентно $test['hello'][0] = "J";, потому что интал 'jerk' равен 0, и будет использоваться только первый символ "J" назначенной строки "JERK!".

После, при выводе $test['hello'], вы будете ссылаться на всю строку, в которой первый символ теперь заменен на J. Вывод $test['hello']['jerk'] снова эквивалентен выводу $test['hello'][0], потому что интервал 'jerk' равен 0, а по правилам индексации строк $test['hello'][0] вернет первый символ $test['hello'].

В интерпретации того, что вы хотели сделать, возможно, вы хотели этого.

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

Или иметь что-то многомерное ...

$test['message']['hello'] = "Hello There";
$test['message']['jerk'] = "JERK!";
print_r($test);
// array('message' => array('hello' => "Hello There", 'jerk' => "JERK!"))
3 голосов
/ 04 марта 2011

Потому что это не массив. Это строка.

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

Вы пытаетесь обработать строку, хранящуюся в $test['hello'], как массив. Вы не сможете заставить $test['hello'] содержать как строку («Hello There»), так и другой массив.

1 голос
/ 04 марта 2011

Стоит отметить, что то, что происходит в приведенном примере кода.

Строка может быть доступна как индексный массив. Когда вы пытаетесь установить второй уровень «массива», он фактически выполняет следующее (поскольку первый уровень является строкой):

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

По сути, это дает (или устанавливает) первый символ строки, поскольку приведение в качестве целого числа jerk равно 0. Если ваша строка могла бы привести к другому целому числу, то она возвратила бы (или установила) другой символ строка.

1 голос
/ 04 марта 2011

Вы пытаетесь объявить $test['hello'] как две вещи: строку и массив.Это может быть только один или другой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...