Calling non-static method with double-colon(::)

2019-01-01 13:38发布

Why can't I use a method non-static with the syntax of the methods static(class::method) ? Is it some kind of configuration issue?

class Teste {

    public function fun1() {
        echo 'fun1';
    }
    public static function fun2() {
        echo "static fun2" ;
    }
}

Teste::fun1(); // why?
Teste::fun2(); //ok - is a static method

标签: php static
9条回答
泪湿衣
2楼-- · 2019-01-01 14:00

This is PHP 4 backwards compatibility. In PHP 4 you could not differ between an object method and the global function written as a static class method. Therefore both did work.

However with the changes in the object model with PHP 5 - http://php.net/oop5 - the static keyword has been introduced.

And then since PHP 5.1.3 you get proper strict standard warnings about those like:

Strict Standards: Non-static method Foo::bar() should not be called statically

And/Or:

Strict Standards: Non-static method Foo::bar() should not be called statically, assuming $this from incompatible context

which you should have enabled for your development setup. So it's merely backwards compatibility to a time where the language couldn't differ enough so this was "defined" at run-time.

Nowadays you can define it already in the code, however the code will not break if you still call it "wrong".

Some Demo to trigger the error messages and to show the changed behavior over different PHP versions: http://3v4l.org/8WRQH

查看更多
孤独寂梦人
3楼-- · 2019-01-01 14:01

PHP 4 did not have a static keyword (in function declaration context) but still allowed methods to be called statically with ::. This continued in PHP 5 for backwards compatibility purposes.

查看更多
人间绝色
4楼-- · 2019-01-01 14:07

PHP is very loose with static vs. non-static methods. One thing I don't see noted here is that if you call a non-static method, ns statically from within a non-static method of class C, $this inside ns will refer to your instance of C.

class A 
{
    public function test()
    {
        echo $this->name;
    }
}

class C 
{
     public function q()
     {
         $this->name = 'hello';
         A::test();
     }
}

$c = new C;
$c->q();// prints hello

This is actually an error of some kind if you have strict error reporting on, but not otherwise.

查看更多
只若初见
5楼-- · 2019-01-01 14:13

Not sure why PHP allows this, but you do not want to get into the habit of doing it. Your example only works because it does not try to access non-static properties of the class.

Something as simple as:

<?php
class Foo {

    private $color;

    public function bar() {
        echo 'before';
        $this->color = "blue";
        echo 'after';
    }
}

Foo::bar();

would result in a fatal error

查看更多
余生请多指教
6楼-- · 2019-01-01 14:17

In most languages you will need to have an instance of the class in order to perform instance methods. It appears that PHP will create a temporary instance when you call an instance method with the scope resolution operator.

查看更多
还给你的自由
7楼-- · 2019-01-01 14:20

I have noticed that if you call non-static method self::test() from within a class, no warning for strict standard will be issued, like when you call Class::test(). I believe that this is not related to LSB, since my class was not extended (tested on php 5.5)?

查看更多
登录 后发表回答