Почему WordPress 5.5.3 c PHP 8 выдаёт 404 на каждой странице сайта?
WordPress в последней на настоящий момент версии 5.5.3 при попытке включить только что выпущенный PHP 8 выдаёт 404 ошибку. Почему?
Официально WordPress будет совместим с PHP 8, только начиная с версии 5.6, которая запланирована на 8 декабря 2020. RC-версия ядра WordPress 5.6 работает правильно с PHP 8, проблема устранена. Однако интересно разобраться, что является источником проблемы.
Для начала попробуем ответить на вопрос, а чему равно значение выражения '' < 0
(пустая строка меньше нуля)?
Первый ответ, который приходит в голову, это false
. Пустая строка приводится к нулю, идёт сравнение 0 < 0
, результат false
.
Так было всегда в PHP, и до PHP 8, результат выражения — false
. Но не в PHP 8. Здесь результат выражения — true
, и это официально объявлено. При сравнении с числовой строкой используется сравнение чисел. Но пустая строка — не числовая, и PHP 8 использует сравнение строк: '' < '0'
, и результат — true
.
Какое отношение это имеет к WordPress?
В ядре есть метод, который вызывается при каждом запросе: \WP_Query::parse_query
. В нём строки
if ( ! is_scalar( $qv['p'] ) || $qv['p'] < 0 ) {
$qv['p'] = 0;
$qv['error'] = '404';
}
В большинстве случаев $qv['p']
содержит пустую строку, что приводит к срабатыванию if
и установке ошибки 404.
В версии WordPress 5.6 строка сравнения выглядит так:
if ( ! is_scalar( $qv['p'] ) || (int) $qv['p'] < 0 ) {
$qv['p'] = 0;
$qv['error'] = '404';
}
что устраняет проблему в PHP 8 и работает корректно во всех версиях PHP.
Резюме
не стоит использовать неявное приведение типов, особенно при разработке кода, который должен работать под PHP 8.