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就足够了。