Почему использование $ this внутри класса в плагине Wordpress приводит к фатальной ошибке? - PullRequest
8 голосов
/ 18 февраля 2011

Я нахожусь в процессе написания плагина Wordpress, который создает страницу в административной области, а также выполняет некоторый код веб-интерфейса.

Приведенный ниже код вызывает приятную ошибку Fatal error: Using $this when not in object context.Что довольно загадочно, так как переменная вызывается внутри класса.

Возможно, я не следую предполагаемой структуре плагина Wordpress для функций и классов, но приведенный ниже концептуальный код был создан с использованием соответствующих записей при разработке плагина.в Кодексе Wordpress.

Может кто-нибудь объяснить, почему возникает ошибка, потому что когда я создаю экземпляр класса вне кодовой базы 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 ]

10 голосов
/ 18 февраля 2011

Итак, я, кажется, исправил это, вернувшись к основам и задав Google простой вопрос: «Использование классов в плагинах Wordpress». Как статья Джей Фортнер , так и статья на 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;
}
5 голосов
/ 10 февраля 2012

Это больше не так.

Не забывайте, что если вы передаете класс, вы можете передать его по ссылке, вы даже можете передать классу собственные функции, используя & $это внутри класса и продолжает изменять тот же экземпляр, это помогает не создавать заново класс каждый раз, когда вы вызываете другую часть плагина, но тот же класс.

From: 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
    }
}
4 голосов
/ 18 февраля 2011

Что вы должны сделать, это следующее:

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 выполнять метод как статический метад, но передача фактического объекта в качестве первого аргумента вызовет метод черезobject.

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

Также будет работать, если вы хотите повторно использовать объект.

1 голос
/ 18 февраля 2011

зависит от того, как вызывается класс, статически Class :: method () будет выдавать ошибки. Если это так, я думаю, вам нужно использовать self :: $ test; но могу ошибаться.

...