2015-11-13 2 views
15

Я столкнулся с чем-то странным.Элемент массива доступа, индексированный с помощью числовой строки

У меня есть php-массив, индексированный цифровыми клавишами. Однако невозможно получить доступ к любому из элементов, поскольку php автоматически обрабатывает числовые строки как целые числа, вызывая недопустимое уведомление о смещении.

В нормальных условиях его невозможно создать массив php с числовыми индексами строк, но это может произойти с типом casting.

Для воспроизведения:

$object = new stdClass(); 
$object->{'1'} = 'one'; 

$array = (array) $object; 

var_dump($array); 
/* produces 
array(1) { 
    ["1"]=> 
    string(3) "one" 
} 
*/ 

//none of the following will work 
$key = '1'; 
echo $array[1], $array['1'], $array["1"], $array[(string)1], $array[$key]; 

Является ли это просто случай ошибка края? Я только столкнулся с проблемой при попытке улучшить свой ответ на another SO question

Живой пример кода: http://codepad.viper-7.com/dFSlH1

+0

Я думаю, что это происходит, когда вы конвертируете из объекта в массив. Потому что он работает нормально, если это ассоциативный массив. Пример: http://codepad.viper-7.com/wskYI9 –

+0

также, если вы используете довольно беспорядочный 'json_decode (json_encode ($ object), true)' подход, эта проблема не происходит – Dale

+2

Некоторая информация здесь http: //php.net/manual/en/language.types.array.php#language.types.array.casting – danjam

ответ

11

Невероятно, но это нормальное поведение в PHP, он рассматривается как ошибка (link) в 2008 году

Но они указывали на manual для броска с (array):

Если объект преобразуется в массив, результатом является массив, элементами которого являются элементы . Ключами являются переменная-член наименования, за некоторыми заметными исключениями: целые свойства: недоступно;

Вы можете использовать get_object_vars() вместо:

$object = new stdClass(); 
$object->{'1'} = 'one'; 

$array = get_object_vars($object); 

$key = '1'; 
echo $array[1]."<br>"; 
echo $array['1']."<br>"; 
echo $array["1"]."<br>"; 
echo $array[(string)1]."<br>"; 
echo $array[$key]."<br>"; 

Не объясняет, почему это происходит, но это решение, чтобы избежать проблемы произнесения.

Не в теме, но я подумал, может быть, это интересно. Найдено в manual.

Чтобы избежать подобных проблем, всегда используйте целое число или строку в качестве индекса, не смешивайте его и не используйте целые числа в строке.

Пример смешанного массива:

$array = array(
    1 => "a", 
    "1" => "b",//overrides 1 
    1.5 => "c",//overrides "1" 
    true => "d",//overrides 1.5 
); 

var_dump($array); 
5

Вы можете использовать

$vars = get_object_vars($object); 
echo $vars[1]; 
+1

oh great, вы были быстрее меня :) – swidmann

2

ключи строк, содержащих действительные целочисленные значения будут ввергнуты в целочисленных ключей автоматически в «нормальном» создании массива - но это, кажется, литье из объекта в массив не применяется та же логика.

Это может быть исправлено, однако, с помощью

$array = array_combine(array_keys($array), array_values($array)); 

после строки, которая создает массив из объекта.http://codepad.viper-7.com/v5rGJa


Хотя, такие же, как Дэйв уже сказал в своем комментарии, используя get_object_vars выглядит как «чистые» решения для меня, как хорошо.

1
foreach ($array as $key => $value){ 
    var_dump($key); 
    var_dump($value); 
} 

показывает

string(1) "1" 
string(3) "one" 

Но echo $array['"1"']; дает

E_NOTICE : type 8 -- Undefined index: "1" -- at line 8 

Это странно!

Смежные вопросы