Lỗi PHP với trình xử lý shortcode từ một lớp


13

Hiện tại tôi đang sử dụng luồng chung sau đây để thêm shortcode cho plugin.

class MyPlugin {

    private $myvar;

    function baztag_func() {
        print $this->myvar;            
    }
}

add_shortcode( 'baztag', array('MyPlugin', 'baztag_func') );

Bây giờ khi lớp này và phương thức của nó được gọi, tôi gặp lỗi sau.

Lỗi nghiêm trọng: Sử dụng $ this khi không ở trong bối cảnh đối tượng trong ...

(Dòng không là nơi tôi đã in $this->myvar)

Đây có phải là vấn đề ở phần cuối của Wordpress hay có điều gì đó tôi đang làm sai? Nó có vẻ là một cái gì đó thực sự đơn giản.


lạc đề - làm cho chức năng static.
kaiser

Câu trả lời:


31

Như lỗi nói rằng bạn cần một thể hiện của lớp để sử dụng $this. Có ít nhất ba khả năng:

Làm cho mọi thứ tĩnh

class My_Plugin
{
    private static $var = 'foo';

    static function foo()
    {
        return self::$var; // never echo or print in a shortcode!
    }
}
add_shortcode( 'baztag', array( 'My_Plugin', 'foo' ) );

Nhưng đó không phải là OOP thực sự nữa, chỉ là không gian tên.

Tạo một đối tượng thực sự đầu tiên

class My_Plugin
{
    private $var = 'foo';

    public function foo()
    {
        return $this->var; // never echo or print in a shortcode!
    }
}

$My_Plugin = new My_Plugin;

add_shortcode( 'baztag', array( $My_Plugin, 'foo' ) );

Những công việc này. Nhưng bạn gặp phải một số vấn đề mơ hồ nếu có ai muốn thay thế shortcode.

Vì vậy, thêm một phương thức để cung cấp thể hiện của lớp:

final class My_Plugin
{
    private $var = 'foo';

    public function __construct()
    {
        add_filter( 'get_my_plugin_instance', [ $this, 'get_instance' ] );
    }

    public function get_instance()
    {
        return $this; // return the object
    }

    public function foo()
    {
        return $this->var; // never echo or print in a shortcode!
    }
}

add_shortcode( 'baztag', [ new My_Plugin, 'foo' ] );

Bây giờ, khi ai đó muốn lấy đối tượng, họ chỉ cần viết:

$shortcode_handler = apply_filters( 'get_my_plugin_instance', NULL );

if ( is_a( $shortcode_handler, 'My_Plugin ' ) )
{
    // do something with that instance.
}

Giải pháp cũ: tạo đối tượng trong lớp của bạn

class My_Plugin
{
    private $var = 'foo';

    protected static $instance = NULL;

    public static function get_instance()
    {
        // create an object
        NULL === self::$instance and self::$instance = new self;

        return self::$instance; // return the object
    }

    public function foo()
    {
        return $this->var; // never echo or print in a shortcode!
    }
}

add_shortcode( 'baztag', array( My_Plugin::get_instance(), 'foo' ) );

người đàn ông thanx ... đó là thông tin vô giá vì wordpress.org đã không nói nhiều về điều này trên trang tài liệu add_shortcode của họ. Tôi đã tìm ra giải pháp nhưng vì bạn đã loại trừ đó là một thực tiễn tồi và bạn có giải pháp tốt hơn nên tôi đánh dấu vấn đề này là đã giải quyết :)
xmaestro

Tôi thực sự xin lỗi khi đào lên câu hỏi cũ này, nhưng bạn có thể giải thích chi tiết những gì dòng này không : NULL === self::$instance and self::$instance = new self;? Tôi hơi bối rối vì ===andđược sử dụng, nhưng không if, nếu bạn hiểu ý tôi.
Sven

@Sven Đây là kiểm tra để ngăn chặn trường hợp thứ hai. Nó làm cho lớp này trở thành một Singleton Ngày nay tôi sẽ không làm điều đó. Tôi sẽ viết lại câu trả lời này.
fuxia

Cảm ơn vì điều đó! Tôi nghĩ bây giờ tôi đang đi đúng hướng, mặc dù điều đáng ngạc nhiên là nó có thể phức tạp như thế nào khi sử dụng WordPress & OOP ;-)
Sven

2
Lõi WordPress @Sven được viết khá nhiều để chống OOP càng tốt. Ngay cả mã mới cũng bỏ qua tất cả những điều mà phần còn lại của thế giới PHP đã học được trong mười năm qua, ví dụ như tiêm phụ thuộc. Vì vậy, có, OOP trong các plugin và chủ đề WordPress luôn bị hack. : /
fuxia

7

Bạn có thể sử dụng như thế này, shortcode bên trong Class

class stockData{


    function __construct() {
        add_shortcode( 'your_shortcode_name', array( $this, 'showData' ) );
        //add_action('login_enqueue_scripts', array( $this,'my_admin_head'));
    }

    function showData(){
        return '<h1>My shortcode content</h1>' ;
    }
}

$object=new stockData();

Nếu bạn muốn truy cập nội dung shortcode từ một lớp khác. Bạn có thể làm như thế này.

class my_PluginClass {

  public function __construct( $Object ) {

    $test = add_shortcode( 'your_shortcode_name', array( $Object, 'your_method_name' ) );

  }

}

class CustomHandlerClass{

  public function your_method_name( $atts, $content ) {
     return '<h1>My shortcode content</h1>' ;
  }
}

$Customobject  = new CustomHandlerClass();
$Plugin         = new my_PluginClass( $Customobject );

1
Tôi thực sự thích giải pháp này. Nó thực sự sạch sẽ và dễ hiểu. Phía nhà phát triển React.js của tôi hài lòng với điều này.
AaronDancer

1

Hãy chắc chắn rằng bạn tạo một thể hiện của lớp trước khi sử dụng nó trừ khi bạn chắc chắn rằng nó được gọi là tĩnh. Khi bạn gọi một phương thức tĩnh, bạn không sử dụng bất kỳ trường hợp nào và do đó nó không có quyền truy cập vào bất kỳ biến hoặc phương thức thành viên nào.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.