为什么php中存在二进制安全AND二进制不安全函数?

9 php string io binary-data

这种行为/实施有什么理由吗?
例:

$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];
Run Code Online (Sandbox Code Playgroud)

给我们一个完整的错误:

注意未定义的索引:在第9行

示例#2:

echo date("Y\0/m/d");
Run Code Online (Sandbox Code Playgroud)

输出:

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);
Run Code Online (Sandbox Code Playgroud)

输出:

索引的数组
"Y/m/d"
字符串(18)"索引的数组"
字符串(6)"Y/m/d"

请注意,$string长度为18,但显示的是17个字符.

编辑

可能的重复PHP手册:

密钥可以是整数或字符串.值可以是任何类型.包含有效整数的字符串将强制转换为整数类型.例如,键"8"实际上将存储在8下.另一方面,"08"将不会被转换,因为它不是有效的十进制整数.简而言之,任何字符串都可以成为关键.字符串可以包含任何二进制数据(最多2GB).因此,密钥可以是任何二进制数据(因为字符串可以是任何二进制数据).

php字符串详细信息:

字符串可以组成的值没有限制; 特别是,字符串中的任何地方都允许使用值为0的字节("NUL字节")(但是,本手册中称为"二进制安全"的一些函数)可能会将字符串移交给忽略数据后的数据库. NUL字节.)

但我仍然不明白为什么语言是这样设计的?是否存在此行为/实施的原因?为什么PHP不会将输入作为二进制安全处理,只是在某些功能中?

来自评论:

原因很简单,很多PHP函数就像printf在幕后使用C库的实现一样,因为PHP开发人员很懒.

这些的arent如echo,var_dump,print_r?换句话说,输出某些东西的函数.如果我们看看我的第一个例子,它们实际上是二进制安全的.对输出实现一些二进制安全和二进制不安全函数对我没有任何意义.或者只是在C中的std lib中使用一些,并编写一些全新的函数.

Mat*_*t S 7

对"为什么"的简短回答仅仅是历史.

PHP最初是作为编写C函数脚本的一种方式编写的,因此可以在生成HTML时轻松调用它们.因此PHP字符串只是C字符串,它是任何字节的集合.因此,在现代PHP术语中,我们会说没有什么是二元安全的,只是因为它没有计划成为其他任何东西.

早期的PHP并不打算成为一种新的编程语言,并且有机地发展,Lerdorf回想起来:"我不知道如何阻止它,从来没有任何编写语言的意图[...]我绝对没有想法如何编写一种编程语言,我只是不断添加下一个逻辑步骤."

随着时间的推移,语言逐渐增长,以支持更复杂的字符串处理函数,许多函数将字符串的特定字节考虑在内并变为"二进制安全". 根据最近编写的正式PHP规范:

至于如何将字符串中的字节转换为字符是未指定的.虽然字符串的用户可能会选择将特殊语义归因于具有该值的字节\0,但从PHP的角度来看,这样的空字节没有特殊含义.PHP不假定字符串包含任何特定数据或为任何字节或序列分配特殊值.

作为一种有机增长的语言,没有采取与C不同的方式普遍处理字符串的举动.因此,函数和库在具体情况下是二元安全的.

  • 你的答案解释了一切.简短明了. (2认同)