如何强制PHP对数组键使用字符串?

2022-08-30 09:11:23

我遇到过一个使用id来命名类型数组的旧应用程序,例如...

array(1) {
  [280]=>
  string(3) "abc"
}

现在我需要重新排序这些,并且a会使在键是整数时看起来不会发生这种情况。var_dump()

如果我为每个索引添加一个,将在键周围显示双引号,我的猜测显示它现在是一个字符串...avar_dump()

array(1) {
  ["280a"]=>
  string(3) "abc"
}

这样我就可以轻松地对它们进行重新排序,而不必接触更多的代码。

不起作用

$newArray = array();
foreach($array as $key => $value) {
   $newArray[(string) $key] = $value;
}

静止图像将它们显示为整数数组索引。var_dump()

有没有办法强制键是字符串,这样我就可以在不破坏数组的情况下对它们进行重新排序?


答案 1

你不能!!

包含有效整数的字符串将转换为整数类型。例如,密钥“8”实际上将存储在8下。另一方面,“08”不会被强制转换,因为它不是有效的十进制整数。

编辑:

其实你可以!!将顺序数组转换为关联数组

$obj = new stdClass;
foreach($array as $key => $value){
    $obj->{$key} = $value;
}
$array = (array) $obj;

在大多数情况下,以下引用是正确的:

包含有效整数的字符串将转换为整数类型。例如,密钥“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"
}

因此,即使您要创建一个带有编号键的数组,它们也只会被转换回整数。

不幸的是,直到最近我才意识到这一点,但我想我会分享我失败的尝试。

失败的尝试

$arr = array_​change_​key_​case($arr); // worth a try. 

返回一个数组,其中包含数组中所有小写或大写的键。编号索引保持原样

我的下一个尝试是通过将旧值作为新(字符串)键来创建新数组。array_combine

我尝试了几种使数组包含字符串类型的数值的方法。$keys

range("A", "Z" )适用于字母表,所以我会尝试使用数字字符串。

$keys = range("0", (string) count($arr) ); // integers

这导致了一个充满键的数组,但都是int类型。

下面是创建具有 string 类型值的数组的几次成功尝试。

$keys = explode(',', implode(",", array_keys($arr))); // values strings

$keys = array_map('strval', array_keys($arr)); // values strings

现在只是将两者结合起来。

$arr = array_combine( $keys, $arr); 

这是我发现数字字符串被转换为整数的时候。

$arr = array_combine( $keys, $arr); // int strings
//assert($arr === array_values($arr)) // true. 

将键更改为字符串并维护其文本值的唯一方法是在键前面加上一个小数点或 。"00","01","02""0.","1.","2."

你可以像这样实现这个目标。

$keys = explode(',', implode(".,", array_keys($arr)) . '.'); // added decimal point 
$arr = array_combine($keys, $arr);

当然,这并不理想,因为您需要像这样定位数组元素。

$arr["280."]   

我创建了一个小函数,即使您只输入整数而不是新字符串,它也将针对正确的数组元素。

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"

编辑:

其实你可以!!将顺序数组转换为关联数组

所有这一切都是徒劳的


答案 2

可以将空字符追加到数组键的末尾。这使得PHP无法将字符串解释为整数。所有的数组函数(如)都在上面工作。在整数字符串之后甚至不会显示任何额外的内容。"\0"array_merge()var_dump()

例:

$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"

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"]

这种方法的唯一缺点是,例如,要访问它,您实际上必须通过访问它,并且由于甚至不会显示末尾有一个空字符,因此没有关于为什么您获得“未定义偏移量”的线索。因此,仅当通过迭代或最终维护您的代码的人会讨厌您时,才使用此黑客。$numbers["444"]$numbers["444\0"]var_dump()foreach()