Table of Contents
The difference between self, static and $this
Late static binding
工作原理
Forwarding call (forwarding call)
注意事项
非静态环境下的私有方法的查找顺序
关于后期静态绑定的解析
Home Backend Development PHP Tutorial Detailed explanation of the differences between self, static, $this and late static binding in PHP

Detailed explanation of the differences between self, static, $this and late static binding in PHP

Apr 13, 2018 am 11:41 AM
self static this

The content shared with you in this article is about the differences between self, static, and $this in PHP and the detailed explanation of late static binding. It has certain reference value. Friends in need can refer to it


The difference between self, static and $this


In order to better understand the difference between self, static and $this, let’s first look at an example .

<?phpclass A {    protected $name = &#39;A&#39;;    static $alias = &#39;a&#39;;    const HASH = &#39;md5&#39;;    public function dd() {        echo $this->name; echo '--';        echo static::$alias; echo '--';     // 后期静态绑定
        echo static::HASH; echo '--';     // 后期静态绑定
        echo self::$alias; echo '--';        echo self::HASH; echo '--';

        var_dump(new self); echo '--';
        var_dump($this); echo '--';
        var_dump(new static); echo '<br>';   // 后期静态绑定
    }    public static function who() {        echo __CLASS__;        echo ' [ This is A ]'; echo '<br>';
    }    public static function test() {        self::who();
    }    public static function test2() {        static::who();  // 后期静态绑定
    }    public static function getInstance() {
        var_dump(new self); echo '--';
        var_dump(new static); echo '<br>';  // 后期静态绑定
    }
}class B extends A {    protected $name = 'B';    static $alias = 'b';    const HASH = 'sha1';    public static function who() {        echo __CLASS__;        echo ' [ This is B ]'; echo '<br>';
    }
}class C extends B {    public static function who() {        echo __CLASS__;        echo ' [ This is C]'; echo '<br>';
    }
}


(new A)->dd();  // A--a--md5--a--md5--object(A)#2 (1) { ["name":protected]=> string(1) "A" } --object(A)#1 (1) { ["name":protected]=> string(1) "A" } --object(A)#2 (1) { ["name":protected]=> string(1) "A" }(new B)->dd();  // B--b--sha1--a--md5--object(A)#2 (1) { ["name":protected]=> string(1) "A" } --object(B)#1 (1) { ["name":protected]=> string(1) "B" } --object(B)#2 (1) { ["name":protected]=> string(1) "B" }A::who();  // A [ This is A ]B::who();  // B [ This is B ]A::test();  // A [ This is A ]B::test();  // A [ This is A ]A::test2(); // A [ This is A ]B::test2(); // B [ This is B ]C::test2(); // C [ This is C]A::getInstance();   // object(A)#1 (1) { ["name":protected]=> string(1) "A" } --object(A)#1 (1) { ["name":protected]=> string(1) "A" }B::getInstance();   // object(A)#1 (1) { ["name":protected]=> string(1) "A" } --object(B)#1 (1) { ["name":protected]=> string(1) "B" }
Copy after login

Summary description:

  • self and __CLASS__ are static references to the current class, depending on the class in which the current method is defined. . In other words, which class self is written in will be the one it refers to.

  • $this points to the object when it is actually called. That is to say, whoever calls the properties or methods of the class during the actual running process, $this points to the object. But $this cannot access static properties and constants of the class, and $this cannot exist in static methods.

  • # In addition to declaring static members (properties and methods) of a class, the static keyword also plays a very important role in late static binding.

  • self can be used to access static properties, static methods and constants of a class, but self points to the class where the current definition is located. This is a limitation of self.

  • $this points to an object that belongs to the same class as static points to.

  • static can be used in static or non-static methods, and can also access static properties, static methods, constants and non-static methods of the class, but cannot access non-static properties.

  • When calling statically, static points to the class that is actually called; when calling non-statically, static points to the class to which the object is actually called.

Late static binding

Late static binding (also called delayed static binding) can be used to reference statically called classes in the inheritance scope, that is, code The class that is initially called at runtime.

Later static binding was originally intended to be expressed by introducing a new keyword, but in the end the static keyword was used.

工作原理

确切地说,static 后期静态绑定的工作原理是存储了上一个非转发调用(non-forwarding call)的类名。

当进行静态方法调用时,该类名(static指向的类名)为明确指定的那个(通常是 :: 运算符的左侧部分),即实际调用时的类。

如上述示例中的:

A::test2(); B::test2();
Copy after login

static 和 self 的区别:

  • self 可以用于访问类的静态属性、静态方法和常量,但 self 指向的是当前定义所在的类,这是 self 的限制。

  • static 也可以用于访问类的静态属性、静态方法和常量,static 指向的是实际调用时的类。

当进行非静态方法调用时,该类名(static指向的类名)为该对象所属的类,即实际调用时的对象所属的类。

如上述示例中的:

(new A)->dd(); 
(new B)->dd();
Copy after login

static 和 $this 有点类似,但又有区别:

  • $this 指向的对象所属的类和 static 指向的类相同。

  • $this 不能用于静态方法中,也不能访问类的静态属性和常量。

  • $this 指向的是实际调用的对象。

  • static 可以用于静态或非静态方法中,也可以访问类的静态属性、静态方法、常量和非静态方法,但不能访问非静态属性。

  • static 指向的是实际调用时的对象所属的类。

Forwarding call (forwarding call)

The so-called forwarding call (forwarding call) refers to static calls made in the following ways: self::, parent::, static:: and forward_static_call().

You can use the get_called_class() function to get the class name of the called method.

The following four forms of calls are all forwarding calls:

  • self::

  • parent::

  • static::

  • ##forward_static_call()

Calls other than this are non-forwarding transfer.

Non-forwarding call(non-forwarding call)

The working principle of late static binding is to store the previous non-forwarding call(non -forwarding call) class name.

Calls made through specific class names or specific objects are non-forwarded calls.

for example:

A::test2(); 
B::test2(); 

(new A)->dd(); 
(new B)->dd();
Copy after login

注意事项

非静态环境下的私有方法的查找顺序

在非静态环境下,在类的非静态方法中,使用 $this 和 static 调用类的私有方法时,执行方式有所不同。

  • $this 会优先寻找所在定义范围(父类)中的私有方法,如果存在就调用。

  • static 是先到它指向的类(子类)中寻找私有方法,如果找到了就会报错,因为私有方法只能在它所定义的类内部调用;如果没找到,再去所在定义范围(父类)中寻找该私有方法,如果存在就调用。

具体来说,$this 会先到所在定义范围内寻找私有方法,再到它指向的对象所属的类中寻找私有方法,然后寻找公有方法,最后到所在定义范围内寻找公共方法。只要找到了匹配的方法,就调用,并停止查找。

而 static 则是先到它指向的类中寻找私有方法,再寻找共有方法;然后到所在定义范围内寻找私有方法,再寻找共有方法。只要找到了匹配的方法,就调用,并停止查找。

下面是一个例子:

<?php
 class  A  {    private function  foo () {
        var_dump($this); echo '--';
        var_dump(new static); echo '--';        echo __CLASS__; echo '--';        echo get_called_class();        echo '<br>';
    }    public function  test () {        $this -> foo ();        static:: foo ();        echo '<br>';
    }
}class  B  extends  A  { }class  C  extends  A  {    private function foo () {        echo 'this is C';
    }
}

(new  B())->test();
(new  C())->test();
Copy after login

输出结果为:

object(B)#1 (0) { } --object(B)#2 (0) { } --A--B
object(B)#1 (0) { } --object(B)#2 (0) { } --A--B

object(C)#1 (0) { } --object(C)#2 (0) { } --A--C

Fatal error: Uncaught Error: Call to private method C::foo() from context 'A'
Copy after login

关于后期静态绑定的解析

后期静态绑定的解析会一直到取得一个完全解析了的静态调用为止。如果静态调用使用了 parent:: 或者 self:: 等转发调用的形式,将会转发调用信息。

<?phpclass  A  {    public static function  foo () {        static:: who ();
    }    public static function  who () {        echo  __CLASS__ . "\n" ;
    }
}class  B  extends  A  {    public static function  test () {
        A :: foo ();        parent :: foo ();        self :: foo ();        static::foo();
        forward_static_call(['A', 'foo']);        echo '<br>';
    }    public static function  who () {        echo  __CLASS__ . "\n" ;
    }
}class  C  extends  B  {    public static function  who () {        echo  __CLASS__ . "\n" ;
    }    public static function test2() {        self::test();
    }
}class  D  extends  C  {    public static function  who () {        echo  __CLASS__ . "\n" ;
    }
}

B::foo();
B::test();

C::foo();
C::test();

D::foo();
D::test2();
Copy after login

以上的输出结果为:

B A B B B B 
C A C C C C D A D D D D
Copy after login

static 后期静态绑定的工作原理是存储了上一个非转发调用(non-forwarding call)的类名。请记住这句话。

下面的例子是非转发调用。

A::foo();  // 输出 AB::foo();   // 输出 BC::foo();   // 输出 C
Copy after login

后期静态绑定 static ,是定义在了 foo() 方法中,哪个类通过非转发调用的形式调用 foo() 方法, foo() 方法中的 static 指向的就是哪个类。

但是,如果通过转发调用的形式,调用 foo() 方法,如:

parent :: foo ();self :: foo ();static::foo();forward_static_call(['A', 'foo']);
Copy after login

那么,就以转发调用代码所在的方法 test() 为准,哪个类通过非转发调用的形式调用 test() 方法, foo() 方法中的 static 指向的就是哪个类。

假如调用 test() 方法时,也采用了转发调用的形式,如:

