哪些函数PHP据说不是"binary safe"?这些 "non-binary safe" 函数将字符串传递给哪些库?为什么?
What are the functions PHP which are said not to be "binary safe"? To which libraries these "non-binary safe" functions hand off the strings? And why?
我在我的机器上使用 Windows 10 家庭单语言版,这是一个 64 位操作系统 .
我已经安装了最新版本的 XAMPP 其中安装了 PHP 7.2.7在我的机器上。
我是根据摘自 PHP Manual 的摘录问这个问题的:
The string in PHP is implemented as an array of bytes and an integer
indicating the length of the buffer. It has no information about how
those bytes translate to characters, leaving that task to the
programmer. There are no limitations on the values the string can be
composed of; in particular, bytes with value 0 (“NUL bytes”) are
allowed anywhere in the string (however, a few functions, said in this
manual not to be “binary safe”, may hand off the strings to libraries
that ignore data after a NUL byte.)
我非常理解 PHP 中二进制安全函数和非二进制安全函数之间的区别。我心中有疑惑。请以适当的解释和适当的例子一一回答。
- "non-binary safe"和"binary-safe"函数的现象出现在PHP只是因为整个PHP解析器都是用C语言写的?
- C 和 PHP 在处理包含任何值(包括 NUL 字节)的字符串时有什么区别?
- 我想要 PHP 中 "non-binary safe" 和 "binary-safe" 的完整函数列表。
- "non-binary safe"和"binary-safe"的特性是否只适用于操作字符串的函数而不适用于处理PHP中其他类型的PHP函数?
- 为什么非二进制安全函数将字符串交给库?
- 非二进制安全函数是否仅在它们处理的字符串包含 NUL 字节时才将字符串传递给库?
- 这些 "non-binary safe" 函数将字符串传递给哪些库?
- 这些库如何处理从 "non-binary safe" 函数接收到的字符串?
- 将包含 NUL 字节的字符串传递给某个库后,"non-binary safe" 函数是否像 "binary safe" 函数一样工作?
函数是否"binary safe"处理运行时数据的问题与系统实现的语言无关,是数据如何处理的问题。 PHP 是一种高级语言,这意味着它具有字符串类型的高级实现。这并不像 C 所依赖的那样依赖于终止空字符,相反,字符串类型维护有关存储字符串的元数据,这允许更灵活和更健壮的实现。然而,这与 "binary safe" 与否无关。
您的其余观点无法真正明确地回答。 php 使用什么库本身取决于您的设置,这是一个动态环境。潜在图书馆如何处理移交给他们的数据与 php 函数是否可以被视为 "binary safe" 无关 - 图书馆不知道 php,它只会移交数据并根据库的实现方式进行处理。
传统上有两种表示字符串的方法:使用特殊字符表示字符串的结尾,或者将其长度与字符串数据一起存储。 C 使用前者;字符串是一个字符数组,末尾有一个空字符。但是,这有一个限制,即 C 中的字符串不能在除末尾以外的任何其他地方使用空字符。
为了克服这个限制,PHP 引擎使用这个结构来表示一个字符串:
struct _zend_string {
zend_refcounted_h gc; /* refcount struct */
zend_ulong h; /* hash value */
size_t len; /* length of string */
char val[1]; /* array of chars (using struct "hack") */
};
如您所见,PHP 开发人员选择将字符串的长度与其数据一起存储。
现在如果混合使用 "binary safe" 和 "non-binary safe" 功能会怎样?
考虑编写 PHP 扩展时可能使用的以下 C 代码:
zend_string *a = zend_string_init("a[=11=]b", /* string length */ 3, 0);
zend_string *b = zend_string_init("a[=11=]c", /* string length */ 3, 0);
if (strcmp(a->val, b->val) == 0) {
php_printf("Strings are equal!");
}
你认为会发生什么?此代码输出 "Strings are equal!",但它们显然不相等。由于strcmp
不考虑字符串的长度,它是一个非二进制安全函数。
大多数 C 的标准库字符串函数都可以归类为 "non-binary safe",因为它依赖于空终止字符。
在扩展代码中处理 zend_string
时,您应该使用 Zend 字符串函数 (zend_string_*
) 而不是 C 的字符串库。
修复之前的代码:
if (zend_string_equals(a, b)) {
php_printf("Equal!");
} else {
php_printf("Not equal");
}
现在可以正确打印 "Not equal"。
正如 arkascha 所解释的,"binary-safe" 和 "non-binary-safe" 的问题与语言无关。
使用空字节 (0x00) 来指示字符串的结尾更简单(这可能是 C 使用它的原因),
但缺点是字符串中的任何地方都不能有空字节
如果您必须能够处理各种数据,这是一个很大的限制。
将长度存储为字符串的元数据部分更为复杂,如 Pete 所示,但它允许您处理任何类型的数据。
关于"binary-safe"或"non-binary-safe"的功能,
在 使用这些函数之前,只需阅读 PHP 手册 。
我就是做这个的。
无需构建列表,因为 PHP 手册已经解释了您需要了解的有关函数的内容,包括它们是否是二进制安全的。
我认为,您的大部分 post 是由于误解了您引用的 PHP 手册的解释,尤其是这一部分:
however, a few functions, said in this manual not to be “binary safe”, may hand off the strings to libraries that ignore data after a NUL byte.
让我尝试通过添加一些我自己的话来使它更清楚:
however, a few functions, said in this manual not to be “binary safe”, are the functions that may hand off the strings to libraries that ignore data after a NUL byte.
所以真的没有说"non-binary safe functions hand off the strings to libraries",这是误读。
意思是"functions that may hand off the strings to libraries that ignore data after a NUL byte, are said in this manual as not binary-safe".
"Handing off to libraries" 只是 "calling functions from other libraries" 的另一种说法。
"Ignoring data after a NUL byte" 是一种称为非二进制安全的行为。
另一种表达方式是:
A few functions in this manual are said not to be "binary safe" because they may call other functions that are also not "binary safe" (functions that ignore data after a NUL byte).
我希望这能帮您解决问题。
我在我的机器上使用 Windows 10 家庭单语言版,这是一个 64 位操作系统 .
我已经安装了最新版本的 XAMPP 其中安装了 PHP 7.2.7在我的机器上。
我是根据摘自 PHP Manual 的摘录问这个问题的:
The string in PHP is implemented as an array of bytes and an integer indicating the length of the buffer. It has no information about how those bytes translate to characters, leaving that task to the programmer. There are no limitations on the values the string can be composed of; in particular, bytes with value 0 (“NUL bytes”) are allowed anywhere in the string (however, a few functions, said in this manual not to be “binary safe”, may hand off the strings to libraries that ignore data after a NUL byte.)
我非常理解 PHP 中二进制安全函数和非二进制安全函数之间的区别。我心中有疑惑。请以适当的解释和适当的例子一一回答。
- "non-binary safe"和"binary-safe"函数的现象出现在PHP只是因为整个PHP解析器都是用C语言写的?
- C 和 PHP 在处理包含任何值(包括 NUL 字节)的字符串时有什么区别?
- 我想要 PHP 中 "non-binary safe" 和 "binary-safe" 的完整函数列表。
- "non-binary safe"和"binary-safe"的特性是否只适用于操作字符串的函数而不适用于处理PHP中其他类型的PHP函数?
- 为什么非二进制安全函数将字符串交给库?
- 非二进制安全函数是否仅在它们处理的字符串包含 NUL 字节时才将字符串传递给库?
- 这些 "non-binary safe" 函数将字符串传递给哪些库?
- 这些库如何处理从 "non-binary safe" 函数接收到的字符串?
- 将包含 NUL 字节的字符串传递给某个库后,"non-binary safe" 函数是否像 "binary safe" 函数一样工作?
函数是否"binary safe"处理运行时数据的问题与系统实现的语言无关,是数据如何处理的问题。 PHP 是一种高级语言,这意味着它具有字符串类型的高级实现。这并不像 C 所依赖的那样依赖于终止空字符,相反,字符串类型维护有关存储字符串的元数据,这允许更灵活和更健壮的实现。然而,这与 "binary safe" 与否无关。
您的其余观点无法真正明确地回答。 php 使用什么库本身取决于您的设置,这是一个动态环境。潜在图书馆如何处理移交给他们的数据与 php 函数是否可以被视为 "binary safe" 无关 - 图书馆不知道 php,它只会移交数据并根据库的实现方式进行处理。
传统上有两种表示字符串的方法:使用特殊字符表示字符串的结尾,或者将其长度与字符串数据一起存储。 C 使用前者;字符串是一个字符数组,末尾有一个空字符。但是,这有一个限制,即 C 中的字符串不能在除末尾以外的任何其他地方使用空字符。
为了克服这个限制,PHP 引擎使用这个结构来表示一个字符串:
struct _zend_string {
zend_refcounted_h gc; /* refcount struct */
zend_ulong h; /* hash value */
size_t len; /* length of string */
char val[1]; /* array of chars (using struct "hack") */
};
如您所见,PHP 开发人员选择将字符串的长度与其数据一起存储。
现在如果混合使用 "binary safe" 和 "non-binary safe" 功能会怎样?
考虑编写 PHP 扩展时可能使用的以下 C 代码:
zend_string *a = zend_string_init("a[=11=]b", /* string length */ 3, 0);
zend_string *b = zend_string_init("a[=11=]c", /* string length */ 3, 0);
if (strcmp(a->val, b->val) == 0) {
php_printf("Strings are equal!");
}
你认为会发生什么?此代码输出 "Strings are equal!",但它们显然不相等。由于strcmp
不考虑字符串的长度,它是一个非二进制安全函数。
大多数 C 的标准库字符串函数都可以归类为 "non-binary safe",因为它依赖于空终止字符。
在扩展代码中处理 zend_string
时,您应该使用 Zend 字符串函数 (zend_string_*
) 而不是 C 的字符串库。
修复之前的代码:
if (zend_string_equals(a, b)) {
php_printf("Equal!");
} else {
php_printf("Not equal");
}
现在可以正确打印 "Not equal"。
正如 arkascha 所解释的,"binary-safe" 和 "non-binary-safe" 的问题与语言无关。
使用空字节 (0x00) 来指示字符串的结尾更简单(这可能是 C 使用它的原因), 但缺点是字符串中的任何地方都不能有空字节 如果您必须能够处理各种数据,这是一个很大的限制。 将长度存储为字符串的元数据部分更为复杂,如 Pete 所示,但它允许您处理任何类型的数据。
关于"binary-safe"或"non-binary-safe"的功能, 在 使用这些函数之前,只需阅读 PHP 手册 。 我就是做这个的。 无需构建列表,因为 PHP 手册已经解释了您需要了解的有关函数的内容,包括它们是否是二进制安全的。
我认为,您的大部分 post 是由于误解了您引用的 PHP 手册的解释,尤其是这一部分:
however, a few functions, said in this manual not to be “binary safe”, may hand off the strings to libraries that ignore data after a NUL byte.
让我尝试通过添加一些我自己的话来使它更清楚:
however, a few functions, said in this manual not to be “binary safe”, are the functions that may hand off the strings to libraries that ignore data after a NUL byte.
所以真的没有说"non-binary safe functions hand off the strings to libraries",这是误读。 意思是"functions that may hand off the strings to libraries that ignore data after a NUL byte, are said in this manual as not binary-safe".
"Handing off to libraries" 只是 "calling functions from other libraries" 的另一种说法。 "Ignoring data after a NUL byte" 是一种称为非二进制安全的行为。
另一种表达方式是:
A few functions in this manual are said not to be "binary safe" because they may call other functions that are also not "binary safe" (functions that ignore data after a NUL byte).
我希望这能帮您解决问题。