为什么在Wordpress插件中的类中使用$ this会导致致命错误?

时间:2011-02-18 11:29:15

标签: php wordpress class wordpress-plugin

我正在编写一个Wordpress插件,在管理区域创建一个页面,并执行一些前端代码。

下面的代码会引发一个很好的Fatal error: Using $this when not in object context错误。这是相当神秘的,因为变量是在类中调用的。

也许我没有按照预期的Wordpress插件结构来处理函数和类,但下面的概念代码是使用Wordpress Codex中插件开发的相关条目创建的。

有人可以解释为什么会触发错误,因为当我在Wordpress代码库之外创建一个类的实例时,一切都很好。

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

4 个答案:

答案 0 :(得分:10)

所以,我似乎已经解决了这个问题,回到基础并向Google提出了一个简单的问题:“在Wordpress插件中使用类”。

Jay Fortner上的文章和dConstructing.com上的文章都很有帮助。

基本上,我现在正在调用类中的add_menu_page和add_submenu_page。我认为这些功能以某种方式创建了一个对象,但它们显然没有。

我的代码现在看起来像这样,我可以在没有错误的情况下调用声明的类变量:

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;
}

答案 1 :(得分:5)

这不再是真的。

  

不要忘记,如果你通过课程,你可能想要通过它   参考,您甚至可以使用& $ this传递类自己的函数   在类的内部并继续修改同一个实例,这有帮助   每次调用不同的部分时都不必重新创建一个类   插件但是同一个类。

来自:https://codex.wordpress.org/Function_Reference/do_action_ref_array

  

从PHP 5.4开始,尽管如此,该数组不再通过引用传递   功能名称。你甚至不能使用参考标记'&'因为   现在通过引用传递调用时间会引发错误。你能做的是   将引用指针作为数组元素传递。这样做确实需要   所有回调都添加到操作以期望引用指针。这个   不是你将在WordPress动作中看到的东西。这种技术是   仅供参考。

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

或者

$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
    }
}

答案 2 :(得分:4)

您应该做的是以下内容:

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

使用array('MyClass', 'index')导致php以静态方式执行该方法,但是将实际对象作为第一个参数传递将通过该对象调用该方法。

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

如果您想重用该对象,也会有效。

答案 3 :(得分:1)

取决于如何调用类,静态Class :: method()将抛出错误。如果是这种情况我认为你需要使用self :: $ test;但可能是错的。