Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 检测非静态调用的静态函数_Php - Fatal编程技术网

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