PHP5: обратные вызовы между объектами класса - PullRequest
2 голосов
/ 06 марта 2011

Я пытаюсь понять, как далеко я могу зайти с замыканиями / обратными вызовами в PHP5, но в настоящее время я застрял в стеклянном футляре «почему это не работает».

В следующем примере я понимаю, что использование $this в обратном вызове (особенно при изменении области действия) не будет работать, оно просто показывает, как я надеюсь использовать обратные вызовы / закрытие.

class Customer {
  public $name = '';
  public $callback = NULL;

  function __construct($name) {
    $this->name = $name;
  }
  function when_enters($callback) {
    $this->callback = $callback;
  }
  function enter_store() {
    if(is_callable($this->callback))
      call_user_func($this->callback);
  }
}

class Salesman {
  public $customer = NULL;

  function add_customer(&$customer) { 
    $this->customer =& $customer;
    $this->customer->when_enters(function() {
      $this->greet_customer();
    });
  }
  function greet_customer() {
    echo "Hello, {$this->customer->name}!";
  }
}
$salesman = new Salesman();
$customer = new Customer('John');
$salesman->add_customer(&$customer);
$customer->enter_store();

Мне удалось воспроизвести эту базовую функцию функционально, реализовав Salesman как статический класс и установив функцию обратного вызова как Salesman::greet_customer вместо $this->greet_customer().

По сути, я хочу знать ... с помощью экземпляров объектов возможна ли такая функциональность?

Ответы [ 2 ]

3 голосов
/ 06 марта 2011

В php, call_user_func может принять массив из двух элементов для вызова метода в классе.Так что если вы сделаете это:

$this->customer->when_enters(array($this,'greet_customer'));

, это будет делать то, что вы хотите.Другая альтернатива в PHP 5.3.0 или выше - использовать замыкание вместе с локальной копией $this:

$this_copy=$this;
$this->customer->when_enters(function() use ($this_copy) {
    $this_copy->greet_customer();
});
1 голос
/ 06 марта 2011

У меня есть хорошие и плохие новости.

Хорошие новости заключаются в том, что следующая основная версия PHP (5.4?) Позволит анонимным функциям быть свойствами класса и вызываться безперепрыгивая через обручи, и позволит вам ссылаться на $this, привязав функцию к определенному контексту .

Плохая новость заключается в том, что никто не знает, когдатранк PHP будет превращен в релиз.

Теперь, учитывая, что вы не можете ссылаться на $this внутри анонимной функции, то, что вы можете здесь сделать, очень ограничено.Один из вариантов - передать текущий объект в функцию:

function enter_store() {
  if(is_callable($this->callback))
    call_user_func($this->callback, $this);
}

Хотя это будет работать и позволит вам тыкать в объект из функции, вы будете ограничены методами и свойствами, помеченными public.Это может или не может быть проблемой для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...