不推荐使用WordPress构造函数

I want to revive an old WordPress theme. This theme has some deprecated functions in it so I'm trying to resolve them.

Notice: The called constructor method for WP_Widget in Custom_Recent_Posts is deprecated since version 4.3.0! Use __construct() instead.

This tells me that the constructor method for WP_Widget is deprecated, so that must be this line:

$this->WP_Widget('Custom_Recent_Posts', 'Custom Recent Posts', $widget_ops);

But that line seems okay? I can't find what's wrong with it.

The full script is like this:

class Custom_Recent_Posts extends WP_Widget {
    function Custom_Recent_Posts() {
        $widget_ops = array('classname' => 'Custom_Recent_Posts', 'description' => 'The recent posts with thumbnails' );
        $this->WP_Widget('Custom_Recent_Posts', 'Custom Recent Posts', $widget_ops);
    }

    function widget($args, $instance) {
        extract($args, EXTR_SKIP);

        echo $before_widget;
        $items = empty($instance['items']) ? ' ' : apply_filters('widget_title', $instance['items']);

        if(!is_numeric($items))
        {
            $items = 3;
        }

        if(!empty($items))
        {
            pp_posts('recent', $items, TRUE);
        }

        echo $after_widget;
    }

    function update($new_instance, $old_instance) {
        $instance = $old_instance;
        $instance['items'] = strip_tags($new_instance['items']);

        return $instance;
    }

    function form($instance) {
        $instance = wp_parse_args( (array) $instance, array( 'items' => '') );
        $items = strip_tags($instance['items']);

?>
            <p><label for="<?php echo $this->get_field_id('items'); ?>">Items (default 3): <input class="widefat" id="<?php echo $this->get_field_id('items'); ?>" name="<?php echo $this->get_field_name('items'); ?>" type="text" value="<?php echo esc_attr($items); ?>" /></label></p>
<?php
    }
}

register_widget('Custom_Recent_Posts');

Any help would be great.


So now I have this:

class Custom_Recent_Posts extends WP_Widget {
    public function __construct() {
        $widget_ops = array('classname' => 'Custom_Recent_Posts', 'description' => 'The recent posts with thumbnails' );
        $this->WP_Widget('Custom_Recent_Posts', 'Custom Recent Posts', $widget_ops);
    }

    function widget($args, $instance) {
        extract($args, EXTR_SKIP);

        echo $before_widget;
        $items = empty($instance['items']) ? ' ' : apply_filters('widget_title', $instance['items']);

        if(!is_numeric($items))
        {
            $items = 3;
        }

        if(!empty($items))
        {
            pp_posts('recent', $items, TRUE);
        }

        echo $after_widget;
    }

    function update($new_instance, $old_instance) {
        $instance = $old_instance;
        $instance['items'] = strip_tags($new_instance['items']);

        return $instance;
    }

    function form($instance) {
        $instance = wp_parse_args( (array) $instance, array( 'items' => '') );
        $items = strip_tags($instance['items']);

?>
            <p><label for="<?php echo $this->get_field_id('items'); ?>">Items (default 3): <input class="widefat" id="<?php echo $this->get_field_id('items'); ?>" name="<?php echo $this->get_field_name('items'); ?>" type="text" value="<?php echo esc_attr($items); ?>" /></label></p>
<?php
    }
}

register_widget('Custom_Recent_Posts');

This should change to

function Custom_Recent_Posts() {
    $widget_ops = array('classname' => 'Custom_Recent_Posts', 'description' => 'The recent posts with thumbnails' );
    $this->WP_Widget('Custom_Recent_Posts', 'Custom Recent Posts', $widget_ops);
}

this

public function __construct() {
    $widget_ops = array('classname' => 'Custom_Recent_Posts', 'description' => 'The recent posts with thumbnails' );
    $this->WP_Widget('Custom_Recent_Posts', 'Custom Recent Posts', $widget_ops);
}

Read these

  1. [closed] constructor method for WP_Widget is deprecated since 4.3.0
  2. The called constructor method for WP_Widget is deprecated since version 4.3.0

In this code:

