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

时间:2022-09-01 17:02:45

I'm not pro in Object Oriented Programming and I got a silly question:

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

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

So the correct way to call doSomething() method is to do test::doSomething('Pizza');, Am I right?

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

Now, what will happen if I call it like this:

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

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

I've tested it and it's working without any error or notice or etc. but is that correct to do this?

我已经测试了它并且没有任何错误或通知等工作但是这样做是否正确?

3 个解决方案

#1


14  

As Baba already pointed out, it results in an E_STRICT depending on your configuration.

正如Baba已经指出的那样,它会导致E_STRICT,具体取决于您的配置。

But even if that's no problem for you, I think it's worth mentioning some of the pitfalls which may result from calling static methods in a non-static way.

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

If you have a class hierarchy like

如果你有一个类层次结构

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

This produces the following output:

这会产生以下输出:

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

As you can see, it's easy to achieve unexpected behaviour when mixing static and non-static method calls and techniques.

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

Therefore, my advice also is: Use Class::method to explicitly call the static method you mean to call. Or even better don't use static methods at all because they make your code untestable.

因此,我的建议是:使用Class ::方法显式调用您要调用的静态方法。或者更好的是根本不使用静态方法,因为它们使代码不可测试。

#2


3  

It is better you call it this way to avoid E_STRICT on some version of PHP

最好用这种方式调用它来避免在某些版本的PHP上使用E_STRICT

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

FROM PHP DOC

来自PHP DOC

Static properties cannot be accessed through the object using the arrow operator ->. Calling non-static methods statically generates an E_STRICT level warning.

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

Also

Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static can not be accessed with an instantiated class object (though a static method can).

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

#3


3  

It makes no difference if your method don't use $this and don't access to static properties.

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

Static properties cannot be accessed through the object using the arrow operator ->.

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

$this is not available inside the method declared as static.

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

But, you should always use :: to call a static method, even through php let you call it on an instance.

但是,你应该总是使用::来调用静态方法,即使通过php让你在一个实例上调用它。

#1


14  

As Baba already pointed out, it results in an E_STRICT depending on your configuration.

正如Baba已经指出的那样,它会导致E_STRICT,具体取决于您的配置。

But even if that's no problem for you, I think it's worth mentioning some of the pitfalls which may result from calling static methods in a non-static way.

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

If you have a class hierarchy like

如果你有一个类层次结构

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

This produces the following output:

这会产生以下输出:

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

As you can see, it's easy to achieve unexpected behaviour when mixing static and non-static method calls and techniques.

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

Therefore, my advice also is: Use Class::method to explicitly call the static method you mean to call. Or even better don't use static methods at all because they make your code untestable.

因此,我的建议是:使用Class ::方法显式调用您要调用的静态方法。或者更好的是根本不使用静态方法,因为它们使代码不可测试。

#2


3  

It is better you call it this way to avoid E_STRICT on some version of PHP

最好用这种方式调用它来避免在某些版本的PHP上使用E_STRICT

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

FROM PHP DOC

来自PHP DOC

Static properties cannot be accessed through the object using the arrow operator ->. Calling non-static methods statically generates an E_STRICT level warning.

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

Also

Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static can not be accessed with an instantiated class object (though a static method can).

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

#3


3  

It makes no difference if your method don't use $this and don't access to static properties.

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

Static properties cannot be accessed through the object using the arrow operator ->.

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

$this is not available inside the method declared as static.

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

But, you should always use :: to call a static method, even through php let you call it on an instance.

但是,你应该总是使用::来调用静态方法,即使通过php让你在一个实例上调用它。