問題描述
我在 PHP 5.3 上遇到了問題.我需要使用 __callStatic
調(diào)用一個(gè)方法,但是如果我在實(shí)例化對(duì)象中使用它,PHP 會(huì)調(diào)用 __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)實(shí)生活中的例子:
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();
?>
打印:操作!不工作.真正的行動(dòng)!
Prints: Ops! Don't works. Real Ops!
請(qǐng)注意,我從 new B()
調(diào)用了 useCallStatic
.如果我直接調(diào)用像 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?
推薦答案
仔細(xì)想了想,其實(shí)不是bug.但這絕對(duì)不直觀.
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();
這是有效的,并調(diào)用 bar().這并不意味著靜態(tài)調(diào)用欄.表示查找當(dāng)前的類名,如果存在則調(diào)用函數(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.
再澄清一點(diǎn):您認(rèn)為 parent::bar()
是否意味著調(diào)用名為 bar()
的靜態(tài)函數(shù)?不,這意味著調(diào)用任何名為 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()
方法調(diào)用 A::__call()
,static::nonExistant()
也是如此.為 任一 調(diào)用調(diào)用 A::__callStatic()
將同樣有效!PHP 無法知道您要調(diào)用哪一個(gè).但是,按照設(shè)計(jì),PHP 在從此類上下文調(diào)用時(shí)給予 __call
優(yōu)先權(quán).
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()
調(diào)用非靜態(tài)函數(shù) regularMethod()
.(同樣,::
操作符并不意味著調(diào)用這個(gè)靜態(tài)函數(shù)".)同樣,parent::staticMethod()
調(diào)用 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.
解決您的問題:
您可以在繼承的類中手動(dòng)調(diào)用self::__callStatic('foo')
.
You could manually call self::__callStatic('foo')
in the inherited class.
或者在 A 類的 __call
方法中過濾已知列表并調(diào)用 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
{
}
}
這很丑陋,但至少擴(kuò)展類的人不需要做任何特別的事情.
It's ugly, but at least people who extend the class won't need to do anything special.
這篇關(guān)于PHP 錯(cuò)誤地處理了我的靜態(tài)調(diào)用的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!