重写 PHP 中的魔术方法
Overriding a magic method in PHP
我用谷歌搜索了一个小时,发现了这个问题的变体,但没有找到这个问题的确切版本,除了一个博客 post 没有用。
我想重写 PHP 扩展 class 中的方法,并在新方法的主体内调用父方法。问题是父级没有这样的方法,但是实现了 __call()
来公开该功能。
例如:
class B extends A {
public function setParentId($new_id)
{
parent::setParentId($new_id);
$this->buildParentTreeCache();
return $this;
}
这行不通。事实上,我遇到了一个令人讨厌的 Apache 内部错误或配置错误。
我发现这个解决方案也不起作用:
(除了我添加了 array($new_id)
部分。示例使用 NULL。)
class B extends A {
public function setParentId($new_id)
{
parent::__call('setParentId', array($new_id));
$this->buildParentTreeCache();
return $this;
}
这个应该有用!我不知道我做错了什么。
正确的做法是什么?
编辑:
我不确定我的配置有什么问题,但我收到的错误消息只是:
[Mon May 04 12:13:12.778136 2015] [fastcgi:error] [pid 30512] (104)Connection reset by peer: [client 127.0.0.1:54854] FastCGI: comm with server "/var/www/fastcgi/php5.fastcgi" aborted: read failed, referer: http://admin.mysite/index.php/category/index
[Mon May 04 12:13:12.779620 2015] [fastcgi:error] [pid 30512] [client 127.0.0.1:54854] FastCGI: incomplete headers (0 bytes) received from server "/var/www/fastcgi/php5.fastcgi", referer: http://admin.mysite/index.php/category/index
编辑 2:
基础 class(本例中的 Class A)是一个自动生成的文件,它也没有我要调用的代码。
事实上,它是一个名为 "BaseCategory" 的 Doctrine 1 模型 "Base" class,它从 sfDoctrineRecord 扩展而来。
class Category extends BaseCategory // My class
class BaseCategory extends sfDoctrineRecord // Autogenerated, prone to be verwritten by the generator
class sfDoctrineRecord 的代码在这里:
按照moonwave99的建议,你应该看看here
Take care of using parent::method with not declared method when using
__call because in this case the string method will be lowercase:
<?php
class A {
function __call( $method, $args ) {
echo get_class( $this ) . ' ' . $method . "\n";
}
}
class B extends A {
function getTest() {
parent::getTest();
}
}
$a = new A();
$a->getTest();
$b = new B();
$b->getTest();
?>
output:
A getTest
B gettest
这可能是导致错误的原因,因此当您执行 parent::setParentId($new_id);
时,它很可能被解释为:
parent::setparentid($new_id);
在 class A
中也尝试使用小写字母
我用谷歌搜索了一个小时,发现了这个问题的变体,但没有找到这个问题的确切版本,除了一个博客 post 没有用。
我想重写 PHP 扩展 class 中的方法,并在新方法的主体内调用父方法。问题是父级没有这样的方法,但是实现了 __call()
来公开该功能。
例如:
class B extends A {
public function setParentId($new_id)
{
parent::setParentId($new_id);
$this->buildParentTreeCache();
return $this;
}
这行不通。事实上,我遇到了一个令人讨厌的 Apache 内部错误或配置错误。
我发现这个解决方案也不起作用:
(除了我添加了 array($new_id)
部分。示例使用 NULL。)
class B extends A {
public function setParentId($new_id)
{
parent::__call('setParentId', array($new_id));
$this->buildParentTreeCache();
return $this;
}
这个应该有用!我不知道我做错了什么。
正确的做法是什么?
编辑:
我不确定我的配置有什么问题,但我收到的错误消息只是:
[Mon May 04 12:13:12.778136 2015] [fastcgi:error] [pid 30512] (104)Connection reset by peer: [client 127.0.0.1:54854] FastCGI: comm with server "/var/www/fastcgi/php5.fastcgi" aborted: read failed, referer: http://admin.mysite/index.php/category/index
[Mon May 04 12:13:12.779620 2015] [fastcgi:error] [pid 30512] [client 127.0.0.1:54854] FastCGI: incomplete headers (0 bytes) received from server "/var/www/fastcgi/php5.fastcgi", referer: http://admin.mysite/index.php/category/index
编辑 2:
基础 class(本例中的 Class A)是一个自动生成的文件,它也没有我要调用的代码。
事实上,它是一个名为 "BaseCategory" 的 Doctrine 1 模型 "Base" class,它从 sfDoctrineRecord 扩展而来。
class Category extends BaseCategory // My class
class BaseCategory extends sfDoctrineRecord // Autogenerated, prone to be verwritten by the generator
class sfDoctrineRecord 的代码在这里:
按照moonwave99的建议,你应该看看here
Take care of using parent::method with not declared method when using __call because in this case the string method will be lowercase:
<?php
class A {
function __call( $method, $args ) {
echo get_class( $this ) . ' ' . $method . "\n";
}
}
class B extends A {
function getTest() {
parent::getTest();
}
}
$a = new A();
$a->getTest();
$b = new B();
$b->getTest();
?>
output:
A getTest
B gettest
这可能是导致错误的原因,因此当您执行 parent::setParentId($new_id);
时,它很可能被解释为:
parent::setparentid($new_id);
在 class A
中也尝试使用小写字母