PHP error with shortcode handler from a class

Currently i am using the following generic flow for adding the shortcode for a plugin.

class MyPlugin {

    private $myvar;

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

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

Now when this class and it’s method are called i get the following error.

Read More

Fatal error: Using $this when not in object context in …

(Line no is where i have printed the $this->myvar)

Is this a problem on WordPress’s end or is there is something i’m doing wrong? It seems to be something really simple.

Related posts

Leave a Reply

3 comments

  1. As the error says you need an instance of the class to use $this. There are at least three possibilities:

    Make everything static

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

    But that’s not real OOP anymore, just namespacing.

    Create a real object first

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

    This … works. But you run into some obscure problems if anyone wants to replace the shortcode.

    So add a method to provide the class instance:

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

    Now, when someone wants to get the object instance, s/he just has to write:

    $shortcode_handler = apply_filters( 'get_my_plugin_instance', NULL );
    
    if ( is_a( $shortcode_handler, 'My_Plugin ' ) )
    {
        // do something with that instance.
    }
    

    Old solution: create the object in your class

    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' ) );
    
  2. You can use like this, shortcode inside the 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();
    

    If you want access shortcode content from another class. You can do like this.

    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 );
    
  3. Make sure that you make an instance of your class before using it unless you are sure it’s supposed to be called statically. When you call a method statically, you don’t use any instances and therefore it doesn’t have access to any member variables or methods.