public static function test2() {    self::test();
}
Copy after login

那么,就以 test2() 方法为准 ... 依次类推。

也就是说,在使用了后期静态绑定的基类中,后期静态绑定所在的方法如果被转发调用,则 static 的指向,会一直向上追溯,直到遇到非转发调用的形式。

相关推荐:

php中const与static的区别与使用


The above is the detailed content of Detailed explanation of the differences between self, static, $this and late static binding in PHP. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Why NameResolutionError(self.host, self, e) from e and how to solve it Why NameResolutionError(self.host, self, e) from e and how to solve it Mar 01, 2024 pm 01:20 PM

The reason for the error is NameResolutionError(self.host,self,e)frome, which is an exception type in the urllib3 library. The reason for this error is that DNS resolution failed, that is, the host name or IP address attempted to be resolved cannot be found. This may be caused by the entered URL address being incorrect or the DNS server being temporarily unavailable. How to solve this error There may be several ways to solve this error: Check whether the entered URL address is correct and make sure it is accessible Make sure the DNS server is available, you can try using the "ping" command on the command line to test whether the DNS server is available Try accessing the website using the IP address instead of the hostname if behind a proxy

How to use self in Python How to use self in Python May 17, 2023 pm 10:40 PM

Before introducing the usage of self in Python, let’s first introduce the classes and instances in Python. We know that the most important concepts of object-oriented are classes and instances. Classes are abstract templates, such as abstract things like students. , can be represented by a Student class. Instances are specific "objects" created based on classes. Each object inherits the same methods from the class, but its data may be different. 1. Take the Student class as an example. In Python, the class is defined as follows: classStudent(object):pass(Object) indicates which class the class inherits from. The Object class is all

Let's talk about why Vue2 can access properties in various options through this Let's talk about why Vue2 can access properties in various options through this Dec 08, 2022 pm 08:22 PM

This article will help you interpret the vue source code and introduce why you can use this to access properties in various options in Vue2. I hope it will be helpful to everyone!

An article that understands this point and catches up with 70% of front-end people An article that understands this point and catches up with 70% of front-end people Sep 06, 2022 pm 05:03 PM

A colleague got stuck due to a bug pointed by this. Vue2’s this pointing problem caused an arrow function to be used, resulting in the inability to get the corresponding props. He didn't know it when I introduced it to him, and then I deliberately looked at the front-end communication group. So far, at least 70% of front-end programmers still don't understand it. Today I will share with you this link. If everything is wrong If you haven’t learned it yet, please give me a big mouth.

What is the function and usage of static in C language What is the function and usage of static in C language Jan 31, 2024 pm 01:59 PM

The role and usage of static in C language: 1. Variable scope; 2. Life cycle; 3. Internal function; 4. Modify global variables; 5. Modify function; 6. Other uses; Detailed introduction: 1. Variable scope, when If there is the static keyword before a variable, then the scope of the variable is limited to the file in which it is declared. In other words, the variable is a "file-level scope", which is very useful for preventing the "duplicate definition" problem of variables; 2. Life cycle, static variables are initialized once when the program starts executing, and destroyed when the program ends, etc.

How to use static, this, super, and final in Java How to use static, this, super, and final in Java Apr 18, 2023 pm 03:40 PM

1. static Please look at the following program first: publicclassHello{publicstaticvoidmain(String[]args){//(1)System.out.println("Hello, world!");//(2)}} Have seen this Segment programs are familiar to most people who have studied Java. Even if you have not learned Java but have learned other high-level languages, such as C, you should be able to understand the meaning of this code. It simply outputs "Hello, world" and has no other use. However, it shows the main purpose of the static keyword.

Practical application scenarios and usage skills of the static keyword in C language Practical application scenarios and usage skills of the static keyword in C language Feb 21, 2024 pm 07:21 PM

Practical application scenarios and usage skills of the static keyword in C language 1. Overview static is a keyword in C language, used to modify variables and functions. Its function is to change its life cycle and visibility during program running, making variables and functions static. This article will introduce the actual application scenarios and usage techniques of the static keyword, and illustrate it through specific code examples. 2. Static variables extend the life cycle of variables. Using the static keyword to modify local variables can extend their life cycle.

How to use Java modifiers abstract, static and final How to use Java modifiers abstract, static and final Apr 26, 2023 am 09:46 AM

Modifier abstract (abstract) 1. Abstract can modify a class (1) The class modified by abstract is called an abstract class (2) Syntax: abstractclass class name {} (3) Features: Abstract classes cannot create objects separately, but they can be declared Reference the abstract class name reference name; (4) Abstract classes can define member variables and member methods (5) Abstract classes have constructors. When used to create subclass objects, jvm creates a parent class object by default; abstract constructor methods apply Applied when jvm creates parent class object. 2. Abstract can modify methods (1) The method modified by asbtract is called an abstract method (2) Syntax: access modifier abstract return value

See all articles