Фатальные ошибки class-wp-widget.php в WordPress 6.0 при использовании PHP 8.1.6
Файл /wp-includes/class-wp-widget.php выдает ошибку для одного блога, но не для другого, и оба имеют одну и ту же версию class-wp-widget.php, что кажется мне нелогичным.
PHP Fatal error: Uncaught ArgumentCountError: Слишком мало аргументов для функции WP_Widget::__construct(), передано 0 в /home/www/stackexchange.com/wp-includes/class-wp-widget-factory.php в строке 61, ожидается как минимум 2 в /home/www/stackexchange.com/wp-includes/class-wp-widget.php:162
Читая код, похоже, что class-wp-widget.php является источником проблемы, но я могу ошибаться.
Мой другой (работающий) блог на том же сервере имеет этот же файл, и я не получаю ошибку.
Вы можете увидеть сломанную функцию WordPress здесь https://developer.wordpress.org/reference/classes/wp_widget/__construct/
Есть ли способ "отключить" виджеты, чтобы деактивировать этот сломанный код WordPress?
Обновление: спасибо @bosco за идею, просмотр трассировки стека помог...
Stack trace:
#0 /home/www/example.com/wp-includes/class-wp-widget-factory.php(61): WP_Widget->__construct()
#1 /home/www/example.com/wp-includes/widgets.php(115): WP_Widget_Factory->register()
#2 /home/www/example.com/wp-content/themes/theme1516/includes/register-widgets.php(22): register_widget()
#3 /home/www/example.com/wp-includes/class-wp-hook.php(307): load_my_widgets()
#4 /home/www/example.com/wp-includes/class-wp-hook.php(331): WP_Hook->apply_filters()
#5 /home/www/example.com/wp-includes/plugin.php(476): WP_Hook->do_action()
#6 /home/www/example.com/wp-includes/widgets.php(1854)
Поскольку "register-widgets.php" является единственным некорневым кодом здесь, и поскольку я предполагаю, что комментарий @bosco верен, я закомментировал старые виджеты, и это по крайней мере убрало "белый экран смерти", хотя главная страница выглядит криво, вероятно, просто скопирую HTML с сайта на PHP 7.x.
Если вы не можете откатиться на PHP версии ниже 8.1 или исправить регистрацию виджета (и вы доверяете своей теме, которой более 10 лет), вы можете обновить строку 61 в файле wp-includes/class-wp-widget-factory.php
следующим образом:
$this->widgets[ $widget ] = new $widget( $widget, $widget );
Это может исправить проблему с регистрацией виджета.

Это была именно моя проблема, и это изменение кода решило её для меня. Огромное спасибо!

Это невероятно! После этого небольшого изменения я смог запустить WordPress и затем легко отключить проблемный плагин. После этого я вернул код обратно к стандартному коду WordPress ($this->widgets[ $widget ] = new $widget()
), и сайт всё ещё работает. Огромное спасибо!

Я подозреваю, что причина в неправильно созданном пользовательском виджете. Взгляните на этот пример из Codex:
class My_Widget extends WP_Widget {
/**
* Настраивает название виджета и прочее
*/
public function __construct() {
$widget_ops = array(
'classname' => 'my_widget',
'description' => 'Мой виджет просто великолепен',
);
parent::__construct( 'my_widget', 'Мой Виджет', $widget_ops );
}
Многие плохо написанные плагины делают так:
class My_Widget extends WP_Widget {
/**
* Настраивает название виджета и прочее
*/
public function __construct() {
parent::__construct();
}
Или вообще не включают метод __construct
! Отсутствие параметров или конструктора — это неправильно. В более ранних версиях PHP эти значения могли заменяться на null
или undefined
, разрешаясь в ''
, но я бы ожидал, что эта проблема проявится ещё до обновления до 8.1, и она определённо должна была появиться в логах ошибок как уведомление.
Поэтому определите, какой именно плагин или тема вызывает эту проблему — с помощью трассировки стека, метода исключения или даже поиска по кодовой базе с помощью специальных инструментов.
Если проблема в коде, который вы поддерживаете (например, в кастомной теме или плагине), вы можете её решить, правильно реализовав Widget API, как указано в Codex и руководствах DevHub. В частности, нужно передать первые два параметра.
Если вы не хотите исправлять виджеты, вы также можете полностью удалить их с вашего сайта.
А пока временно понизьте версию PHP до 8.0. И 8.0, и 8.1 — это поддерживаемые версии PHP, которые получают обновления. WordPress ещё не имеет официальной поддержки 8.0, а 8.1 — это очень свежий релиз (начало 2022 года), поэтому неудивительно, что при обновлении вы столкнулись с проблемами совместимости и конфликтами со сторонним кодом.

Хотя я ценю усилия, этот ответ похож на другие ответы, которые я нашел в Google. В моем конкретном случае я не использую виджеты, они просто были включены в тему как дополнительные элементы, и у меня нет желания исправлять дюжину старых виджетов 10-летней давности. Что касается PHP 8.x, у меня есть два тестовых блога, которые отлично работают на Arch, кстати ;-)

использовали вы виджеты или нет — не имеет отношения к проблеме (я запускаю свой сайт на 8.0). Если вы не собираетесь использовать виджеты и не хотите их исправлять, то вам следует их удалить. Проблема не в WordPress, а в стороннем коде, который некорректно использует API и вызывает ошибки.

Иначе говоря, когда ваш код, написанный с использованием библиотеки для стандарта C++ 98, не компилируется после обновления до стандарта C++ 20, это ни в коем случае не вина Комитета/Рабочей группы по C++ — вы пытаетесь использовать библиотеку, которую какой-то нерадивый разработчик написал более 20 лет назад и никогда не обновлял, на платформе, которая изначально не была предназначена для этого. WordPress придерживается раздражающе строгих принципов обратной совместимости — но критические изменения полезны для здоровья и развития любой технологии.

Тогда как в данном случае Виджет был изначально создан некорректно

Если у вас до сих пор есть эта проблема, попробуйте перейти в файл
wordpress/wp-includes/class-wp-widget-factory.php
на строку 61 и внести следующее изменение, чтобы исправить проблему без изменения другого кода:
Замените это: $this->widgets[ $widget ] = new $widget();
На это: $this->widgets[ $widget ] = new $widget( $widget, $widget );
Теперь всё должно работать как ожидается.

Конечно, это плохая идея, и вы не должны вносить это изменение, а потом просто уйти. Но когда ваш сайт не загружается, и вы даже не можете экспортировать или восстановить его, потому что интерфейс администратора недоступен, это огромная помощь.
