Почему WordPress 5.5.3 c PHP 8 выдаёт 404 на каждой странице сайта?
WordPress в последней на настоящий момент версии 5.5.3 при попытке включить только что выпущенный PHP 8 выдаёт 404 ошибку. Почему?
Ответы (1 шт):
Официально 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 ) {
что устраняет проблему в PHP 8 и работает корректно во всех версиях PHP.
Резюме: не стоит полагаться на неявное приведение типов, особенно при разработке кода, который планируется использовать под PHP 8.