Php 检测非静态调用的静态函数
如何检测静态函数以非静态方式调用 例如,在这种情况下:Php 检测非静态调用的静态函数,php,Php,如何检测静态函数以非静态方式调用 例如,在这种情况下: class Foo { public static function bar() { // How can I tell here that bar() is called on an instance? //var_dump(debug_backtrace()[0]['type'] == '::'); // at all times the above prints boo
class Foo
{
public static function bar()
{
// How can I tell here that bar() is called on an instance?
//var_dump(debug_backtrace()[0]['type'] == '::');
// at all times the above prints bool(true)
return 1;
}
}
// later in the code
$foo = new Foo();
$foo::bar(); // that's fine
// even later
$foo->bar(); // this should not happen, yet it's here and there
我想调试并消除上面最后一行中的情况:某个地方有人错误地调用实例上的函数,期望它返回与subject中实例相关的内容;取而代之的是一个有点相关的常数。随后我需要知道这是什么时候发生的。如果地狱失控或抛出异常,我也没问题
到目前为止,我发现对静态函数的非静态调用是无效的,因此
debug_backtrace()[0]['type']
告诉我们什么都没有(在这两种情况下都是:
)解决方案有两个方面:
E\u STRICT
报告:
error_reporting(error_reporting() ^ E_STRICT);
static
关键字
public /* static */ function bar()
class Foo
{
public function bar()
{
$calledStatically = debug_backtrace()[0]['type'] == '::';
if (!$calledStatically) {
throw new Exception("Should not happen");
}
// ...
}
}
从文件中:
类型
(字符串):当前调用类型。如果方法调用返回“->”。如果是静态的
返回方法调用“::”。如果是函数调用,则什么都不会发生
返回
快速演示
Foo::bar(); // normal result returned
$foo = new Foo();
$foo->bar(); // throws exception
如果你不想永远关闭
E_STRICT
,有一种方法
如果类Foo
纯粹出于运气或天意,仅在以下几个地方实例化:
public function getFoo()
{
return new Foo();
}
然后,如果我们将其子类化并重新定义bar()
:
然后,如果我们用实例化的Foo2
替换Foo
public function getFoo()
{
//return new Foo();
return new Foo2();
}
调用上述新静态方法时将引发异常:
$q = Foo::bar(); // no error just as before
$foo = $other->getFoo();
$foo->bar(); // throws exception
如果有人调用
$foo->bar()
在这种-Foo
上,他会很快被通知他犯了错误。静态调用非静态函数是错误的。以非静态方式调用静态函数是不正确的。你的代码是后者的例子,而不是前者。@Sherif我更新了这个问题,使它更明显地表明这不是错误,我想我当时想知道的是,如果这不是错误,你为什么要检测这个呢?让我不快的是,你使用了“调试这些案例”的语句,这让我相信你的印象是这可能会导致错误行为。不可能。PHP在编译时已经知道该方法是静态声明的。因此,在运行时尝试从对象实例调用该方法并不重要。它仍然知道使用静态上下文,如果它确实在我试图修复的遗留代码中导致错误行为;不知道哪里出了问题,我该怎么解决?你看到的这种马车行为是什么?很可能它与非静态调用静态方法无关,这就是为什么我一直在想为什么你会问这样一个奇怪的问题。也许可以尝试展示产生问题的实际代码,并解释期望的行为与实际问题的实际行为?因为现在您在这个问题中提供的代码没有显示任何问题。正如我在问题中所指出的,debug\u backtrace
没有按照您认为应该的方式提供帮助。$utils=new utils()$utils::whoDat()$utils->whoDat()代码>该如何工作?确定上次更新。。。不确定删除“静态”是否有效。但这似乎是可行的。是的,如果你禁用了不,那就去吧
$q = Foo::bar(); // no error just as before
$foo = $other->getFoo();
$foo->bar(); // throws exception