在 PHP 中从类外部调用私有方法和私有属性

2022-08-30 14:22:19

我想在非常罕见的特定情况下从类外部访问私有方法和变量。

我已经看到,尽管使用了内省,但这是不可能的。

具体情况是下一个:

我想有这样的东西:

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 并调用了 $demo->myMethod(),你会得到一个控制台:该控制台可以访问编写命令的第一个方法,如下所示:

> $this->myPublicMethod();

但是您无法成功运行第二个:

> $this->myPrivateMethod();

你们中是否有人有任何想法,或者是否有任何PHP库允许您执行此操作?

多谢!


答案 1

只需公开该方法即可。但是如果你想变得棘手,你可以试试这个(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);

答案 2

编辑:进行了更新,以包括带有参数的私有函数调用示例。

PHP 5.4 开始,您可以使用预定义的类将类的方法/属性绑定到甚至有权访问私有成员的 delta 函数。Closure

闭包类

例如,我们有一个带有私有变量的类,我们希望在类外部访问它:

class Foo {
    private $bar = "Foo::Bar";
    private function add_ab($a, $b) {
        return $a + $b;
    }
}

5.4 菲律宾比索

$foo = new Foo;

// Single variable example
$getFooBarCallback = function() {
    return $this->bar;
};

$getFooBar = $getFooBarCallback->bindTo($foo, 'Foo');

echo $getFooBar(); // Prints Foo::Bar

// Function call with parameters example
$getFooAddABCallback = function() {
    // As of PHP 5.6 we can use $this->fn(...func_get_args()) instead of call_user_func_array
    return call_user_func_array(array($this, 'add_ab'), func_get_args());
};

$getFooAddAB = $getFooAddABCallback->bindTo($foo, 'Foo');

echo $getFooAddAB(33, 6); // Prints 39

从 PHP 7 开始,您可以使用新方法将 obect 的任何方法/属性绑定到回调函数,即使对于私有成员也是如此:Closure::call

7 菲律宾比索

$foo = new Foo;

// Single variable example
$getFooBar = function() {
    return $this->bar;
};

echo $getFooBar->call($foo); // Prints Foo::Bar

// Function call with parameters example
$getFooAddAB = function() {
    return $this->add_ab(...func_get_args());
};

echo $getFooAddAB->call($foo, 33, 6); // Prints 39

推荐