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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3445953/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 09:47:45  来源:igfitidea点击:

How can I force PHP to use strings for array keys?

phparrays

提问by alex

I've come across an old app that uses an id to name type array, for example...

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

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

Now I need to reorder these, and a var_dump()would make it appear that that isn't going to happen while the keys are integers.

现在我需要对这些重新排序,并且 avar_dump()会使其看起来在键是整数时不会发生。

If I add an ato every index, var_dump()will show double quotes around the key, my guess to show it is now a string...

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

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

This would let me easily reorder them, without having to touch more code.

这将让我轻松地重新排序它们,而无需接触更多代码。

This does not work.

这并不起作用

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

A var_dump()still shows them as integer array indexes.

Avar_dump()仍然将它们显示为整数数组索引。

Is there a way to force the keys to be strings, so I can reorder them without ruining the array?

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

采纳答案by prodigitalson

EDIT:

编辑

I assumed that if they are integers, I can't reorder them without changing the key (which is significant in this example). However, if they were strings, I can reorder them how they like as the index shouldn't be interpreted to have any special meaning. Anyway, see my question update for how I did it (I went down a different route).

我假设如果它们是整数,我不能在不更改键的情况下对它们重新排序(这在本例中很重要)。但是,如果它们是字符串,我可以将它们重新排序,因为索引不应被解释为具有任何特殊含义。无论如何,请参阅我的问题更新以了解我是如何做到的(我走了不同的路线)。

Actually they dont have to be in numeric order...

实际上它们不必按数字顺序...

array(208=>'a', 0=> 'b', 99=>'c');

Is perfectly valid if youre assigning them manually. Though i agree the integer keys might be misinterpreted as having a sequential meaning by someone although you would think if they were in a non-numeric order it would be evident they werent. That said i think since you had the leeway to change the code as you updated that is the better approach.

如果您手动分配它们,则完全有效。尽管我同意整数键可能会被某人误解为具有顺序含义,尽管您会认为如果它们按非数字顺序排列,很明显它们不是。也就是说,我认为因为您在更新时有更改代码的余地,这是更好的方法。



Probably not the most efficient way but easy as pie:

可能不是最有效的方法,但很简单:

$keys = array_keys($data);

$values = array_values($data);
$stringKeys = array_map('strval', $keys);

$data = array_combine($stringKeys, $values);

//sort your data

回答by TarranJones

YOU CAN'T!!

你不能!!

Strings containing valid integers will be cast to the integer type. E.g. the key "8" will actually be stored under 8. On the other hand "08" will not be cast, as it isn't a valid decimal integer.

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

Edit:

编辑:

ACTUALLY YOU CAN!!Cast sequential array to associative array

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

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

In most cases, the following quote is true:

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

Strings containing valid integers will be cast to the integer type. E.g. the key "8" will actually be stored under 8. On the other hand "08" will not be cast, as it isn't a valid decimal integer.

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

This examples from the PHP Docs

这个例子来自 PHP Docs

 <?php
    $array = array(
        1    => "a",
        "1"  => "b",
        1.5  => "c",
        true => "d",
    );
    var_dump($array);
?>

The above example will output:

上面的例子将输出:

array(1) {
  [1]=> string(1) "d"
}

So even if you were to create an array with numbered keys they would just get casted back to integers.

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

Unfortunately for me I was not aware of this until recently but I thought I would share my failed attempts.

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

Failed attempts

失败的尝试

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

Returns an array with all keys from array lowercased or uppercased. Numbered indices are left as is.

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

My next attempts was to create a new array by array_combineing the old values the new (string)keys.

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

I tried several ways of making the $keysarray contain numeric values of type string.

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

range("A", "Z" )works for the alphabet so I though I would try it with a numeric string.

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

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

This resulted in an array full of keys but were all of int type.

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

Here's a couple of successful attempts of creating an array with the values of type string.

下面是使用字符串类型的值创建数组的几次成功尝试。

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

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

Now just to combine the two.

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

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

This is when I discovered numeric strings are casted to integers.

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

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

The only way to change the keys to strings and maintain their literal values would be to prefix the key with a suffix it with a decimal point "00","01","02"or "0.","1.","2.".

将键更改为字符串并保持其文字值的唯一方法是在键前加上后缀,后缀为小数点"00","01","02""0.","1.","2.".

You can achieve this like so.

你可以这样实现。

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

Of course this is less than ideal as you will need to target array elements like this.

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

$arr["280."]   

