PHP:扩展现有类

PHP:扩展现有类,php,oop,Php,Oop,是否可以设置类的父级?即,在运行时实例化父类的实例,然后创建扩展某个父实例的子类实例。例如: class A { var $test = 'default'; } class B extends A { public function __contsruct(A $a) { parent = $a; //does not work } } $a = new A(); $a->test = 'changed'; $b = new B($a); $b

是否可以设置类的父级?即,在运行时实例化父类的实例,然后创建扩展某个父实例的子类实例。例如:

class A {
    var $test = 'default';
}

class B extends A {
    public function __contsruct(A $a) {
        parent = $a; //does not work
    }
}

$a = new A();
$a->test = 'changed';
$b = new B($a);
$b->test == 'changed'; //should be true

我知道我可以
$b=newb()$b->test='changed'
,但这不是我要问的问题。

您所要求的在基本PHP中是不可能的。有几种方法可以做类似的事情

您可以使用高度实验性的扩展。系统和功能应该起作用。但是,它们操作整个类,而不是类的实例。这可能会限制它们对应用程序的有用性

如果您试图模拟其他语言(如Ruby和Perl)的可扩展类功能,那么相关函数可能更合适。然而,它仍然在整个类上运行

通常被接受的“PHP方式”是通过。事实上,在5.3中,你可以做一些像

class Bar {
    public function say($thing) {
        echo "Bar::say says: $thing\n";
    }
}

class Foo extends Bar {
    private $extensions = array();

    public function addExtension($func_name, $func) {
        $this->extensions[ $func_name ] = $func;
    }

    public function __call($func_name, $arguments) {
        array_unshift($arguments, $this);
        if(array_key_exists($func_name, $this->extensions))
            call_user_func_array($this->extensions[ $func_name ], $arguments);
    }
}

$f = new Foo();
$anon = function($obj, $string){ $obj->say($string); };
$f->addExtension('example', $anon);
$f->example("Hello, world!");
您将在_调用中注意到,在创建匿名函数时,第一个参数将成为实例。这是因为PHP5.3的匿名函数实现不能引用
$this
。这也意味着它们不能引用类的受保护或私有成员。这可以通过克隆实例并使用公开受保护和私有成员来纠正。有关示例实现,请参见

由于PHP的限制,您不能直接将匿名函数分配给属性并调用它。此示例不起作用:

class WillNotWork {
    public $fatal_error;
}

$broken = new WillNotWork();
$anon = function($arg) { echo "I'm about to create a {$arg} error!"; };
$broken->fatal_error = $anon;
$broken->fatal_error("fatal");
// Fatal error: Call to undefined method WillNotWork::fatal_error()

实现这一点的简单方法如下:

class Foo
{
    function __construct() {
        $this->hello = "Hello";
    }

    public function sayHello() {
        echo $this->hello."!";
    }
}

class Bar
{
    function __construct(&$foo) {
        $this->foo = $foo;
    }

    public function sayHelloAgain() {
        echo $this->foo->sayHello()." Again!";
    }
}

$foo = new Foo();
echo $foo->sayHello(); //outputs "Hello!"

$bar = new Bar($foo);
echo $bar->sayHelloAgain(); //outputs "Hello! Again!"

否,因为
$a
是一个独立于
$b

的实例,所以这是不可能的。但是,根据你试图解决的具体问题,可能还有其他的解决方法。有趣的解决方法,值得一试。此外,您不需要
和$foo
<代码>$foo就足够了。