我如何强制PHP使用数组键的string?
我遇到了一个旧的应用程序,使用一个ID来命名types的数组,例如…
array(1) { [280]=> string(3) "abc" }
现在我需要对这些进行重新sorting,而var_dump()
会使它看起来在按键是整数时不会发生。
如果我添加a
到每个索引, var_dump()
将显示关键的双引号,我的猜测显示它现在是一个string…
array(1) { ["280a"]=> string(3) "abc" }
这可以让我轻松地重新排列它们,而不必触摸更多的代码。
这不起作用。
$newArray = array(); foreach($array as $key => $value) { $newArray[(string) $key] = $value; }
一个var_dump()
仍然将它们显示为整型数组索引。
有没有办法强制键是string,所以我可以重新sorting而不损坏数组?
编辑 :
我认为,如果他们是整数,我不能重新sorting他们没有改变的关键(在这个例子中是重要的)。 但是,如果它们是string,我可以将它们重新sorting,因为索引不应被解释为具有任何特殊含义。 无论如何,看我的问题更新我是如何做到的(我走了一条不同的路线)。
其实他们不必以数字顺序…
array(208=>'a', 0=> 'b', 99=>'c');
如果你手动分配它们是完全有效的。 虽然我同意整数键可能被错误地解释为具有某人的连续含义,尽pipe你会认为如果他们是在一个非数字的顺序,这将是显而易见的,他们werent。 这就是说,我认为既然你有更新的代码的余地,你更新,这是更好的方法。
可能不是最有效的方法,但很容易:
$keys = array_keys($data); $values = array_values($data); $stringKeys = array_map('strval', $keys); $data = array_combine($stringKeys, $values); //sort your data
这个怎么样?
$newArray = array(); foreach($oldArray as $key => $value) { $newArray[$key.''] = $value; }
编辑:也尝试过,是的,它没有工作。
从PHP文档 :
一个键可以是一个整数或一个string。 如果一个键是一个整数的标准表示,它将被解释为这样(即“8”将被解释为8,而“08”将被解释为“08”)。 浮点键被截断为整数。 PHP中没有不同的索引和关联数组types; 只有一个数组types,可以包含整数和string索引。
我想现在取决于你如何sorting数组。 (最终输出?)
使用一个对象而不是一个数组$object = (object)$array;
我可以通过在每个键的末尾添加'.0'来实现这个function,例如:
$options = []; for ($i = 1; $i <= 4; $i++) { $options[$i.'.0'] = $i; }
将返回:
array("1.0" => 1, "2.0" => 2, "3.0" => 3, "4.0" => 4)
它可能不是完全最优的,但是它允许你对数组进行sorting并提取(等同于)原始密钥,而不必截断任何东西。
您可以将空字符"\0"
追加到数组键的末尾。 这使得PHP不能将string解释为一个整数。 所有的数组函数(如array_merge()
)都可以工作。 甚至连var_dump()
都不会在整数string后面显示任何内容。
例:
$numbers1 = array(); $numbers2 = array(); $numbers = array(); $pool1 = array(111, 222, 333, 444); $pool2 = array(555, 666, 777, 888); foreach($pool1 as $p1) { $numbers1[$p1 . "\0"] = $p1; } foreach($pool2 as $p2) { $numbers2[$p2 . "\0"] = $p2; } $numbers = array_merge($numbers1, $numbers2); var_dump($numbers);
结果输出将是:
array(8) { ["111"] => string(3) "111" ["222"] => string(3) "222" ["333"] => string(3) "333" ["444"] => string(3) "444" ["555"] => string(3) "555" ["666"] => string(3) "666" ["777"] => string(3) "777" ["888"] => string(3) "888" }
没有了. "\0"
. "\0"
部分结果数组将是:
array(8) { [0] => string(3) "111" [1] => string(3) "222" [2] => string(3) "333" [3] => string(3) "444" [4] => string(3) "555" [5] => string(3) "666" [6] => string(3) "777" [7] => string(3) "888" }
此外, ksort()
也将忽略空字符,这意味着$numbers[111]
和$numbers["111\0"]
在sortingalgorithm中都具有相同的权重。
这个方法唯一的缺点是要访问,例如$numbers["444"]
,你实际上必须通过$numbers["444\0"]
访问它,因为即使var_dump()
也不会显示空字符在结尾处,没有线索为什么你会得到“未定义的偏移量”。 因此,如果通过foreach()
迭代,或者最终维护代码将会憎恨你,那么只能使用这个hack。
你不能!
包含有效整数的string将被转换为整数types。 例如,键“8”实际上将被存储在8以下。另一方面,“08”不会被投射,因为它不是有效的十进制整数。
编辑:
实际上你可以! 将连续数组转换为关联数组
$obj = new stdClass; foreach($array as $key => $value){ $obj->{$key} = $value; } $array = (array) $obj;
在大多数情况下,以下引用是真的。
包含有效整数的string将被转换为整数types。 例如,键“8”实际上将被存储在8以下。另一方面,“08”不会被投射,因为它不是有效的十进制整数。
这个例子来自PHP文档
<?php $array = array( 1 => "a", "1" => "b", 1.5 => "c", true => "d", ); var_dump($array); ?>
上面的例子会输出:
array(1) { [1]=> string(1) "d" }
所以,即使你要用数字键创build一个数组,他们也只会被转换成整数。
对我来说不幸的是,直到最近我还没有意识到这一点,但我仍然会分享我失败的尝试。
失败的尝试
$arr = array_change_key_case($arr); // worth a try.
返回数组中小写或大写数组中所有键的数组。 编号指数保持不变 。
我接下来的尝试是通过array_combine
旧的值新的(string)键来创build一个新的数组。
我尝试了几种使$keys
数组包含stringtypes的数值的方法。
range("A", "Z" )
适用于字母表,所以我虽然我会尝试用数字string。
$keys = range("0", (string) count($arr) ); // integers
这导致了一个数组完整的键,但都是inttypes。
这里有几个成功的尝试,创build一个数组的stringtypes的值。
$keys = explode(',', implode(",", array_keys($arr))); // values strings $keys = array_map('strval', array_keys($arr)); // values strings
现在只是将两者结合起来。
$arr = array_combine( $keys, $arr);
这是当我发现数字string被转换为整数。
$arr = array_combine( $keys, $arr); // int strings //assert($arr === array_values($arr)) // true.
将密钥更改为string并保持它们的字面值的唯一方法是在密钥前加一个带有小数点"00","01","02"
或"0.","1.","2."
的后缀"0.","1.","2."
。
你可以这样做。
$keys = explode(',', implode(".,", array_keys($arr)) . '.'); // added decimal point $arr = array_combine($keys, $arr);
当然,这是不太理想的,因为你将需要像这样的目标数组元素。
$arr["280."]
我已经创build了一个小函数,即使您只input整数而不是新string,它也会将正确的数组元素作为目标。
function array_value($array, $key){ if(array_key_exists($key, $array)){ return $array[ $key ]; } if(is_numeric($key) && array_key_exists('.' . $key, $array)){ return $array[ '.' . $key ]; } return null; }
用法
echo array_value($array, "208"); // "abc"
编辑:
实际上你可以! 将连续数组转换为关联数组
所有这一切都没有
编辑:这应该工作
foreach($array as $key => $value) { $newkey = sprintf('%s',$key); $newArray["'$newkey'"] = $value; }