Why does using $ this inside a class in a Wordpress plugin cause a fatal error?

I am in the process of writing a Wordpress plugin that creates a page in the admin area and also executes some external code.

A good error appears in the code below Fatal error: Using $this when not in object context . Which is quite mystifying, since the variable is called inside the class.

Perhaps I do not follow the intended structure of the Wordpress plugin for functions and classes, but the conceptual code below was created using the appropriate plugin development records in Wordpress Codex.

Can someone explain why the error occurs, because when I create an instance of the class outside of Wordpress code, everything is fine.

 if (!class_exists("MyClass")) { class MyClass { var $test = 'Test variable'; public function index() { //Index code } public function add() { echo $this->test; } } } add_action('admin_menu', 'my_plugin_menu'); function my_plugin_menu() { add_menu_page('My Plugin', 'My Plugin', 'manage_options', 'my-plugin', array('MyClass', 'index')); add_submenu_page('my-plugin', 'Add New Thing', 'Add New', 'manage_options', 'my-plugin-add', array('MyClass', 'add')); } 
+7
source share
4 answers

So, I seem to have fixed this by going back to the basics and asking Google the modest question: "Using classes in Wordpress plugins."

Both the Jay Fortner article and one of dConstructing.com were helpful.

Basically, now I call add_menu_page and add_submenu_page from the class. I was impressed that these functions somehow created the object, but they obviously do not.

Now my code looks something like this, and I can call the declared class variable without errors:

 if (!class_exists("MyClass")) { class MyClass { var $test = 'Test variable'; function __construct() { add_action('admin_menu', 'my_plugin_menu'); } function my_plugin_menu() { add_menu_page('My Plugin', 'My Plugin', 'manage_options', 'my-plugin', array(&$this, 'index')); add_submenu_page('my-plugin', 'Add New Thing', 'Add New', 'manage_options', 'my-plugin-add', array(&$this, 'add')); } public function index() { //Index code } public function add() { echo $this->test; } } new MyClass; } 
+9
source

What you need to do is the following:

 function my_plugin_menu() { add_menu_page('My Plugin', 'My Plugin', 'manage_options', 'my-plugin', array(new MyClass, 'index')); add_submenu_page('my-plugin', 'Add New Thing', 'Add New', 'manage_options', 'my-plugin-add', array('MyClass', 'add')); } 

Using array('MyClass', 'index') forces php to execute the method as static methed, but passing the actual object as the first argument will call the method through the object.

 function my_plugin_menu() { $Class = new MyClass(); add_menu_page( 'My Plugin', 'My Plugin', 'manage_options', 'my-plugin', array($Class, 'index') ); } 

Will also work if you want to reuse an object.

+4
source

This is no longer the case.

Do not forget that if you go through the class, you can pass its link, you can even go through the classes of your own functions using & $ this inside the class and continue to change the same instance, this helps you do not need to recreate the class every time you call another part of the plugin, but the same class.

From: https://codex.wordpress.org/Function_Reference/do_action_ref_array

As with PHP 5.4, the array is no longer passed by reference, despite the function name. You can’t even use the reference sign '&' because the time of calling the link now throws an error. What you can do is pass the reference as an element of the array. This requires all callbacks added to the action, expect a link pointer. This is not what you see in WordPress actions. This method is provided for informational purposes only.

 $Class = new MyClass(); add_menu_page( 'My Plugin', 'My Plugin', 'manage_options', 'my-plugin', array(&$Class, 'index') 

or

 $myClass= new MyClass ; add_action('admin_menu', array( $myClass, 'admin_menu' ) ); class MyClass { public function admin_menu() { add_menu_page('MyMenu', 'MyMenu', 'read', 'mymenu', array( $this, 'action' )); } public function action() { //Do something here } } 
+4
source

depends on how the class is called, the static method Class :: method () will cause errors. If so, I think you need to use self :: $ test; but may be wrong.

+1
source

All Articles