首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哪些PHP函数被认为不是“二进制安全”?这些“非二进制安全”函数将字符串传递给哪些库?为什么?

哪些PHP函数被认为不是“二进制安全”?这些“非二进制安全”函数将字符串传递给哪些库?为什么?
EN

Stack Overflow用户
提问于 2018-06-23 11:18:44
回答 3查看 515关注 0票数 10

我使用的是Windows 10家庭单语言版,这是我的计算机上的64位操作系统

我已经安装了最新版本的XAMPP,它在我的计算机上安装了PHP7.2.7

我是根据PHP手册的摘录提出这个问题的:

PHP中的字符串被实现为一个字节数组和一个指示缓冲区长度的整数。它没有关于如何将这些字节转换为字符的信息,而将该任务留给程序员。字符串可以组成的值没有任何限制;特别是,字符串中任何地方都允许值为0的字节(“NUL字节”)(但是,本手册中说的一些函数不属于“二进制安全”,可能会将字符串传递给库,这些库在NUL字节之后忽略数据。)

我非常理解PHP中二进制安全函数和非二进制安全函数之间的区别。我脑子里一直有疑虑。请一个接一个地回答,并附上适当的解释和适当的例子。

  • 在PHP中存在“非二进制安全”和“二进制安全”函数是因为整个PHP解析器都是用C语言编写的。
  • 在处理包含任何值(包括NUL字节)的字符串时,C和PHP之间有什么区别?
  • 我想要完整的PHP函数列表,它们是“非二进制安全的”和“二进制安全的”。
  • “非二进制安全”和“二进制安全”的特性只适用于操纵字符串的函数,而不适用于处理PHP中其他类型的PHP函数吗?
  • 为什么非二进制安全函数将字符串传递给库?
  • 非二进制安全函数是否只在它们处理的字符串包含NUL字节时才将字符串传递给库?
  • 这些“非二进制安全”函数将字符串传递给哪些库?
  • 这些库如何处理从“非二进制安全”函数接收的字符串?
  • 在将包含NUL字节的字符串传递给某个库后,“非二进制安全”函数是否像“二进制安全”函数一样工作?
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-07-31 10:46:09

正如arkascha所解释的,“二进制安全”和“非二进制安全”的问题与语言无关。

使用空字节(0x00)表示字符串的结尾更简单(这可能是C与它一起使用的原因),但缺点是,如果必须能够处理所有类型的数据,则字符串中任何地方都不能有空字节,这是很大的限制。将长度存储为字符串的元数据部分要复杂得多,如Pete所示,但它允许您处理任何类型的数据。

关于哪些函数是“二进制安全的”或“非二进制安全的”,只需在使用这些函数之前阅读PHP手册即可。这就是我要做的。没有必要构造一个列表,因为PHP手册已经解释了您需要了解的函数,包括它们是否是二进制安全的。

我相信,你的大部分帖子是因为误解了你引用的PHP手册的解释,特别是这个部分:

然而,在本手册中有几个函数被认为不是“二进制安全”,可能会将字符串传递给忽略NUL字节后忽略数据的库。

让我试着用我自己的话说得更清楚些:

然而,在本手册中有几个函数说不是“二进制安全”,是可能将字符串传递给忽略NUL字节后的数据的库的函数。

所以它并没有说“非二进制安全函数将字符串传递给库”,这是一种误解。它的意思是“函数可以将字符串传递给忽略NUL字节后忽略数据的库,在本手册中,这些函数被认为是不二进制安全的”。

“向库传递”只是“从其他库调用函数”的另一种方式。“忽略NUL字节后的数据”是一种称为非二进制安全的行为。

另一种说法是:

本手册中的一些函数被认为不是“二进制安全”,因为它们可以调用其他也不是“二进制安全”的函数(在NUL字节之后忽略数据的函数)。

我希望这能帮你弄清楚。

票数 9
EN

Stack Overflow用户

发布于 2018-07-29 10:25:12

传统上表示字符串的方法有两种:使用特殊字符发送字符串结束的信号,或者将字符串长度与字符串数据一起存储。C使用前者;字符串是一个字符数组,结尾处为空字符。但是,这有一个限制,即C中的字符串不能在任何其他地方使用空字符,只能在末尾使用。

为了克服这个限制,PHP引擎使用这个结构来表示一个字符串:

代码语言:javascript
复制
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选择存储字符串的长度及其数据。

如果混合“二进制安全”和“非二进制安全”功能会发生什么?

考虑在编写PHP扩展时可能使用的以下C代码:

代码语言:javascript
复制
zend_string *a = zend_string_init("a\0b", /* string length */ 3, 0);
zend_string *b = zend_string_init("a\0c", /* string length */ 3, 0);

if (strcmp(a->val, b->val) == 0) {
    php_printf("Strings are equal!");
}

你觉得会发生什么?此代码输出“字符串相等!”尽管他们显然不平等。由于strcmp不考虑字符串的长度,所以它是一个非二进制安全函数。

C的大多数标准库字符串函数都可以被归类为“非二进制安全”,因为它依赖于空终止字符。

在扩展代码中处理zend_string时,应该使用Zend函数(zend_string_*)而不是C的字符串库。

若要修复前面的代码,请执行以下操作:

代码语言:javascript
复制
if (zend_string_equals(a, b)) {
    php_printf("Equal!");
} else {
    php_printf("Not equal");
}

这现在正确地打印“不相等”。

票数 5
EN

Stack Overflow用户

发布于 2018-06-23 11:29:53

函数是否以“二进制安全”的方式处理运行时数据的问题与系统使用的语言无关。这是一个如何处理数据的问题。PHP是一种高级语言,这意味着它具有字符串类型的高级实现。这并不像C所依赖的那样依赖终止空字符,而是字符串类型维护有关存储字符串的元数据,这使得实现更加灵活和健壮。然而,这与“二进制安全”与否无关。

你的其他观点并不能得到明确的回答。php库使用什么取决于您的设置,这是一个动态环境。潜在的库如何处理移交给他们的数据也与php函数是否可以被视为“二进制安全”无关--库不知道php,它只能根据库的实现方式来传递数据和处理。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51000656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档