静态调用非静态方法与静态调用之间的区别

时间:2016-10-06 07:31:09

标签: php

给出以下代码:

<?php
class MyClass {
    public function print() {
        echo $this->number . "\n";
    }

    public static function staticPrint() {
        echo "staticPrint\n";
    }
}

class MyExtendedClass extends MyClass {
    protected $number = 100;

    public function extendedPrint() {
        $this->print();
        $this::print(); // What's the difference?
        $this->staticPrint(); // Why is this allowed?
        $this::staticPrint();
        echo "Print done...!\n";
    }
}

$myExtendedClass = new MyExtendedClass();
$myExtendedClass->extendedPrint();

使用以下输出:

100
100
Print done...!

$this->print()$this::print()之间有什么区别吗?

4 个答案:

答案 0 :(得分:1)

恕我直言,如果你从班级中打电话,没有任何区别。

但是,如果你从课外调用它,你需要首先实例化以调用非静态方法。

$var = new MyExtendedClass;
$var->print();

静态:( 在PHP 7上弃用

$var = MyExtendedClass::print();

在PHP 7上,您的方法需要Static关键字,因此可以静态调用。 Full reference

答案 1 :(得分:1)

声明为static的方法将始终静态调用:

public static function bar() { var_dump($this); }

无论你怎样称呼这种方法,都会导致:

Fatal error: Uncaught Error: Using $this when not in object context

(或其变体取决于您的PHP版本。)

的函数使static关键字的行为有所不同......

class Foo {
    public function bar() { var_dump($this); }
}

$f = new Foo;
$f::bar();
Deprecated: Non-static method Foo::bar() should not be called statically
Fatal error: Uncaught Error: Using $this when not in object context

从外部调用函数实际上是静态调用它。

class Foo {
    public function bar() { var_dump($this); }
    public function baz() { $this::bar(); }
}

$f = new Foo;
$f->baz();
object(Foo)#1 (0) {
}

通过$this::调用函数在对象上下文中调用它。

本手册仅为::运营商提供these vague paragraphs

  

从类定义外部引用这些项时,请使用类的名称。

     

从PHP 5.3.0开始,可以使用变量引用该类。变量的值不能是关键字(例如self,parent和static)。

似乎在课程::之外始终静态操作,$f::替换课程的名称。但是,在对象上下文中,::会保留上下文,可能会启用parent::调用的正确操作,这显然应该保留对象上下文。

答案 2 :(得分:0)

在示例中,您给出了No,没有区别。

虽然在大多数情况下完全不同,因为在非静态中,您正在打印对象的当前数字值,这可能已更改(任何设置)方法或类似方法可能被称为。)

对于静态调用,它将始终打印相同的值(在范围中声明的默认值,100)。

答案 3 :(得分:0)

简短的回答是: $instance::method(…) (其中$instance是一个类实例,而不是字符串)似乎等同于get_class($instance)::method(…) (在您的情况下)表示MyExtendedClass::print())。

当您致电SomeClassName::method(…)时,method收到或未收到$this值的事实是零星的。这取决于您拨打SomeClassName::method(…)的地方。从SomeClassName::method(…)或其后代的相同或其他方法中调用SomeClassName将导致将来自调用$this传递给method };否则method可能不会收到任何$this值。

因此,当您致电$instance::method(…)时,method可能会或可能不会收到$this值。如果它收到$this值,则来自调用地点的$this,但不是$instance (虽然它们可能重合,如同$this::method(…)$instance = $this; …; $instance::method(…))。

http://sandbox.onlinephpfunctions.com/code/93d4ea2dd47dbc2c5ed338a96ca4d00d4ffef77b