PHP 子类的神奇方法 __call
我的情况最好用一些代码来描述:
class Foo {
function bar () {
echo "called Foo::bar()";
}
}
class SubFoo extends Foo {
function __call($func) {
if ($func == "bar") {
echo "intercepted bar()!";
}
}
}
$subFoo = new SubFoo();
// what actually happens:
$subFoo->bar(); // "called Foo:bar()"
// what would be nice:
$subFoo->bar(); // "intercepted bar()!"
我知道我可以通过在子类中重新定义 bar()
(以及所有其他相关方法)来使其工作,但出于我的目的,如果 __call 函数能够处理它们那就太好了。它只会让事情变得更加整洁和易于管理。
这在 PHP 中可能吗?
My situation is best described with a bit of code:
class Foo {
function bar () {
echo "called Foo::bar()";
}
}
class SubFoo extends Foo {
function __call($func) {
if ($func == "bar") {
echo "intercepted bar()!";
}
}
}
$subFoo = new SubFoo();
// what actually happens:
$subFoo->bar(); // "called Foo:bar()"
// what would be nice:
$subFoo->bar(); // "intercepted bar()!"
I know I can get this to work by redefining bar()
(and all the other relevant methods) in the sub-class, but for my purposes, it'd be nice if the __call
function could handle them. It'd just make things a lot neater and more manageable.
Is this possible in PHP?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
__call()
仅当未找到该函数时才被调用,因此您的示例(如所写)是不可能的。
__call()
is only invoked when the function isn't otherwise found so your example, as written, is not possible.您可以尝试的一件事是将函数范围设置为私有或受保护。当从类外部调用一个私有函数时,它会调用 __call 魔术方法,您可以利用它。
One thing you can try is to set your functions scope to private or protected. When one private function is called from outside the class it calls the __call magic method and you can exploit it.
它不能直接完成,但这是一种可能的替代方案:
这种事情有利于调试和测试,但您希望在生产代码中尽可能避免 __call() 和朋友因为他们的效率不是很高。
It can't be done directly, but this is one possible alternative:
This sort of thing is good for debugging and testing, but you want to avoid
__call()
and friends as much as possible in production code as they are not very efficient.如果您需要向父 bar() 添加额外的内容,这可行吗?
或者这只是出于好奇而提出的问题?
If you need to add something extra to the parent bar(), would this be doable?
or is this just a question from curiosity?
为了达到相同的效果,您可以执行以下操作:
What you could do to have the same effect is the following: