Почему 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 ) {

что устраняет проблему в PHP 8 и работает корректно во всех версиях PHP.

Резюме: не стоит использовать неявное приведение типов, особенно при разработке кода, который должен работать под PHP 8.

Источник: KAGG Design

Игорь Гергель

Единственный обладатель значков золотой WordPress и бронзовый WooCommerce на StackOverflow RU. WordPress Core contributor. Работал ведущим девелопером в команде WPML.

%d такие блоггеры, как: