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);

どちらの場合もfalseになるはずです。

さらに深く掘り下げると、OPCacheと関係があることがわかりました。OPCache が無効になっている場合、結果は問題ありません。両方の呼び出しで false が返されます。ただし、OPCache を有効にすると、最初の実行では問題ありませんが、2 回目の実行では (つまり、キャッシュされた結果が提供されると)、結果が正しくありません。

関数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 でもテストされています。OSは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)

2 回目の実行 - 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)

(理由はよくわかりませんが、phponlyで実行すると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 に答える