Назовите закрытые методы и частные собственности снаружи класса в PHP

Я хочу получить доступ к закрытым методам и переменным снаружи классов в очень редких конкретных случаях.

Я видел, что это не быть возможным, хотя самоанализ используется.

Конкретный случай является следующим:

Я хотел бы иметь что-то вроде этого:

class Console
{
    final public static function run() {

        while (TRUE != FALSE) {
            echo "\n> ";
            $command = trim(fgets(STDIN));

            switch ($command) {
                case 'exit':
                case 'q':
                case 'quit':
                    echo "OK+\n";
                    return;
                default:
                    ob_start();
                    eval($command);
                    $out = ob_get_contents();
                    ob_end_clean();

                    print("Command: $command");
                    print("Output:\n$out");         

                    break;
            }
        }
    }
}

Этот метод должен смочь быть введенным в коде как это:

Class Demo
{
    private $a;

    final public function myMethod()
    {
        // some code
        Console::run();
        // some other code
    }

    final public function myPublicMethod()
    {
        return "I can run through eval()";
    }

    private function myPrivateMethod()
    {
        return "I cannot run through eval()";
    }
}

(это - всего одно упрощение. реальный идет через сокет, и реализуйте набор большего количества вещей...),

Так...

Если Вы инстанцируете класса Демонстрация, и Вы называете $demo-> myMethod (), то Вы получите консоль: та консоль может получить доступ к первому методу, пишущий команду как:

> $this->myPublicMethod();

Но Вы не можете выполнить успешно второй:

> $this->myPrivateMethod();

У какого-либо из Вас есть какая-либо идея, или если существует какая-либо библиотека для PHP, который позволяет Вам делать это?

Большое спасибо!

16
задан Pablo López Torres 29 April 2010 в 15:39
поделиться

3 ответа

Просто сделайте метод общедоступным. Но если вы хотите усложнить ситуацию, вы можете попробовать это (PHP 5.3):

class LockedGate
{
    private function open()
    {
        return 'how did you get in here?!!';
    }
}

$object = new LockedGate();
$reflector = new ReflectionObject($object);
$method = $reflector->getMethod('open');
$method->setAccessible(true);
echo $method->invoke($object);
57
ответ дан 30 November 2019 в 15:05
поделиться

Первый вопрос, который вы должны задать: если вам нужно получить к нему доступ извне класса, почему вы объявили его закрытым? Если это не ваш код, то у создателя, вероятно, была веская причина объявить его закрытым, и доступ к нему напрямую является очень плохой (и в значительной степени неподдерживаемой) практикой.

РЕДАКТИРОВАТЬ : Как указывает Адам В. в комментариях, вам необходимо сделать закрытый метод доступным перед его вызовом. Образец кода обновлен, чтобы включить это. Я не тестировал его - просто добавляю сюда, чтобы держать ответ в актуальном состоянии.

Как уже было сказано, вы можете использовать Reflection , чтобы выполнить это. Создайте экземпляр ReflectionClass , вызовите getMethod для метода, который вы хотите вызвать, а затем вызовите invoke для возвращенного ReflectionMethod .

Пример кода (хотя я его не тестировал, поэтому могут быть ошибки) может выглядеть как

$demo = new Demo();
$reflection_class = new ReflectionClass("Demo");
$reflection_method = $reflection_class->getMethod("myPrivateMethod");
$reflection_method->setAccessible(true);
$result = $reflection_method->invoke($demo, NULL);
4
ответ дан 30 November 2019 в 15:05
поделиться

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

private function _myPrivateMethod()

Тогда я просто делаю функцию общедоступной.

public function _myPrivateMethod()

Таким образом, хотя функция является общедоступной, соглашение об именах уведомляет о том, что в то время как общедоступная функция является частной и ее не следует использовать.

2
ответ дан 30 November 2019 в 15:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: