在PHP中,函数是二进制安全的意味着什么?


119

PHP什么它通过一个函数是指binary-safe

是什么使它们与众不同,它们通常在哪里使用?

Answers:


106

这意味着当您传递任意二进制数据(即,包含非ASCII字节和/或空字节的字符串)时,该函数将正常运行。

例如,非二进制安全函数可能基于C函数,该函数需要以null结尾的字符串,因此,如果字符串包含null字符,该函数将忽略其后的所有内容。

这是相关的,因为PHP不会干净地分隔字符串和二进制数据。


2
这是否意味着二进制安全字符串仅包含长度为1个字节的“字符”?
查理·帕克

3
@CharlieParker:不,你倒退了。二进制安全性是函数的属性,这意味着它们可以正确处理任何字符串。相反的是只包含ASCII字符的字符串非空字符-这样的字符串应该正确地被任何函数进行处理。
Michael Borgwardt 2014年

也许是因为我正在阅读redis协议中的“批量字符串”而感到困惑,它说它们代表“单个二进制二进制安全”字符串。我想我现在正确理解了您的帖子。但是,说一个字符串是“二进制安全的”(在我提供的示例中)是否有意义?
查理·帕克2014年

93

其他用户已经提到了binary safe一般意义。

在PHP中,含义更具体,仅以Michael给出的示例为例。

PHP中的所有字符串都有关联的长度,该长度是组成字符串的字节数。当函数操作字符串时,它可以:

  1. 依靠该长度的元数据。
  2. 依靠以空字符结尾的字符串,即,在实际上是字符串一部分的数据之后,带有值的字节 0将出现。

确实,引擎操作的所有字符串PHP变量也都是以空值结尾的。依赖2的函数的问题是,如果字符串本身包含带有值的字节0,则正在操作该函数的函数将认为该字符串已在该点结束,并且之后将忽略所有内容。

例如,如果PHP的strlen功能像C标准库那样工作strlen,则结果将是错误的:

$str = "abc\x00abc";
echo strlen($str); //gives 7, not 3!

15
最后一个例子!
拉斐尔2012年

5
在PHP 7.0中的测试中,strlen()函数是一个二进制安全函数。
linjie

@Artefacto:您是说内置的PHP函数strlen()二进制安全函数吗?我向您确认是因为在该函数的PHP手册页面strlen()上没有提到它是二进制安全函数还是非二进制安全函数。PHP手册中唯一缺少的一件事就是在我脑海中造成混乱,因此我想向您确认。我热切期待您的答复。谢谢。
PHPLover

@PHPLover是strlen()是二进制安全的。运行php -r 'var_dump("\x00\x00\x00");'以进行验证,但是php的strlen在长一段时间内都是二进制安全的,因为至少是php 4.x(也就是说,存在一个可憎之类叫做“ mb_overload”,但请假装不存在-php.net /manual/en/mbstring.overload.php
hanshenrik

62

更多示例:

<?php

    $string1 = "Hello";
    $string2 = "Hello\x00World";

    // This function is NOT ! binary safe
    echo strcoll($string1, $string2); // gives 0, strings are equal.

    // This function is binary safe
    echo strcmp($string1, $string2); // gives <0, $string1 is less than $string2.

?>

\x表示十六进制表示法。另请:PHP字符串

0x00 = NULL
0x04 = EOT (End of transmission)

ASCII表以查看ASCII字符列表


只是为了确保我理解,然后Hello\r\nWORLD应该不像Hello函数是二进制安全的一样,对吗?
查理·帕克

另外,如何实现这种功能?是否有正则表达式检查其二进制安全性或是否使用其他方法?
查理·帕克

@Subscriberius:内置函数是strlen() 二进制安全的吗?
PHPNut
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.