PHP数组键中允许的字符?


86

我有一些php数组键,其中填充了许多奇怪的字符。

可以吗?我无法使用的物品有任何限制吗?


限制条件:$a = (object) ['@km³' => 123]; error_log($a->@km³);
Bitterblue

Answers:


90

根据手册

键可以是整数或字符串。该值可以是任何类型。

此外,将进行以下按键强制转换:

  • 包含有效整数的字符串将强制转换为整数类型。例如,键“ 8”实际上将存储在8以下。另一方面,“ 08”将不是强制转换,因为它不是有效的十进制整数。
  • 浮点数也被强制转换为整数,这意味着小数部分将被截断。例如,密钥8.7实际上将存储在8以下。
  • 布尔也被强制转换为整数,即,键true将实际存储在1以下,而键false将存储在0以下。
  • 空值将强制转换为空字符串,即键空值实际上将存储在“”下。
  • 数组和对象不能用作键。这样做将导致警告:偏移量类型非法。

再次手册:

字符串是一系列字符,其中字符与字节相同。这意味着PHP仅支持256个字符的集合,因此不提供本机Unicode支持。查看字符串类型的详细信息。

简而言之,任何字符串都可以作为键。字符串可以包含任何二进制数据(最大2GB)。因此,键可以是任何二进制数据(因为字符串可以是任何二进制数据)。

数组键的一些随机(有效)滥用:

$w = array(chr(0) => 'null byte?', chr(rand(0, 255)) => 'random byte?');
var_dump($w);

1
需要说明的是,这并不意味着您不能将Unicode字符串用作数组键。实际上,任何二进制字符串都可以正常工作。我发现PHP自我描述的缺乏Unicode支持很烦人,因为这不是真的。:)
deceze

1
@deceze Unicode属于“任何二进制数据”的类别:)(尽管我猜想该手册的措辞,但我认为有必要进行澄清)。说“不提供本机Unicode支持”是正确的。PHP的核心不包括strlen,substr等的Unicode版本。尽管“不提供对Unicode字符串的本机处理”可能更合适。
科尔宾

3
当然,核心不包含任何用于处理Unicode字符串的功能。但是只要您不想操纵字符串,PHP就可以很好地支持它们。实际上,默认情况下,几乎所有PHP安装都可使用MB扩展,因此“核心支持”与否之间的区别主要是学术上的。:)
deceze

1
@deceze也许他们的注释应该显示为“不是本机(请参阅mb扩展名)”或类似的内容。你说的没错。自2005年以来,任何PHP安装都基本上支持Unicode,尽管我认为PHP(带有扩展名)对Unicode的支持仍然有些令人不快。
科尔宾

@Corbin,您为什么称其为滥用而不是使用
Pacerier,2013年

12

密钥必须是字符串或整数。有一些强制转换,但我认为手册在解释方面做得很好:

键可以是整数或字符串。该值可以是任何类型。

此外,将进行以下按键强制转换:

  • 包含有效整数的字符串将强制转换为整数类型。例如,键“ 8”实际上将存储在8以下。另一方面,“ 08”将不是强制转换,因为它不是有效的十进制整数。
  • 浮点数也被强制转换为整数,这意味着小数部分将被截断。例如,密钥8.7实际上将存储在8以下。
  • 布尔也被强制转换为整数,即,键true将实际存储在1以下,而键false将存储在0以下。
  • 空值将强制转换为空字符串,即键空值实际上将存储在“”下。
  • 数组和对象不能用作键。这样做将导致警告:偏移量类型非法。

资源类型现在可以转换为整数(不确定这是否是一项新功能),因此您可以通过将文件句柄或curl句柄转换为整数并将其用作键,从而间接使用例如文件句柄或curl句柄作为键。
thomasrutter

10

我找到了这个答案,以寻找有关我遇到的问题的更多信息。我使用的字符串中包含UTF-8字符,不能用作我拥有的数组的键。

就像是

$str = "R&D - Solution";
$arr = array( "R&D - Solution" => "Research" );
echo $arr[$str];  // did not work

对我来说(不大不明智)解决方案是这样做。

$str = md5("R&D - Solution");
$arr = array( md5("R&D - Solution") => "Research" );
echo $arr[$str];  // works!

2
我喜欢md5()来生成数组键。即使此时并非完全必要,它仍然感觉更安全。
Billynoah 2014年

1
md5()非常适合从任何字符串生成纯文本密钥。安全不是问题。快速也很好。唯一的问题是他们是否决定弃用然后消除它,因为现在它对最初设计的内容不利。我们将会看到。
Patanjali

2
您是否在使用旧版本的PHP?您的第一个示例在PHP 7.1中运行良好。
Elliot B.19年

6

PHP数组键可以是整数或字符串。PHP字符串是字节数组,表示字节序列。没有其他类型的字符串,PHP也不会对数组键字符串施加任何特殊限制。换句话说:只要是字符串,一切都会进行。


我认为从字符串到整数键的隐式转换是一个重要的区别,因为某些函数在键是否为整数时的操作方式有所不同。例如,您可能仅使用任意字符串号来发现数组函数随后会从0..n-1重新索引它们。
马修(Matthew)

1
同意,但我认为这是这个问题范围的边界。:)
deceze

5

您可以将任何可放入PHP字符串中的内容用作数组键。所允许的字符没有限制。

$a = array();

$x = 'long string of random garage';
echo $a[$x]; // this is ok

$x = array();
echo $a[$x]; // not ok

1

如果复杂键导致“未定义索引”错误,则可能只是出现“修剪”问题。

我疯了,因为一个复杂的键吐出了“未定义的索引”错误,我认为这可能是语法违规。导致错误的数组键是从MySQL数据库查询的字段中构建的,该字段已转换为键并在新数组中使用。密钥如下所示:pl_1DNKoiJKwotCqAycickBVhTy这是代码的构造方式。

//new array created from database query
$new_array[$dbquery['fieldname']] = {some value};

//key value found in field of second array
$keyval = $array_two['fieldname'];

//this produced the "undefined index" error
echo $new_array[$keyval];

实际上,当$keyval$dbquery['fieldname']看起来是完美匹配时(通过在浏览器中回显两者进行视觉验证)。只需trim在第二条语句中使用这样的方式就解决了这个难题:$keyval = trim($array_two['fieldname']);一旦“修剪”了,php就不再抱怨了。

希望这可以从一些令人沮丧的时刻中拯救其他人。


0

我个人对数组键中的不寻常字符没有任何问题。除了说密钥必须是标量之外,合法和不合法的东西也没有得到充分的记录。最好的选择就是尝试一下。


是的,有点不一致,但是有据可查。
科尔宾

0

除了所有正确答案外:您还可以使用PSR,它们是最佳程序员之间的一种规则,具有良好而标准的编码风格。



-1

可以使用ANSI“é”对php页面进行编码(Cinéma不会显示为Cinéma)。在Notepad ++中,只需使用菜单Encode => Convert ANSI并保存


2
(此帖子似乎无法为问题提供高质量的答案。请编辑您的答案,或仅将其发布为对问题的评论)。
sɐunıɔןɐqɐp

您能进一步解释吗?如果é不存在怎么办,如果OP根本不使用Notepad ++怎么办?
Nico Haase
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.