【发布时间】:2016-08-24 08:22:57
【问题描述】:
这种行为/实施是否有任何原因?
示例:
$array = array("index_of_an_array" => "value");
class Foo {
private $index_of_an_array;
function __construct() {}
}
$foo = new Foo();
$array = (array)$foo;
$key = str_replace("Foo", "", array_keys($array)[0]);
echo $array[$key];
给我们一个错误这是完整的:
注意未定义索引:第 9 行
示例 #2:
echo date("Y\0/m/d");
输出:
2016
但是! 例如,echo 或 var_dump() 和其他一些函数会“按原样”输出字符串,只有 \0 字节被浏览器隐藏。
$string = "index-of\0-an-array";
$strgin2 = "Y\0/m/d";
echo $string;
echo $string2;
var_dump($string);
var_dump($string2);
输出:
数组索引
“年/月/日”
string(18) "数组索引"
string(6) "年/月/日"
注意,$string 长度为 18,但显示了 17 个字符。
编辑
来自possible duplicate 和php manual:
键可以是整数或字符串。该值可以是任何类型。 包含有效整数的字符串将被转换为整数类型。例如。键“8”实际上将存储在 8 下。另一方面,“08”不会被强制转换,因为它不是有效的十进制整数。所以简而言之,任何字符串都可以是键。一个字符串可以包含任何二进制数据(最大 2GB)。因此,键可以是任何二进制数据(因为字符串可以是任何二进制数据)。
字符串可以包含的值没有限制; 特别是,任何地方都允许值为 0 的字节(“NUL 字节”) 在字符串中(但是,有几个函数,在本手册中说不是 “二进制安全”,可能会将字符串交给忽略数据的库 在一个 NUL 字节之后。)
但我还是不明白为什么语言是这样设计的?这种行为/实施是否有原因?为什么 PHP 不会在任何地方都将输入作为二进制安全处理,而只是在某些函数中处理?
来自comment:
原因很简单,很多像
printf这样的PHP函数在后台使用了C库的实现,因为PHP开发者很懒。
不是echo, var_dump, print_r 吗?换句话说,输出一些东西的函数。如果我们看一下我的第一个示例,它们实际上是二进制安全的。为输出实现一些二进制安全和二进制不安全函数对我来说毫无意义。或者只是使用 C 中的 std lib 中的一些,并编写一些全新的函数。
【问题讨论】:
-
嗯,
\0表示字符串的结尾...如果将其放在双引号之间,它将被解释。你试过把它放在单引号里吗? -
因为它便宜且易于编写,因为 C 可以完成大部分工作。
-
@Alnitak - 你的评论有什么意义?我在这里偶然发现使用谷歌,现在我正在阅读一个 200k 代表成员使用任何事实来抨击一种语言。当 SO 的老牌成员在没有任何事实的情况下四处游荡时,我们这些普通人是否应该信任他们?
-
在预期只使用长度的例程中,“C”空终止字符串的问题可能是“尴尬”的。一些较旧的“安全”程序可能存在问题。想象一下有人使用的密码中包含一个空字节?空字节之后的所有内容都将被忽略?
标签: php string io binary-data