PHP中作为数组键的数字字符串
是否可以使用像PHP中作为数组键的数字字符串,php,Php,是否可以使用像“123”这样的数字字符串作为PHP数组中的键,而不将其转换为整数 $blah = array('123' => 1); var_dump($blah); 印刷品 array(1) { [123]=> int(1) } 我想要 array(1) { ["123"]=> int(1) } 您可以将键类型转换为字符串,但由于PHP的松散键入,它最终将转换为整数。你自己看看: $x=array((string)123=>'abc'); var
“123”
这样的数字字符串作为PHP数组中的键,而不将其转换为整数
$blah = array('123' => 1);
var_dump($blah);
印刷品
array(1) {
[123]=>
int(1)
}
我想要
array(1) {
["123"]=>
int(1)
}
您可以将键类型转换为字符串,但由于PHP的松散键入,它最终将转换为整数。你自己看看:
$x=array((string)123=>'abc');
var_dump($x);
$x[123]='def';
var_dump($x);
从PHP手册:
键可以是整数或字符串。如果钥匙是标准的
表示一个整数,它将被解释为(即。
“8”将解释为8,“08”将解释为“08”)。
键中的浮点被截断为整数。索引和关联
数组类型在PHP中是相同的类型,两者都可以包含整数
和字符串索引
没有;不,不是:
发件人:
键可以是整数或字符串。如果一个键是一个整数的标准表示形式,它将被解释为这样(即,“8”将被解释为8,而“08”将被解释为“08”)
附录
由于下面的评论,我认为指出这种行为与JavaScript对象键类似但不完全相同会很有趣
foo = { '10' : 'bar' };
foo['10']; // "bar"
foo[10]; // "bar"
foo[012]; // "bar"
foo['012']; // undefined!
如果您需要在php数据结构中使用数字键,那么对象将起作用。对象保持顺序,因此可以进行迭代
$obj = new stdClass();
$key = '3';
$obj->$key = 'abc';
我在同时使用“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";
}
}
我的解决办法是:
$id = 55;
$array = array(
" $id" => $value
);
空格字符(prepend)是一个很好的解决方案,因为保持int转换:
foreach( $array as $key => $value ) {
echo $key;
}
您将看到55为int。我在合并同时具有字符串键和整数键的数组时遇到问题。整数也应作为字符串处理,这一点很重要,因为它们是输入字段的名称(如鞋码等) 当我使用
$data=array\u merge($data,$extra)时代码>PHP将“重新排序”键。在尝试进行排序时,整数键(我尝试使用6
-'6'
-“6”
甚至(string)“6”
作为键)从0重命名为n
。。。如果你仔细想想,在大多数情况下,这是你想要的行为
您可以使用$data=$data+$extra代码>取而代之。
非常直截了当,但一开始我没有想到^。我在尝试对数组排序时遇到了这个问题,我需要排序键为十六进制sha1。当得到的sha1值没有字母时,PHP将键转换为整数。但是我需要根据字符串的相对顺序对数组进行排序。因此,我需要找到一种方法,在不改变排序顺序的情况下强制键为字符串
看看ASCII图表(),感叹号排序与空格差不多,当然比所有数字和字母都低
因此,我在键字符串的末尾附加了一个感叹号
for(...) {
$database[$sha.'!'] = array($sha,$name,$age);
}
ksort($database);
$row = reset($database);
$topsha = $row[0];
是的,可以通过数组强制转换stdClass
对象:
$data = new stdClass;
$data->{"12"} = 37;
$data = (array) $data;
var_dump( $data );
这将为您提供(PHP 7.1版之前的版本):
(更新:我最初的答案显示了一种更复杂的方式,使用了json\u decode()
和json\u encode()
,这是不必要的。)
请注意注释:很遗憾,无法直接引用该值:$data['12']
将产生通知
更新:
从PHP 7.2开始,还可以使用数字字符串作为键来引用值:
var_dump( $data['12'] ); // int 32
包含有效整数的字符串将强制转换为整数类型。例如,键“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
}
关于@david solution,请注意,当您尝试访问关联数组中的字符串值时,数字将不起作用。我的猜测是,它们在幕后(访问数组时)被强制转换为整数,并且找不到任何值。以整数形式访问这些值也不起作用。但是您可以使用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)
作为解决方法,您可以使用json_FORCE_object选项将PHP数组编码为json对象
i、 例如,这个例子:
$a = array('foo','bar','baz');
echo "RESULT: ", json_encode($a, JSON_FORCE_OBJECT);
将导致:
RESULT: {"0" : "foo", "1": "bar", "2" : "baz"}
由于PHP是松散类型的,“123”
=123
几乎适用于所有用途。你想要它作为一个字符串的原因是什么(有一个int是不好的)?我想到的原因与数组函数有关,比如array\u merge
如果输入数组具有相同的字符串键,则该键的后一个值将覆盖前一个值。但是,如果数组包含数字键,则后面的值将不会覆盖原始值,而是追加。作为数组键的数字字符串存在问题的另一个例子是:另一个用例的可能重复:单元测试JSON数据转换。将这样的数组转换为JSON并返回不会让您断言原始数组和结果完全相同;php确定字符串是否为数字,然后对其进行转换。那么你是说这是不可能的吗?显示有一种方法可以使用看起来像整数的字符串作为数组中的键。问题出在PHP解释器上。甚至不可能想象有一种混合字符串和整数作为数组键的语言。最好的解决方案是什么?正如Undolog提出的,最好的解决方案是使用尾随空格。。。不幸的是,@sentenza:这是可以想象的,特别是因为PHP允许字符串和整数混合作为数组的键:[42=>'answer','snafu'=>'fubar']
@LS-yes。我知道PHP允许你这样做,但是如果你在一个假设的泛型类型系统中考虑关键字,它将不匹配任何包含字符串A的混合类型。
RESULT: {"0" : "foo", "1": "bar", "2" : "baz"}