PHP:如果我以非静态方式调用静态方法怎么办

2022-08-30 16:43:10

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

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

正如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 显式调用你想要调用的静态方法。或者更好的是,不要使用静态方法,因为它们会使你的代码无法测试


答案 2

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

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

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

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


推荐