Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP 5.6 function_exists strange behavior with OPCache

I stumbled upon strange behavior of php function function_exists() in PHP 5.6. The thing is, that if I provide the function name parameter directly as string, the result is different than when provided as variable. Here is the code:

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

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

and here is the result:

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

I would expect, that it should be false in both cases.

When digging deeper, i discovered, that it has something to do with OPCache. When the OPCache is disabled, the results are fine - both calls returns false. But with OPCache enabled, in the first run its still OK but in the second run (so when the cached result is served), result is wrong.

Function posix_getpwuid is disabled in PHP configuration in disable_functions. When tested with non-existent function name, results are correct.

When testing in PHP 5.5.21, results are fine (with or without OPCache).

Using Zend OPcache v7.0.4-dev in both PHP 5.5 and 5.6.

I'm thinking about submitting a bug to PHP developers, just wanted to be sure I'm not missing something.

Thanks.

edit: Also tested with freshly compiled PHP 5.6.6 and 5.6.7. OS is fully updated CentOS 6.6. Results are same for either 5.6.6 or 5.6.7.

PHP built without any build options:

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

with realy simple 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

test script:

<?
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']);

and result - first run and correct result:

# /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)

second run - served by OPCache, result is bad:

# /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)

(Now I'm not sure why, but when executed with php only, OPCache didnt start, so I used php-cgi)

like image 656
dave Avatar asked Mar 24 '15 15:03

dave


1 Answers

I reported a bug in PHP https://bugs.php.net/bug.php?id=69297

It has been fixed now for 5.6.8. http://git.php.net/?p=php-src.git;a=commit;h=d380d1cb1ba48c41682f749692b78a10e91dd070

I tested the patch and it works fine.

Thank you @tlenss for testing with me.

like image 129
dave Avatar answered Oct 12 '22 22:10

dave