Errores fatales en class-wp-widget.php de WordPress 6.0 en PHP 8.1.6

31 may 2022, 02:05:12
Vistas: 21.9K
Votos: 5

/wp-includes/class-wp-widget.php me da un error en un blog, pero no en el otro, y ambos tienen la misma versión de class-wp-widget.php, lo cual no tiene sentido para mí.

PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function WP_Widget::__construct(), 0 passed in /home/www/stackexchange.com/wp-includes/class-wp-widget-factory.php on line 61 and at least 2 expected in /home/www/stackexchange.com/wp-includes/class-wp-widget.php:162

Leyendo el código, parece que class-wp-widget.php es la raíz del problema, pero podría estar equivocado.

Mi otro blog (que funciona) en el mismo servidor tiene este mismo archivo y no obtengo el error.

Puedes ver la función de WordPress rota aquí https://developer.wordpress.org/reference/classes/wp_widget/__construct/

¿Hay alguna manera de "desactivar" los widgets para desactivar este código de WordPress roto?

Actualización: gracias @bosco por la idea, mirando el Stack trace ayudó...

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)

Dado que "register-widgets.php" es el único código no principal aquí, y porque asumo que el comentario de @bosco es correcto, comenté los widgets antiguos y eso al menos eliminó la "pantalla blanca de la muerte". Mientras tanto la página de inicio se ve extraña, probablemente solo copiaré y pegaré el HTML del sitio con PHP 7.x.

8
Comentarios

Si fuera un problema de compatibilidad con PHP 8.1, apostaría a que estarías viendo un aviso de desaprobación en su lugar - según Make: "Todos los problemas conocidos restantes de PHP 8.1 son avisos de desaprobación.". Lo más probable es que este error sea producto de un plugin o tema que utiliza un método de registro de Widgets obsoleto desde hace tiempo - que la pila de llamadas en el error no mencione una extensión no significa que el error no haya sido causado por una. El método tradicional de solución de problemas de desactivar/activar uno por uno podría ayudar a identificar al culpable

bosco bosco
31 may 2022 02:47:03

Al leer el código yo mismo, parece que probablemente una extensión está pasando algo a register_widget() que no anula correctamente el constructor WP_Widget.

bosco bosco
31 may 2022 02:59:08

Yo esperaría antes de actualizar a PHP 8.1, aunque WordPress funciona en PHP 8.0 todavía no lo soporta oficialmente, y muchos plugins y temas no han sido probados o funcionan en 8.0. 8.1 es aún más nuevo, y muchas de las herramientas no se han actualizado para ejecutarse en él todavía. Al menos durante unos meses más deberías considerar 8.1 como tecnología de vanguardia. Siempre que estés en una versión de PHP que todavía esté dentro de su ventana de soporte, estarás bien por ahora

Tom J Nowell Tom J Nowell
31 may 2022 03:00:19

De lo contrario, Bosco probablemente tenga razón, desactiva todos los plugins y actívalos uno por uno, y luego revisa ese plugin en busca de sus llamadas de registro de widgets. Un stack trace habría señalado directamente el plugin relevante. El error que compartiste solo indica que está relacionado con Widgets, lo más probable es que un widget personalizado esté intentando llamar al constructor padre pero no está pasando ningún argumento, como esto: parent::__construct() cuando debería ser así: parent::__construct( 'my_widget', 'My Widget' );

Tom J Nowell Tom J Nowell
31 may 2022 03:02:27

OK @bosco voy a intentarlo de nuevo, encontré algunas llamadas antiguas a register_widget en un tema antiguo, tal vez pueda comentarlas.

Jay Brunet Jay Brunet
31 may 2022 03:10:10

@PJBrunet deberías publicar tu solución como una solución, no como una edición, el sitio nunca verá que resolviste tu problema y seguirá mostrándolo para intentar obtener una respuesta.

Tom J Nowell Tom J Nowell
31 may 2022 03:54:09

