我如何强制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; }