【问题标题】:PHP: What if I call a static method in non-static wayPHP:如果我以非静态方式调用静态方法怎么办
【发布时间】:2012-10-04 04:08:45
【问题描述】:

我不是面向对象编程的专业人士,我有一个愚蠢的问题:

class test {
    public static function doSomething($arg) {
        $foo = 'I ate your ' . $arg;
        return $foo;
    }
}

所以调用doSomething()方法的正确方法是test::doSomething('Pizza');,对吗?

现在,如果我这样称呼它会发生什么:

$test = new test;
$bar = $test->doSomething('Sandwich');

我已经对其进行了测试,它可以正常工作,没有任何错误或通知等,但是这样做是否正确?

【问题讨论】:

  • 我的问题有那么无用,我应该得到-1吗?
  • 正如人们所说的“他什么都不质疑,什么也不学”(问题很基本,但我看不出你得到-1的任何理由)+1
  • 为什么这个问题被认为如此基础?我已经这样做了很多年了,我并不清楚这是否是不好的做法,这就是把我带到这里的原因。这是一个很好的问题。
  • @OCDev 这个问题很老,但谢谢。 :)
  • 这类永恒的问题对于那些还没有看到答案的人来说不会过时。再次感谢您的提问!

标签: php static-methods


【解决方案1】:

正如 Baba 已经指出的那样,它会根据您的配置生成E_STRICT

但即使这对您来说没有问题,我认为值得一提的是一些可能因以非静态方式调用静态方法而导致的陷阱。

如果你有像这样的类层次结构

class A {
    public static function sayHello() {
        echo "Hello from A!\n";
    }

    public function sayHelloNonStaticWithSelf() {
        return self::sayHello();
    }

    public function sayHelloNonStaticWithStatic() {
        return static::sayHello();
    }
}

class B extends A {
    public static function sayHello() {
        echo "Hello from B!\n";
    }

    public function callHelloInMultipleDifferentWays() {
        A::sayHello();
        B::sayHello();
        $this->sayHelloNonStaticWithSelf();
        $this->sayHelloNonStaticWithStatic();
        $this->sayHello();
    }
}

$b = new B();
$b->callHelloInMultipleDifferentWays();

这会产生以下输出:

Hello from A!
// A::sayHello() - obvious

Hello from B!
// B::sayHello() - obvious

Hello from A!
// $this->sayHelloNonStaticWithSelf()
// self alweays refers to the class it is used in

Hello from B!
// $this->sayHelloNonStaticWithStatic()
// static always refers to the class it is called from at runtime

Hello from B!
// $this->sayHello() - obvious

如您所见,在混合静态和非静态方法调用和技术时很容易实现意外行为。

因此,我的建议也是: 使用 Class::method 显式调用您要调用的静态方法。 甚至最好不要使用静态方法,因为它们会使您的代码无法测试

【讨论】:

  • 您的答案值得被接受,因为有完整的解释和示例。顺便说一句,关于你的最后一行,我认为不可能总是不使用静态方法,因为有时最好的解决方案是使用静态方法。它节省了大量代码并使应用程序更简单、更可编辑。如果你愿意,我可以给你展示太多的例子。无论如何,感谢您的完整回答。
  • 谢谢!是的,我也知道静态函数非常方便的情况,但我仍然更喜欢更高级别的可测试性而不是静态的好处。我对这个话题的评论只是为了(至少)引发对静态的这种潜在问题副作用的有意识的思考。
  • 错了。使用箭头运算符调用静态方法不会产生错误或警告。
  • 值得注意的是,您也可以致电$test::doSomthing(),这似乎是正确的并且有优势。
【解决方案2】:

如果您的方法不使用$this 并且不访问静态属性,则没有区别。

不能通过对象使用箭头操作符访问静态属性 ->。

$this 在声明为静态的方法中不可用。

但是,您应该始终使用:: 来调用静态方法,即使通过 php 让您在实例上调用它。

【讨论】:

    【解决方案3】:

    最好这样称呼它以避免在某些版本的 PHP 上使用E_STRICT

    $bar = test::doSomething('Sandwich');
    

    FROM PHP DOC

    使用箭头运算符 -> 无法通过对象访问静态属性。静态调用非静态方法会生成 E_STRICT 级别的警告。

    还有

    将类属性或方法声明为静态使它们无需实例化即可访问。声明为静态的属性不能被实例化的类对象访问(尽管静态方法可以)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-20
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多