Можно ли использовать цифровую строку типа "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];