Числовая строка в виде массива в PHP

Можно ли использовать цифровую строку типа "123" в качестве ключа в массиве PHP без преобразования в целое число?

 $blah = array('123' => 1); var_dump($blah); 

печать

 array(1) { [123]=> int(1) } 

я хочу

 array(1) { ["123"]=> int(1) } 

Нет; нет, это не так:

Из руководства :

Ключ может быть целым числом или строкой. Если ключ является стандартным представлением целого числа, он будет интерпретироваться как таковой (т.е. «8» будет интерпретирован как 8, а «08» будет интерпретирован как «08»).

добавление

Из-за комментариев ниже я подумал, что было бы интересно указать, что поведение похоже, но не идентично объектным ключам JavaScript.

 foo = { '10' : 'bar' }; foo['10']; // "bar" foo[10]; // "bar" foo[012]; // "bar" foo['012']; // undefined! 

Да, это возможно с помощью массива-литья объекта stdClass :

 $data = new stdClass; $data->{"12"} = 37; $data = (array) $data; var_dump( $data ); 

Это дает вам (вплоть до версии PHP 7.1):

 array(1) { ["12"]=> int(37) } 

(Обновление: мой первоначальный ответ показал более сложный способ, используя json_decode() и json_encode() что необязательно.)

Обратите внимание на комментарий : К сожалению, невозможно напрямую ссылаться на значение: $data['12'] приведет к уведомлению.

Обновление :
Из PHP 7.2 на нем также можно использовать числовую строку в качестве ключа для ссылки на значение:

 var_dump( $data['12'] ); // int 32 

Если вам нужно использовать числовой ключ в структуре данных php, объект будет работать. И объекты сохраняют порядок, поэтому вы можете выполнять итерацию.

 $obj = new stdClass(); $key = '3'; $obj->$key = 'abc'; 

Мое обходное решение:

 $id = 55; $array = array( " $id" => $value ); 

Пробел char (preend) является хорошим решением, поскольку сохраняет преобразование int:

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

Вы увидите 55 как int.

Вы можете придать ключевому слову строку, но в конечном итоге она будет преобразована в целое число из-за неправильной настройки PHP. Посмотреть на себя:

 $x=array((string)123=>'abc'); var_dump($x); $x[123]='def'; var_dump($x); 

Из руководства по PHP:

Ключ может быть целым числом или строкой. Если ключ является стандартным представлением целого числа, он будет интерпретироваться как таковой (т.е. «8» будет интерпретирован как 8, а «08» будет интерпретирован как «08»). Поплавки в ключе усекаются до целого. Индексированные и ассоциативные типы массивов являются одним и тем же типом в PHP, которые могут содержать как целые, так и строковые индексы.

Строки, содержащие действительные целые числа, будут переданы в целочисленный тип. Например, ключ «8» будет фактически сохранен под 8. С другой стороны, «08» не будет выбрано, так как это не допустимое целое число.

НЕПРАВИЛЬНО

У меня есть функция кастинга, которая обрабатывает последовательный процесс ассоциативного массива,

 $array_assoc = cast($arr,'array_assoc'); $array_sequential = cast($arr,'array_sequential'); $obj = cast($arr,'object'); $json = cast($arr,'json'); function cast($var, $type){ $orig_type = gettype($var); if($orig_type == 'string'){ if($type == 'object'){ $temp = json_decode($var); } else if($type == 'array'){ $temp = json_decode($var, true); } if(isset($temp) && json_last_error() == JSON_ERROR_NONE){ return $temp; } } if(@settype($var, $type)){ return $var; } switch( $orig_type ) { case 'array' : if($type == 'array_assoc'){ $obj = new stdClass; foreach($var as $key => $value){ $obj->{$key} = $value; } return (array) $obj; } else if($type == 'array_sequential'){ return array_values($var); } else if($type == 'json'){ return json_encode($var); } break; } return null; // or trigger_error } 

Я столкнулся с этой проблемой в массиве с ключами «0» и «». Это означало, что я не мог проверить ключи массива с помощью == или ===.

 $array=array(''=>'empty', '0'=>'zero', '1'=>'one'); echo "Test 1\n"; foreach ($array as $key=>$value) { if ($key == '') { // Error - wrongly finds '0' as well echo "$value\n"; } } echo "Test 2\n"; foreach ($array as $key=>$value) { if ($key === '0') { // Error - doesn't find '0' echo "$value\n"; } } 

Обходной путь заключается в том, чтобы использовать ключи массива обратно в строки перед использованием.

 echo "Test 3\n"; foreach ($array as $key=>$value) { if ((string)$key == '') { // Cast back to string - fixes problem echo "$value\n"; } } echo "Test 4\n"; foreach ($array as $key=>$value) { if ((string)$key === '0') { // Cast back to string - fixes problem echo "$value\n"; } } 

У меня возникла проблема с объединением массивов, в которых были как строковые, так и целые ключи. Было важно, чтобы целые числа также обрабатывались как строка, поскольку они были именами для полей ввода (как в размерах обуви и т. Д.).

Когда я использовал $data = array_merge($data, $extra); PHP будет «переупорядочивать» ключи. В попытке сделать заказ, целые ключи (я пробовал с 6'6'"6" даже (string)"6" качестве ключей) получил переименован из 0 в n … Если вы думаете об этом, в большинстве случаев это было бы желательным поведением.

Вы можете обойти это, используя $data = $data + $extra; вместо. Довольно прямо, но я не думал об этом сначала ^^.

Что касается решения @david, обратите внимание, что при попытке доступа к строковым значениям в ассоциативном массиве номера не будут работать. Я предполагаю, что они отлиты целыми числами за кулисами (при доступе к массиву), и никакое значение не найдено. Доступ к значениям в виде целых чисел также не будет работать. Но вы можете использовать array_shift () для получения значений или итерации массива.

 $data = new stdClass; $data->{"0"} = "Zero"; $data->{"1"} = "One"; $data->{"A"} = "A"; $data->{"B"} = "B"; $data = (array)$data; var_dump($data); /* Note the key "0" is correctly saved as a string: array(3) { ["0"]=> string(4) "Zero" ["A"]=> string(1) "A" ["B"]=> string(1) "B" } */ //Now let's access the associative array via the values //given from var_dump() above: var_dump($data["0"]); // NULL -> Expected string(1) "0" var_dump($data[0]); // NULL (as expected) var_dump($data["1"]); // NULL -> Expected string(1) "1" var_dump($data[1]); // NULL (as expected) var_dump($data["A"]); // string(1) "A" (as expected) var_dump($data["B"]); // string(1) "B" (as expected) 

У меня была эта проблема, пытаясь отсортировать массив, в котором мне нужен ключ сортировки, который будет шестнадцатеричным sha1. Когда полученное значение sha1 не имеет букв, PHP превращает ключ в целое. Но мне нужно было отсортировать массив по относительному порядку строк. Поэтому мне нужно было найти способ заставить ключ быть строкой, не меняя порядок сортировки.

Глядя на диаграмму ASCII ( https://en.wikipedia.org/wiki/ASCII ), восклицательный знак сортируется примерно так же, как и пространство, и, конечно же, меньше, чем все числа и буквы.

Поэтому я добавил восклицательный знак в конце ключевой строки.

 for(...) { $database[$sha.'!'] = array($sha,$name,$age); } ksort($database); $row = reset($database); $topsha = $row[0];