問題描述
我在 PHP 5.3 上遇到了問題.我需要使用 __callStatic
調用一個方法,但是如果我在實例化對象中使用它,PHP 會調用 __call
代替.
I'm havinh a problem on PHP 5.3. I need to call a method by using __callStatic
, but if I use it in a instancied object, PHP call __call
instead.
以上現(xiàn)實生活中的例子:
Above a real life example:
<?php
class A {
function __call($method, $args){
// Note: $this is defined!
echo "Ops! Don't works. {$this->c}";
}
static function __callStatic($method, $args){
echo 'Fine!';
}
}
class B extends A {
public $c = 'Real Ops!';
function useCallStatic(){
static::foo();
// === A::foo();
// === B::foo();
}
}
$foo = new B();
$foo->useCallStatic();
// This works:
// B::foo();
?>
打印:操作!不工作.真正的行動!
Prints: Ops! Don't works. Real Ops!
請注意,我從 new B()
調用了 useCallStatic
.如果我直接調用像 B::foo()
.
Note that I call useCallStatic
from a new B()
. If I call directly works fine like B::foo()
.
我能做些什么才能正常工作?
What I can do to it works fine?
推薦答案
仔細想了想,其實不是bug.但這絕對不直觀.
After thinking about it, it's not really a bug. But it's definitely unintuitive.
<?php
class A
{
public function foo()
{
static::bar();
}
public function bar()
{
echo "bar()
";
}
}
$a = new A();
$a->foo();
這是有效的,并調用 bar().這并不意味著靜態(tài)調用欄.表示查找當前的類名,如果存在則調用函數(shù)bar
,無論是否為靜態(tài)函數(shù).
This is valid, and calls bar(). It does not mean call bar statically. It means to look up the current class name and call function bar
if it exists, whether or not it's a static function.
再澄清一點:您認為 parent::bar()
是否意味著調用名為 bar()
的靜態(tài)函數(shù)?不,這意味著調用任何名為 bar()
的函數(shù).
To clarify a bit more: do you think parent::bar()
means to call a static function called bar()
? No, it means call whatever function is named bar()
.
考慮:
<?php
class A
{
function __call($name, $args)
{
echo "__call()
";
}
static function __callStatic($name, $ags)
{
echo "__callStatic()
";
}
function regularMethod()
{
echo "regularMethod()
";
}
static function staticMethod()
{
echo "staticMethod()
";
}
}
class B extends A
{
function foo()
{
parent::nonExistant();
static::nonExistant();
parent::regularMethod();
parent::staticMethod();
}
}
$b = new B();
$b->foo();
parent::nonExistant()
方法調用 A::__call()
,static::nonExistant()
也是如此.為 任一 調用調用 A::__callStatic()
將同樣有效!PHP 無法知道您要調用哪一個.但是,按照設計,PHP 在從此類上下文調用時給予 __call
優(yōu)先權.
The parent::nonExistant()
method invokes A::__call()
, as does static::nonExistant()
. Invoking A::__callStatic()
for either call would be equally as valid! There is no way for PHP to know which one you want to be called. However, by design, PHP gives __call
the priority when invoked from this sort of context.
parent::regularMethod()
調用非靜態(tài)函數(shù) regularMethod()
.(同樣,::
操作符并不意味著調用這個靜態(tài)函數(shù)".)同樣,parent::staticMethod()
調用 A::staticMethod()
正如人們所期望的那樣.
parent::regularMethod()
invokes the non static function regularMethod()
. (Again, the ::
operator does not mean "call this static function.") Likewise parent::staticMethod()
invokes A::staticMethod()
as one might expect.
解決您的問題:
您可以在繼承的類中手動調用self::__callStatic('foo')
.
You could manually call self::__callStatic('foo')
in the inherited class.
或者在 A 類的 __call
方法中過濾已知列表并調用 self::__callStatic
.
Or within the __call
method of class A filter against a known list and call self::__callStatic
.
function __call($f, $a)
{
if ($f == 'foo')
return self::__callStatic($f, $a);
else
{
}
}
這很丑陋,但至少擴展類的人不需要做任何特別的事情.
It's ugly, but at least people who extend the class won't need to do anything special.
這篇關于PHP 錯誤地處理了我的靜態(tài)調用的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!