I've created a little function which will target the correct array element even if you only enter the integer and not the new 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;
}

Usage

用法

echo array_value($array, "208"); // "abc"

Edit:

编辑:

ACTUALLY YOU CAN!!Cast sequential array to associative array

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

All that for nothing

这一切都是白费

回答by Paul-Emile MINY

Use an object instead of an array $object = (object)$array;

使用对象而不是数组 $object = (object)$array;

回答by Tim Aagaard

You can append the null character "\0"to the end of the array key. This makes it so PHP can't interpret the string as an integer. All of the array functions (like array_merge()) work on it. Also not even var_dump()will show anything extra after the string of integers.

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

Example:

例子:

$numbers1 = array();
$numbers2 = array();
$numbers = array();

$pool1 = array(111, 222, 333, 444);
$pool2 = array(555, 666, 777, 888);

foreach($pool1 as $p1)
{
    $numbers1[$p1 . "
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"
}
"] = $p1; } foreach($pool2 as $p2) { $numbers2[$p2 . "
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"
}
"] = $p2; } $numbers = array_merge($numbers1, $numbers2); var_dump($numbers);

The resulting output will be:

结果输出将是:

$options = [];
for ($i = 1; $i <= 4; $i++) {
    $options[$i.'.0'] = $i;
}

Without the . "\0"part the resulting array would be:

如果没有该. "\0"部分,结果数组将是:

foreach($array as $key => $value) { 
    $newkey = sprintf('%s',$key);
    $newArray["'$newkey'"] = $value; 
} 

Also ksort()will also ignore the null character meaning $numbers[111]and $numbers["111\0"]will both have the same weight in the sorting algorithm.

ksort()将忽略空字符的含义,$numbers[111]并且$numbers["111\0"]在排序算法中都具有相同的权重。

The only downside to this method is that to access, for example $numbers["444"], you would actually have to access it via $numbers["444\0"]and since not even var_dump()will show you there's a null character at the end, there's no clue as to why you get "Undefined offset". So only use this hack if iterating via a foreach()or whoever ends up maintaining your code will hate you.

这种方法的唯一缺点是,例如$numbers["444"],要访问它,您实际上必须通过它来访问它$numbers["444\0"],因为甚至var_dump()不会显示末尾有一个空字符,所以不知道为什么会得到“未定义的偏移量”。因此,只有在通过 a 进行迭代foreach()或最终维护您的代码的人会讨厌您时才使用此 hack 。

回答by NeuroXc

I was able to get this to work by adding '.0' onto the end of each key, as such:

我能够通过在每个键的末尾添加“.0”来使其工作,如下所示:

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

Will return:

将返回:

array("1.0" => 1, "2.0" => 2, "3.0" => 3, "4.0" => 4)

array("1.0" => 1, "2.0" => 2, "3.0" => 3, "4.0" => 4)

It may not be completely optimal but it does allow you to sort the array and extract (an equivalent of) the original key without having to truncate anything.

它可能不是完全最优的,但它确实允许您对数组进行排序并提取(等效于)原始键,而无需截断任何内容。

回答by user387302

Edit: This should work

编辑:这应该有效

##代码##

回答by Walf

Only one commenter got this right, and the accepted answer is bad. asort(), uasort(), and arsort()are built-ins that sort arrays whilst maintaining the key associations, and they've existed since version 4. RTFM, people.

只有一位评论者说对了,接受的答案是badasort(), uasort(), 和arsort()是在维护键关联的同时对数组进行排序的内置函数,它们自第 4 版以来就已存在。RTFM,人们。

Don't escape/corrupt your data by messing with keys. You can't stop PHP from using integer keys, so don't try. It only happens when the integer representation is exactly the same as the string, so you just cast them as such when reading the keys & values from the array, i.e. (string) $key. You can do all the sort operations you need using the aforementioned functions.

不要通过弄乱密钥来逃避/破坏您的数据。您无法阻止 PHP 使用整数键,所以不要尝试。只有当整数表示与字符串完全相同时才会发生这种情况,因此在从数组中读取键和值时,您只需将它们强制转换,即(string) $key. 您可以使用上述函数执行所需的所有排序操作。

回答by Ramya Aravind

Hi we can make the index of the array a string using the following way. If we convert an array to xml then indexes like [0]may create issue so convert to string like [sample_0]

嗨,我们可以使用以下方式使数组的索引成为字符串。如果我们将数组转换为 xml,则索引之类的[0]可能会产生问题,因此转换为字符串之类的[sample_0]

##代码##