@TomJNowell Sí, lo consideré. No soy nuevo aquí LOL. No estoy convencido de que el problema esté resuelto. Un tema antiguo que ha funcionado durante más de 10 años hasta PHP 7.x no debería hacer que WordPress colapse con una pantalla blanca de la muerte. Sería aún mejor algún tipo de asistente de migración de temas/plugins para PHP 8.x. Llevo 20 años programando en PHP y no tengo ningún interés en aprender los widgets de WordPress. En mi opinión experta, fueron una mala idea desde el principio, y mira, nunca realmente despegaron. Eso, y el POO ha sido objeto de bromas durante años, nadie quiere arreglar los errores de constructores en PHP tampoco.

Jay Brunet Jay Brunet
31 may 2022 04:20:53

No confío en temas que no reciben actualizaciones regulares - nunca confiaría en un tema escrito para compatibilidad con un núcleo de WordPress que tiene más de 10 años y que no ha sido tocado desde entonces. No hay razón para que WordPress deba soportar el código de los widgets en tu tema ya que nunca fueron implementados correctamente desde el principio. Sería mejor encontrar un tema nuevo completamente, ya que este problema bien podría ser indicativo de más abusos de API/características mal codificadas, y dado que nunca ha sido actualizado, muy probablemente un número de vulnerabilidades de seguridad.

bosco bosco
31 may 2022 22:44:03
Mostrar los 3 comentarios restantes
Todas las respuestas a la pregunta 3
4
16

En caso de que no puedas revertir a una versión de PHP anterior a la 8.1 o solucionar el registro del widget (y confías en tu tema de más de 10 años), puedes actualizar la línea 61 del archivo wp-includes/class-wp-widget-factory.php de esta manera:

$this->widgets[ $widget ] = new $widget( $widget, $widget );

Esto podría solucionar el problema de registro del widget.

31 ago 2022 11:25:52
Comentarios

Este era exactamente mi problema también y este cambio de código lo resolvió para mí. ¡Muchas gracias por esto!

SqlRyan SqlRyan
6 feb 2023 18:09:25

Gracias. Eso me salvó el día.

recantha recantha
16 may 2023 22:28:50

¡Eso fue increíble! Después de hacer ese pequeño cambio pude iniciar WordPress y luego desactivar fácilmente el plugin problemático. Luego pude cambiar el código de nuevo al código predeterminado de WordPress ($this->widgets[ $widget ] = new $widget()), y el sitio web sigue funcionando. ¡Muchísimas gracias!

Jesper Jesper
29 jul 2023 19:35:31

Recordatorio amistoso de que modificar el núcleo nunca es una buena idea. Haces una actualización y puf, hay que volver a hacerlo.

Fredy31 Fredy31
17 ago 2023 22:38:56
5

Sospecho que la causa es un widget personalizado que ha sido construido incorrectamente. Mira este ejemplo del Codex:

class My_Widget extends WP_Widget {

    /**
     * Configura el nombre del widget, etc.
     */
    public function __construct() {
        $widget_ops = array( 
            'classname' => 'my_widget',
            'description' => 'Mi Widget es increíble',
        );
        parent::__construct( 'my_widget', 'Mi Widget', $widget_ops );
    }

Lo que hacen muchos plugins mal construidos es esto:

class My_Widget extends WP_Widget {

