go to bug id or search bugs for
Several websites are affected (Wordpress, NextCloud, PMB, Phpbb etc ...) on PHP 7.3.x till this version (7.3.15) and same with PHP 7.4 till now since several month.
The problem isn't present with PHP 7.2.x and lower.
The affected function is : if (!function_exists('getallheaders'))
With PHP 7.3 and 7.4 the following error is reported :
Fatal error: Cannot redeclare getallheaders() in ...
With exactly the same website without modification files the problem is not present on PHP 7.2 and lower.
Sample error message on PHP 7.3 and 7.4 :
Nextcloud : Fatal error: Cannot redeclare getallheaders() in /home/httpd/*/*/*/*/*/3rdparty/ralouphie/getallheaders/src/getallheaders.php on line 10
PhpBB : /home/httpd/*/*/*/*/*/forum/vendor/ralouphie/getallheaders/src/getallheaders.php on line 10
PMB : /home/httpd/*/*/*/*/*/includes/apache_functions.inc.php on line 10
Wordpress etc ...
All web developers are saying to rename the function "function getallheaders()" to avoid this error message ... which is not possible to everybody which are not developers ...
I'm using PHP 7.2, 7.3 and 7.4 on PHP-FPM with compilation install.
Someone could solve this problem which become more visible since people are upgrading their website to PHP 7.3 and + ?
Thank you in advance.
Fatal error: Cannot redeclare getallheaders() in ...
Add a Patch
Add a Pull Request
developers simply need to learn that it's a terrible idea to taint the global namespace with random *unprefixed* userland functions
eveniif the function_exists() hack would work what makes you thinking that your handcrafted function is signature and *behavior" compatible?
Reading through the docs for the opcache ini settings I note that the default value for opcache.optimization_level was changed in 7.3 to remove a flag, and a brief wander through the source reveals that the flag in question acquired new meaning between 7.2 and 7.3, and is also described as "unsafe", as is one of its neighbours that was removed from the default in 5.6.18. Hypothetically speaking, if one were to set up a new PHP installation by, say, copy-pasting the same ini files that originate in ancient history and have been passed from version to version since PHP 5, and hypothetically they maybe had buggered about with opcache related settings at some point and "turned everything on to make it faster", then hypothetically they might end up in a situation where those unsafe flags are set. Hypothetically.
I could be way off base there, but whatever is going on this has opcache fingerprints all over it. The fact that you are consistently seeing the same issue across many point releases in two minor version branches indicates that this is a config/environment issue. As such, the best place to start would be to conduct a thorough review of the active PHP configuration (i.e. phpinfo()), paying particularly close attention to opcache.
I feel like this is stating the obvious, but if were the case that multiple large scale foss projects had been fundamentally incompatible with new releases of PHP for the last 14+ months, someone would probably have noticed before now.
You have right, this problem is strange because I don't find it into bugs.php.net after so much long time. Thank you about the idea to check opcache, I disabled it temporary for testing but the problem was still here ...
I will continue to check my configuration but it don't seem to be related with opcache ... if someone have an idea and solved this problem on his configuration it's interest me ...
I doubt this is opcache related. PHP 7.3 added getallheaders() for the FPM SAPI and the code also tries to define this function. You mention that there is a function_exists check, which should have prevented this. Can you share what the file that containts the getallheaders() declaration looks like?
Among others, this is about <https://github.com/ralouphie/getallheaders/blob/develop/src/getallheaders.php>.
Yes exactly, the file is this one :
The condition "if (!function_exists('getallheaders'))" isn't checked and I need (same for few people over Internet too) rename the function "function getallheaders()" to "function _something_different_here_getallheaders()" to avoid the problem ...
A friend is using PHP 7.4 and he don't have this problem, but I don't know where to look because a configuration which change behavior of the function "function_exists()" is very strange.
My friend and me found the BUG :)
When the function "getallheaders" is disabled with disable_functions in php.ini, the function isn't visible by function_exists() but if we redeclare it, it's raise an error (instead a disabled function warning).
We are thinking it's really a bug because before 7.3 the behavior isn't same.
Could you check on your side please with PHP 7.3.x or 7.4.x ?
This strange behavior seem to exist since 13 years at least :
When a function is disabled, if we check this function with function_exists() it's reply "don't exist", but if we are trying to declare the function it's reply "exist already". Funny :)
"disable_functions" should throw an exception when a disabled function is called so one can handle it proper without spread *slow and expensive* function exists into the codebase - try/catch is much faster in cases where it don't throw
such compat layers defining a function which is part of a newer php release should go into a include file because code like below would be completly optimized out by opcache given the constant nature known at "compile time"
if(PHP_VERSION_ID < 70300)
that would also work better if you don't want a seperated include file which could be thrown away all togehter after deciding no longer support anything below PHP 7.3
on newer php versions this would also optimized out completly and avoid the issue of that bugreport as well as the terrible runtime overhead of function_exists()
if(PHP_VERSION_ID < 70300))
This is a pretty interesting case. I'm not sure what the correct behavior for this is.
Should we be allowing redefinition of disabled functions? Might be rather problematic technically.
Things would be a lot clearer here if disabled functions were simply completely removed, rather than replaced with a dummy implementation.
It seems to me that function_exists() should return true, even if
the function is disabled.
> It seems to me that function_exists() should return true,
> even if the function is disabled
only if you provide a dedicated function or trow exceptions when disabled functions are called because otherwise you can't write any code which handles the situation correctly
The following pull request has been associated:
Patch Name: Completely remove disabled functions
On GitHub: https://github.com/php/php-src/pull/5473
Fixed in PHP 8 by https://github.com/php/php-src/commit/53eee290b6f5ca531aef19885a392c939013ce36. It will now be possible to redefine disabled functions.