Khi phần bên trái là một đối tượng, bạn sử dụng ->
. Nếu không, bạn sử dụng ::
.
Điều này có nghĩa ->
là phần lớn được sử dụng để truy cập các thành viên thể hiện (mặc dù nó cũng có thể được sử dụng để truy cập các thành viên tĩnh, việc sử dụng đó không được khuyến khích), trong khi ::
thường được sử dụng để truy cập các thành viên tĩnh (mặc dù trong một số trường hợp đặc biệt, nó được sử dụng để truy cập các thành viên thể hiện ).
Nói chung, ::
được sử dụng cho độ phân giải phạm vi , và nó có thể có hoặc là một tên lớp, parent
, self
, hoặc (trong PHP 5.3) static
sang bên trái của nó. parent
đề cập đến phạm vi của siêu lớp của lớp nơi nó được sử dụng; self
đề cập đến phạm vi của lớp nơi nó được sử dụng; static
đề cập đến "phạm vi được gọi" (xem các ràng buộc tĩnh muộn ).
Quy tắc là một cuộc gọi với ::
là một cuộc gọi thể hiện khi và chỉ khi:
- phương thức đích không được khai báo là tĩnh và
- có một bối cảnh đối tượng tương thích tại thời điểm cuộc gọi, nghĩa là những điều này phải đúng:
- cuộc gọi được thực hiện từ một bối cảnh
$this
tồn tại và
- lớp của
$this
hoặc là lớp của phương thức được gọi hoặc lớp con của nó.
Thí dụ:
class A {
public function func_instance() {
echo "in ", __METHOD__, "\n";
}
public function callDynamic() {
echo "in ", __METHOD__, "\n";
B::dyn();
}
}
class B extends A {
public static $prop_static = 'B::$prop_static value';
public $prop_instance = 'B::$prop_instance value';
public function func_instance() {
echo "in ", __METHOD__, "\n";
/* this is one exception where :: is required to access an
* instance member.
* The super implementation of func_instance is being
* accessed here */
parent::func_instance();
A::func_instance(); //same as the statement above
}
public static function func_static() {
echo "in ", __METHOD__, "\n";
}
public function __call($name, $arguments) {
echo "in dynamic $name (__call)", "\n";
}
public static function __callStatic($name, $arguments) {
echo "in dynamic $name (__callStatic)", "\n";
}
}
echo 'B::$prop_static: ', B::$prop_static, "\n";
echo 'B::func_static(): ', B::func_static(), "\n";
$a = new A;
$b = new B;
echo '$b->prop_instance: ', $b->prop_instance, "\n";
//not recommended (static method called as instance method):
echo '$b->func_static(): ', $b->func_static(), "\n";
echo '$b->func_instance():', "\n", $b->func_instance(), "\n";
/* This is more tricky
* in the first case, a static call is made because $this is an
* instance of A, so B::dyn() is a method of an incompatible class
*/
echo '$a->dyn():', "\n", $a->callDynamic(), "\n";
/* in this case, an instance call is made because $this is an
* instance of B (despite the fact we are in a method of A), so
* B::dyn() is a method of a compatible class (namely, it's the
* same class as the object's)
*/
echo '$b->dyn():', "\n", $b->callDynamic(), "\n";
Đầu ra:
B :: $ prop_static: B :: $ prop_static giá trị
B :: func_static (): trong B :: func_static
$ b-> prop_instance: B :: $ prop_instance giá trị
$ b-> func_static (): trong B :: func_static
$ b-> func_instance ():
trong B :: func_instance
trong A :: func_instance
trong A :: func_instance
$ a-> dyn ():
trong A :: callDocate
trong dyn động (__callStatic)
$ b-> dyn ():
trong A :: callDocate
trong dyn động (__call)