    /**
     * Configura el nombre del widget, etc.
     */
    public function __construct() {
        parent::__construct();
    }

¡O incluso no incluyen un método __construct en absoluto! No pasar parámetros o no tener un constructor es incorrecto. Versiones anteriores de PHP pueden haber sustituido estos valores por null o undefined, resolviendo a '', pero aún así habría esperado que esto se convirtiera en un problema antes de actualizar a 8.1, y ciertamente habría aparecido en el registro de errores como un aviso.

Así que identifica qué plugin o tema es responsable de esto, ya sea con trazas de pila, un proceso de eliminación, o incluso haciendo una búsqueda en el código base con una herramienta.

Si esto está en código que mantienes, como un tema o plugin personalizado, puedes resolver el problema implementando correctamente la API de Widgets como indican el Codex y los manuales de DevHub. Específicamente, proporcionando los dos primeros parámetros.

Si no estás interesado en arreglar los widgets, también puedes eliminarlos completamente de tu sitio.


Mientras tanto, vuelve a la versión 8.0 por un tiempo. Tanto 8.0 como 8.1 son versiones soportadas actualmente de PHP y están recibiendo actualizaciones. WordPress aún no ha construido soporte oficial para 8.0, y 8.1 es una versión muy reciente (principios de 2022), así que no es sorprendente que hayas encontrado problemas de compatibilidad y choques con código de terceros al actualizar.

31 may 2022 03:10:03
Comentarios

Aunque agradezco el esfuerzo, esta respuesta se parece a otras que encontré en Google. En mi caso particular, no estoy usando los widgets, solo se incluyeron como extras en el tema, y no tengo ningún deseo de arreglar una docena de widgets antiguos de hace más de 10 años. En cuanto a PHP 8.x, tengo dos blogs de prueba funcionando bien en Arch, por cierto ;-)

Jay Brunet Jay Brunet
31 may 2022 03:42:31

si usaste o no los widgets es irrelevante para el problema (yo ejecuto mi propio sitio en 8.0). Si no tienes intención de usar los widgets y no quieres arreglarlos, entonces deberías eliminarlos. El problema no es WordPress, es código de terceros que hace un uso incorrecto de la API generando errores.

Tom J Nowell Tom J Nowell
31 may 2022 03:52:04

Para decirlo de otra manera, cuando tu código escrito para depender de una biblioteca hecha para el estándar C++ 98 no compila al actualizar tu código al estándar C++ 20, no es en absoluto culpa del Comité/Grupo de Trabajo de C++ - estás intentando usar una biblioteca que alguien escribió hace más de 20 años y nunca actualizó en una plataforma que nunca fue construida para facilitarlo. WordPress tiene una convicción molesta cuando se trata de compatibilidad con versiones anteriores - pero los cambios disruptivos son buenos para la salud y el desarrollo de cualquier tecnología.

bosco bosco
31 may 2022 22:31:46

Mientras que en este caso el Widget fue construido incorrectamente desde el primer día

Tom J Nowell Tom J Nowell
31 may 2022 22:34:19

@TomJNowell Estas cosas pasan, pero PHP 8.x parece ser más estricto que versiones anteriores. Encontré otros errores fatales, pero afortunadamente fueron corregidos en WP 6.

Jay Brunet Jay Brunet
2 jun 2022 01:33:23
3

Para cualquiera que aún tenga este problema, puedes intentar ir a wordpress/wp-includes/class-wp-widget-factory.php en la línea 61 y hacer este cambio para solucionar el problema sin modificar ningún otro código:

Cambia esto: $this->widgets[ $widget ] = new $widget();

Por esto: $this->widgets[ $widget ] = new $widget( $widget, $widget );

Ahora todo debería funcionar como se espera.

19 ene 2023 21:54:43
Comentarios

No, no edites nunca los archivos núcleo.

vancoder vancoder
20 ene 2023 00:40:26

Sin duda es una mala idea y no deberías hacer este cambio y luego simplemente irte, pero cuando tu sitio no carga y ni siquiera puedes exportarlo o recuperarlo porque la interfaz de administración no está disponible, esto es de gran ayuda.

SqlRyan SqlRyan
6 feb 2023 18:16:57

en la actualización de Wordpress de marzo 2023 (6.2) todavía hay una incompatibilidad con la versión PHP 8.1 que todavía debe resolverse de esta manera... :/ (sí, este archivo se sobrescribe después de cada actualización)

hello_earth hello_earth
10 abr 2023 16:55:50