クラスのショートコードハンドラーでのPHPエラー


13

現在、プラグインのショートコードを追加するために次の一般的なフローを使用しています。

class MyPlugin {

    private $myvar;

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

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

このクラスとそのメソッドが呼び出されると、次のエラーが発生します。

致命的なエラー:...のオブジェクトコンテキストにないときに$ thisを使用する

(行番号は、私が印刷した場所です$this->myvar

これはWordpressの終わりの問題ですか、私が間違っていることはありますか?それは本当にシンプルなもののようです。


off topic-関数を作成しますstatic
カイザー

回答:


31

エラーが示すように、使用するクラスのインスタンスが必要$thisです。少なくとも3つの可能性があります。

すべてを静的にする

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' ) );

しかし、それはもはや本当のOOPではなく、単なる名前空間です。

最初に実際のオブジェクトを作成します

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' ) );

これは…機能します。しかし、誰かがショートコードを置き換えたい場合、いくつかのあいまいな問題に遭遇します。

そのため、クラスインスタンスを提供するメソッドを追加します。

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' ] );

さて、誰かがオブジェクトのインスタンスを取得したいときは、次のように書くだけです:

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

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

古いソリューション:クラスにオブジェクトを作成します

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' ) );

thanx man ...それは、wordpress.orgがadd_shortcodeのドキュメントページであまり語っていないため、貴重な情報です。私は解決策を見つけましたが、あなたはそれを悪い習慣として除外し、あなたはより良い解決策を持っているので、この問題を解決済みとしてマークします:)
xmaestro

この古い質問を掘り下げて本当に申し訳ありませんが、この行が何をするのか詳しく説明していただけNULL === self::$instance and self::$instance = new self;ますか?===andが使用されているため、少し混乱していifますが、意味がわからない場合は、なしで使用してください。
スベン

@Svenこれは、2番目のインスタンスを防ぐためのチェックです。このクラスはシングルトンになります…最近はそうしません。この答えを書き直します。
FUXIA

それをありがとう!私はそれはそれはWordPress&OOP ;-)使用することができますどのように複雑な驚くべきことであるが、今私は、正しい軌道に乗ってと思う
スヴェン

2
@Sven WordPressコアは、可能な限りアンチOOPとして作成されています。新しいコードでさえ、たとえば依存関係の注入など、過去10年間にPHPの世界が学んだことをすべて無視します。そのため、はい、WordPressプラグインとテーマのOOPは常にハックです。:/
fuxia

7

このように、クラス内でショートコードを使用できます

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();

別のクラスのショートコードコンテンツにアクセスする場合。このようにすることができます。

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
私はこのソリューションが本当に好きです。本当にきれいで理解しやすいです。私のReact.js開発者側はこれに満足しています。
AaronDancer

1

静的に呼び出されることが確実でない限り、使用する前にクラスのインスタンスを作成してください。メソッドを静的に呼び出す場合、インスタンスを使用しないため、メンバー変数またはメソッドにアクセスできません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.