Вызовите защищенный метод извне класса в PHP - PullRequest
6 голосов
/ 11 июня 2009

У меня есть особый случай, когда мне нужно вызвать защищенный метод извне класса. Я очень хорошо разбираюсь в том, что я делаю программированием, но я не был бы полностью против этого в этом особом случае, который у меня есть. Во всех остальных случаях мне нужно продолжать запрещать доступ к внутреннему методу, и поэтому я хотел бы сохранить метод защищенным.

Какие существуют элегантные способы доступа к защищенному методу вне класса? До сих пор я нашел это .

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

Ответы [ 6 ]

5 голосов
/ 06 сентября 2011

В PHP вы можете сделать это, используя Reflections. Для вызова защищенных или закрытых методов используйте метод setAccessible () http://php.net/reflectionmethod.setaccessible (просто установите значение TRUE)

3 голосов
/ 12 июня 2009

Я думаю, что в этом случае рефакторинг, чтобы вам не требовались подобные вещи, вероятно, самый элегантный путь. Говоря, что одним из вариантов является использование __call и внутри этого анализа debug_backtrace, чтобы увидеть, какой класс вызвал метод. Затем проверьте друзей из списка

class ProtectedClass {

    // Friend list
    private $friends = array('secret' => array('FriendClass')); 

    protected function secret($arg1, $arg2) {
        // ...
    }

    public function __call($method, $args) {

        $trace = debug_backtrace();
        $class = $trace[1]['class'];
        if(in_array($class, $this->friends[$method]))
            return $this->$method($args[0], $args[1]);

        throw new Exception();
    }
}

Думаю, мне нужен душ.

1 голос
/ 11 июня 2009

Это немного глупо, но может быть вариант.

Добавление дочернего класса для доступа к вашей защищенной функции

public class Child extends Parent {
    public function protectedFunc() {
        return parent::protectedFunc();
    }
}

Затем создайте экземпляр Child вместо Parent, где вам нужно вызвать эту функцию.

0 голосов
/ 30 марта 2010

Предположим, что объявление вашего метода выглядит так:

protected function getTheFoo() {
    ...
}

protected function setTheFoo($val) {
    ...
}

Использование:

$obj->__get('the_foo');
$obj->__set('the_foo', 'myBar');

Это обходит защищенные методы и идет прямо к переменным экземпляра.

0 голосов
/ 12 июня 2009

Я бы подумал о том, что случилось с дизайном программы, если мне нужно вызвать частную функцию?

Раньше был случай, когда

  • ваш класс несет ответственность за несколько вещей (на самом деле это две или три calsses вместе) или
  • правила инкапсуляции нарушены (например, служебные функции)

Найдя любой способ обойти эти вопросы, вы нигде не приблизитесь к реальному решению.

0 голосов
/ 11 июня 2009

Я просто добавляю это, поскольку я не программировал на PHP в течение двух лет. Не могли бы вы просто добавить в класс функцию, которая вызывает защищенный метод следующим образом?

$obj->publicFunc = create_function('$arg', 'return $this->protectedFunc($arg);');

Редактировать : Я думаю, что Том прав, глядя на документацию для create_function. Похоже, область действия $ будет «неправильной», когда вы попытаетесь вызвать ее в этом примере.


Похоже, что традиционные анонимные функции поддерживаются также начиная с PHP 5.3.0 (и мое первое решение, вероятно, не будет работать), поэтому я, вероятно, вместо этого напишу так:

$obj->publicFunc = function($arg) { 
     return $this->protectedFunc($arg); 
};

Так как я думаю, что это выглядит немного чище (и ваша IDE выберет это, конечно, лучше).


Тьфу, я пытался использовать Reflection для вызова метода, но PHP тоже не позволит вам сделать это. Похоже, вам придется использовать какой-то детский класс, как предлагали другие авторы. Если вы найдете метод, который работает, разработчики, скорее всего, в будущем классифицируют его как ошибку и сломают ваш код при обновлении до следующей версии.

Я рекомендую расширить класс.

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