class Custom_Recent_Posts extends WP_Widget {
    function Custom_Recent_Posts() {
        $widget_ops = array('classname' => 'Custom_Recent_Posts', 'description' => 'The recent posts with thumbnails' );
        $this->WP_Widget('Custom_Recent_Posts', 'Custom Recent Posts', $widget_ops);
    }

The class is named Custom_Recent_Posts, and so is its constructor. This is a PHP 4.x style constructor, from back in the days when PHP wanted so desperately to be like Java.

When PHP 5.x came along, PHP realized it didn't need to act like Java. It was its own language, and a popular one at that. So it introduced the __construct method, which looks like PHP's other magic methods. But it kept the PHP 4.x style constructors around so it didn't break anyone's legacy code.

At version 4.3 of WordPress, they decided to adopt the new, more PHP-like __construct syntax instead of the wannabe-Java approach. That's why you're seeing the error. To fix it, you need to change two things:

  1. Your class's constructor needs to be named __construct
  2. When it calls WP_Widget's constructor, it needs to call its __construct.

The first one is easy. Just rename the Custom_Recent_Posts() function to __construct. Done. Takes like 5 seconds.

The second one is easy at first. Just change $this->WP_Widget to $this->__construct, right? Except $this->__construct refers to your class's __construct method. You need to call parent::__construct to tell PHP which class's __construct method it needs to call.

So the corrected code would be:

class Custom_Recent_Posts extends WP_Widget {
    function __construct() {
        $widget_ops = array('classname' => 'Custom_Recent_Posts', 'description' => 'The recent posts with thumbnails' );
        parent::__construct('Custom_Recent_Posts', 'Custom Recent Posts', $widget_ops);
    }

See the Widgets API sample code at the WordPress Codex.

function _deprecated_constructor does not provide full information about the affected class file path. which takes loot time when you upgrade your code (wp-content) from PHP-(lower) to PHP-(7.x.x)


you can save little time here by adding those line to core function( i know it is bad practice. but after finished upgradation you can remove this code!)

/www/wp-content/functions.php Line no:3879

  function _deprecated_constructor( $class, $version, $parent_class = '' ) {

    /**
     * Fires when a deprecated constructor is called.
     *
     * @since 4.3.0
     * @since 4.5.0 Added the `$parent_class` parameter.
     *
     * @param string $class        The class containing the deprecated constructor.
     * @param string $version      The version of WordPress that deprecated the function.
     * @param string $parent_class The parent class calling the deprecated constructor.
     */
    do_action( 'deprecated_constructor_run', $class, $version, $parent_class );

    /**
     * Filters whether to trigger an error for deprecated functions.
     *
     * `WP_DEBUG` must be true in addition to the filter evaluating to true.
     *
     * @since 4.3.0
     *
     * @param bool $trigger Whether to trigger the error for deprecated functions. Default true.
     */
    if ( WP_DEBUG && apply_filters( 'deprecated_constructor_trigger_error', true ) ) {
        if ( function_exists( '__' ) ) {
            if ( ! empty( $parent_class ) ) {
                /* translators: 1: PHP class name, 2: PHP parent class name, 3: version number, 4: __construct() method */
// addional code start here! --------------------------------------------    
                $reflector = new ReflectionClass($parent_class);
                $filepath = 'filepath :' . $reflector->getFileName();
                trigger_error( sprintf( __( 'The called constructor method for %1$s in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead. %5$s' ),$class, $parent_class, $version, '<pre>__construct()</pre>', $filepath ) );  
    // addional code end here! ---------------------
            } else {
                /* translators: 1: PHP class name, 2: version number, 3: __construct() method */
                trigger_error( sprintf( __( 'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ),
                    $class, $version, '<pre>__construct()</pre>' ) );
            }
        } else {
            if ( ! empty( $parent_class ) ) {
                trigger_error( sprintf( 'The called constructor method for %1$s in %2$s is <strong>deprecated</strong> since version %3$s! Use %4$s instead.',
                    $class, $parent_class, $version, '<pre>__construct()</pre>' ) );
            } else {
                trigger_error( sprintf( 'The called constructor method for %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.',
                    $class, $version, '<pre>__construct()</pre>' ) );
            }
        }
    }

}

By this way you can get affected filepath with Notice.