Почему WordPress 5.5.3 c PHP 8 выдаёт 404 на каждой странице сайта?

WordPress 5.5.3 при попытке включить только что выпущенный PHP 8 выдаёт 404 ошибку. Почему?

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

Оставьте комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.