gpt4 book ai didi

PHP 错误地处理了我的静态调用

转载 作者:可可西里 更新时间:2023-11-01 00:06:56 27 4
gpt4 key购买 nike

我在 PHP 5.3 上遇到了问题。我需要使用 __callStatic 调用方法,但如果我在实例化对象中使用它,PHP 会改为调用 __call

上面是一个真实的例子:

<?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();

?>

打印:糟糕!不工作。真正的行动!

请注意,我从 new B() 调用了 useCallStatic。如果我直接调用,效果很好,如 B::foo()

我能做些什么让它工作正常?

最佳答案

仔细想想,还真不是bug。但这绝对是不直观的。

<?php
class A
{
public function foo()
{
static::bar();
}

public function bar()
{
echo "bar()\n";
}
}

$a = new A();
$a->foo();

这是有效的,并调用 bar()。这并不意味着静态调用 bar。意思是查找当前类名,如果存在就调用函数bar,不管是不是静态函数。

再澄清一点:你认为 parent::bar() 意味着调用名为 bar() 的静态函数吗?不,这意味着调用任何名为 bar() 的函数。

考虑:

<?php
class A
{
function __call($name, $args)
{
echo "__call()\n";
}

static function __callStatic($name, $ags)
{
echo "__callStatic()\n";
}

function regularMethod()
{
echo "regularMethod()\n";
}

static function staticMethod()
{
echo "staticMethod()\n";
}

}

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 优先权。

parent::regularMethod() 调用非静态函数 regularMethod()。 (同样,:: 运算符并不意味着“调用此静态函数。”)同样,parent::staticMethod() 调用 A::staticMethod() 正如人们所期望的那样。

解决您的问题:

您可以在继承的类中手动调用 self::__callStatic('foo')

或者在 A 类的 __call 方法中过滤已知列表并调用 self::__callStatic

function __call($f, $a)
{
if ($f == 'foo')
return self::__callStatic($f, $a);
else
{
}
}

这很丑陋,但至少扩展类的人不需要做任何特别的事情。

关于PHP 错误地处理了我的静态调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6181603/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com