11

我偶然发现了 PHP 5.6 中 php 函数function_exists ( )的奇怪行为。问题是,如果我将函数名称参数直接作为字符串提供,结果与作为变量提供时不同。这是代码:

$f='posix_getpwuid';
$r1=function_exists('posix_getpwuid');
$r2=function_exists($f);

echo phpversion() . "\n";
var_dump($r1);
var_dump($r2);

结果如下:

5.6.5
bool(true)    # $r1=function_exists('posix_getpwuid');
bool(false)   # $r2=function_exists($f);

我希望,在这两种情况下它都应该是错误的。

当深入挖掘时,我发现它与OPCache 有关。当 OPCache 被禁用时,结果很好 - 两个调用都返回 false。但是启用 OPCache 后,在第一次运行时它仍然可以,但在第二次运行时(所以当缓存的结果被提供时),结果是错误的。

函数posix_getpwuid在 PHP 配置中的disable_functions中被禁用。当使用不存在的函数名进行测试时,结果是正确的。

在 PHP 5.5.21 中进行测试时,结果很好(有或没有 OPCache)。

在 PHP 5.5 和 5.6 中使用 Zend OPcache v7.0.4-dev。

我正在考虑向 PHP 开发人员提交一个错误,只是想确保我没有遗漏任何东西。

谢谢。

编辑:还使用新编译的 PHP 5.6.6 和 5.6.7 进行了测试。操作系统已全面更新 CentOS 6.6。5.6.6 或 5.6.7 的结果相同。

PHP 在没有任何构建选项的情况下构建:

./configure \
    --prefix=/usr/local/php/5.6.7-test

用非常简单的 php.ini

disable_functions = posix_getpwuid
date.timezone = Europe/Prague
zend_extension=/usr/local/php/5.6.7-test/lib/php/extensions/no-debug-non-zts-20131226/opcache.so

测试脚本:

<?
echo phpversion() . "\n";
$f='posix_getpwuid';
$r1=function_exists('posix_getpwuid');
$r2=function_exists($f);
echo "\n\n";

echo "string: ";
var_dump ($r1);
echo "var.  : ";
var_dump ($r2);

echo "opcache status: ";
var_dump(opcache_get_status()['opcache_enabled']);

和结果 - 第一次运行和正确的结果:

# /usr/local/php/php-TEST/bin/php-cgi -c /data/web/php-test/ fce.php

X-Powered-By: PHP/5.6.7
Content-type: text/html; charset=UTF-8

5.6.7

string: bool(false)
var.  : bool(false)
opcache status: bool(true)

第二次运行 - 由 OPCache 提供服务,结果很糟糕:

# /usr/local/php/php-TEST/bin/php-cgi -c /data/web/php-test/ fce.php

X-Powered-By: PHP/5.6.7
Content-type: text/html; charset=UTF-8

5.6.7

string: bool(true)
var.  : bool(false)
opcache status: bool(true)

(现在我不知道为什么,但是当php只执行时,OPCache 没有启动,所以我使用了php-cgi

4

1 回答 1

3

我报告了 PHP https://bugs.php.net/bug.php?id=69297中的一个错误

现在已为 5.6.8 修复。 http://git.php.net/?p=php-src.git;a=commit;h=d380d1cb1ba48c41682f749692b78a10e91dd070

我测试了补丁,它工作正常。

感谢@tlens 与我一起进行测试。

于 2015-03-25T16:40:35.663 回答