Opened 2 years ago
Closed 2 years ago
#56010 closed defect (bug) (fixed)
apache_mod_loaded returns fatal TypeError in some environments with PHP 8
Reported by: | engahmeds3ed | Owned by: | SergeyBiryukov |
---|---|---|---|
Milestone: | 6.1 | Priority: | normal |
Severity: | major | Version: | |
Component: | General | Keywords: | php8 has-patch commit |
Focuses: | Cc: |
Description
When we call WP Core function (apache_mod_loaded) in environment like WP Engine which has the PHP function (apache_get_modules) already disabled also with php 8 or above will lead to the following fatal error:
PHP Fatal error: Uncaught TypeError: in_array(): Argument #2 ($haystack) must be of type array, null given in /<redacted>/wp-includes/functions.php:5834\nStack trace: #0 /<redacted>/wp-includes/functions.php(5834): in_array('mod_pagespeed', NULL, true) #1 /<redacted>/wp-content/plugins/wp-rocket/inc/ThirdParty/Plugins/ModPagespeed.php(52): apache_mod_loaded('mod_pagespeed', false)
and this is happening because of the following code:
https://github.com/WordPress/WordPress/blob/master/wp-includes/functions.php#L5890
Here we get the return value from (apache_get_modules) which is this cases returns null because it's already disabled by the hosting company then pass this null as a second argument to the in_array function which expects an array.
Before PHP 8, we may see only notice in logs but after PHP 8 we get fatal error which blocks the site completely.
Possible solutions:-
- Cast the value passed to (in_array) to be array (but this will return not valid values in such mentioned environments)
- Add the following condition along with the check if the function exists or not like this
<?php if ( function_exists( 'apache_get_modules' ) && false === strpos( ini_get( 'disable_functions' ), 'apache_get_modules' ) ) {
to make sure that this function isn't in the disabled functions.
Whatever solution we will take, I can work on it.
Thanks
Attachments (1)
Change History (8)
#3
@
2 years ago
- Keywords has-patch added
- Milestone changed from Awaiting Review to 6.1
Hi there, welcome to WordPress Trac! Thanks for the report.
I think ensuring that $mods
is an array might make sense in theory. However, an array is the documented return value for apache_get_modules()
. Unless I'm missing something, the only way to get that fatal error is to redeclare the disabled function (which is possible in PHP 8.0+) and return null
instead of an array, which seems like a wrong thing to do on the host's part, an empty array should be returned instead.
If the function is simply disabled and not redeclared, the function_exists()
check should return false
, though that may not always be the case, see comment:10:ticket:55711.
Based on comment:2, it looks like this was corrected and the host made adjustments to return an empty array. In that case, I think we can use the existing phpinfo()
fallback, see 56010.diff.
#4
@
2 years ago
Amazing as usual!
You are totally right, returning null was the host's problem and this shouldn't be the case we rely on in CORE.
falling back to the phpinfo solution will fix the issue and return the real expected value.
Thanks
Today when I tried again in WP Engine I found that (apache_get_modules) returns empty array, so we will not have this fatal error in WP Engine but still returns not accurate results as it always returns empty array, which means no apache module is installed and activated which isn't correct.