来自类的短代码处理程序的PHP错误


13

目前,我正在使用以下通用流程为插件添加简码。

class MyPlugin {

    private $myvar;

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

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

现在,当调用此类及其方法时,出现以下错误。

致命错误:不在对象上下文中时使用$ this ...

(行号是我在上打印的位置$this->myvar

这是Wordpress的问题,还是我做错了什么?这似乎很简单。


脱离话题 -发挥作用static
kaiser 2012年

Answers:


31

如错误所示,您需要使用该类的实例$this。至少有三种可能性:

使一切静止

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的人...那是无价的信息,因为wordpress.org在其add_shortcode文档页面上没有透露太多信息。我已经想出了解决方案,但由于您已将其排除在外,并且您有更好的解决方案,所以我将此问题标记为已解决:)
xmaestro 2012年

我真的很抱歉挖这个老问题,但你能plase阐述这一行做了什么:NULL === self::$instance and self::$instance = new self;?我有点困惑,因为===and被使用了,但是if如果您不明白我的意思,那就不用了。
2015年

@Sven这是防止再次发生的检查。它使该类成为Singleton……如今,我不会这样做。我将重写此答案。
fuxia

感谢那!我认为我现在走在正确的轨道上,尽管使用WordPress和OOP可以使它变得多么复杂是令人惊讶的;-)
Sven

2
@Sven WordPress核心尽可能多地编写为反OOP。即使是新代码,也忽略了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

除非确定应该静态调用该类,否则请确保在使用该类之前先创建该类的实例。静态调用方法时,不使用任何实例,因此它无权访问任何成员变量或方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.