PHP использует __get для вызова метода? - PullRequest
1 голос
/ 07 февраля 2012

У меня есть кое-что из PHP, которое я бы хотел делегировать методам.Вроде миксин бедняков.

В основном я хотел бы следующее:

<?php

class Apprentice
{
    public function magic() {
        echo 'Abracadabra!';
    }
}

class Sourcerer // I work magic with the source
{
    private $apprentice;

    public function __construct(){
        $this->apprentice = new Apprentice();
    }

    public function __get($key) {
        if (method_exists($this->apprentice, $key)) {
            return $this->apprentice->{$key};
        }
        throw Exception("no magic left");
    }
}

$source = new Sourcerer();
$source->magic();
?>

Чтобы не бросать Fatal error: Call to undefined method Sourcerer::magic() in .../test__get.php.

Ответы [ 4 ]

9 голосов
/ 07 февраля 2012
public function __call($name, $args) {
    if (method_exists($this->apprentice, $name)) {
        return $this->apprentice->$name($args);
    }
    throw Exception("no magic left");
}

ps: используйте __call для методов, а __get - только для свойств.И да, лучше использовать call_user_func_array, в противном случае аргументы передаются в виде массива в функцию magic.

return call_user_func_array(array($this->apprentice, $name), $args);
3 голосов
/ 07 февраля 2012
  1. Чтобы вызвать метод на apprentice, вам нужно будет вызвать его так:

    return $this->apprentice->$key();
    
  2. Вы используете $source->magic(), который не вызывает метод __get. __get для доступа к переменной, как $source->magic, но $source->magic() - это вызов функции. Если вам нужен магический метод для вызовов функций, это __call.

2 голосов
/ 07 февраля 2012

Больше похоже на __call вместо __get в вашем случае:

class Sourcerer // I work magic with the source
{
    private $apprentice;

    public function __construct(){
        $this->apprentice = new Apprentice();
    }

    public function __call($name, $arguments) {
        if (method_exists($this->apprentice, $name)) {
            return call_user_func_array(array($this->apprentice, $name), $arguments);
        }
        throw Exception("no magic left");
    }
}
1 голос
/ 07 февраля 2012

Ваш звонок вместо этого будет:

$source = new Sourcerer();
$source->apprentice->magic();

Также я считаю, что магический метод __get() работает со свойствами, а не с именами методов.

Наконец, в вашем фактическом определении __get() синтаксис неверен: он должен быть throw new Exception('message');. Я бы также переместил это в предложение else, в противном случае он будет запускаться при каждом вызове независимо от того, находится ли он вне любой if / else или другой логики.

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