题
在PHP5,之间的区别是什么使用 self
和 $this
?
当是每一个合适?
解决方案
简答
使用
$ this
来引用当前 宾语。使用self
来引用 现在的课程。换句话说,使用 非代理成员的$ this-> member
, 对静态成员使用self :: $ member
。
完整答案
以下是正确用于非静态和静态成员变量的 $ this
和 self
的示例:
<?php
class X {
private $non_static_member = 1;
private static $static_member = 2;
function __construct() {
echo $this->non_static_member . ' '
. self::$static_member;
}
}
new X();
?>
以下是错误使用 $ this
和 self
的非静态和静态成员变量的示例:
<?php
class X {
private $non_static_member = 1;
private static $static_member = 2;
function __construct() {
echo self::$non_static_member . ' '
. $this->static_member;
}
}
new X();
?>
以下是成员函数的多态与 $ this
的示例:
<?php
class X {
function foo() {
echo 'X::foo()';
}
function bar() {
$this->foo();
}
}
class Y extends X {
function foo() {
echo 'Y::foo()';
}
}
$x = new Y();
$x->bar();
?>
以下是使用 self
作为成员函数的抑制多态行为的示例:
<?php
class X {
function foo() {
echo 'X::foo()';
}
function bar() {
self::foo();
}
}
class Y extends X {
function foo() {
echo 'Y::foo()';
}
}
$x = new Y();
$x->bar();
?>
这个想法是
$ this-&gt; foo()
调用foo()
成员函数,无论当前对象的确切类型是什么。如果对象是类型X
,则它调用X :: foo()
。如果对象是类型Y
,则它调用Y :: foo()
。但是使用self :: foo(),总是调用X :: foo()
。
来自 http://www.phpbuilder.com/board/showthread.php ΔT= 10354489 :
其他提示
关键字self NOT 仅指“当前类”,至少不会限制您使用静态成员。在非静态成员的上下文中, self
还提供绕过vtable的方法(在vtable上查看wiki )以获取当前对象。正如您可以使用 parent :: methodName()
来调用函数的父版本,因此您可以调用 self :: methodName()
来调用当前的类实现一种方法。
class Person {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function getTitle() {
return $this->getName()." the person";
}
public function sayHello() {
echo "Hello, I'm ".$this->getTitle()."<br/>";
}
public function sayGoodbye() {
echo "Goodbye from ".self::getTitle()."<br/>";
}
}
class Geek extends Person {
public function __construct($name) {
parent::__construct($name);
}
public function getTitle() {
return $this->getName()." the geek";
}
}
$geekObj = new Geek("Ludwig");
$geekObj->sayHello();
$geekObj->sayGoodbye();
这将输出:
你好,我是路德维希的极客
再见路德维希的人
sayHello()
使用 $ this
指针,因此调用vtable来调用 Geek :: getTitle()
。
sayGoodbye()
使用 self :: getTitle()
,因此不使用vtable,并调用 Person :: getTitle()
。在这两种情况下,我们都在处理实例化对象的方法,并且可以访问被调用函数中的 $ this
指针。
请勿使用 self ::
,请使用 static ::
自我的另一个方面::值得一提。恼人地 self ::
是指定义点而不是执行点的范围。考虑这个简单的类有两种方法:
class Person
{
public static function status()
{
self::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
如果我们调用 Person :: status()
,我们将看到“Person is alive”。 。现在考虑当我们创建一个继承自此的类时会发生什么:
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
调用 Deceased :: status()
,我们希望看到“Person is deceased”然而,我们看到的是“人还活着”。当调用 self :: getStatus()
时,范围包含原始方法定义。
PHP 5.3有一个解决方案。 static ::
解析运算符实现了“后期静态绑定”。这是一种奇特的说法,它被称为类的范围。将 status()
中的行更改为 static :: getStatus()
,结果就是您所期望的。在旧版本的PHP中,你必须找到一个kludge来做到这一点。
请参阅 PHP文档
所以回答问题并不是问...
$ this-&gt;
引用当前对象(类的实例),而 static ::
引用类
要真正了解我们所谈论的时候,我们谈谈 self
与 $this
, ,实际上我们需要挖掘到了什么在概念和实际水平。我真的不感觉到任何答案,这样做适当的,因此,这里是我的尝试。
让我们开始谈论什么 类 和一个 对象 是。
课程和目的,在概念上
那么,是什么 是 一个 类?很多人将它定义为一个 蓝图 或 模板 对于一个对象。事实上,你可以读取更多的 关于类PHP在这里.和某种程度上这是什么,它确实是。让我们看看一个等级:
class Person {
public $name = 'my name';
public function sayHello() {
echo "Hello";
}
}
正如你可以告诉中,有一个属于该类的所谓的 $name
和方法(功能)被称为 sayHello()
.
它的 非常 重要的是要注意的 类 是一个静态结构。这意味着类 Person
, 一旦定义,都是一样的无处不在,你看看它。
一个物体在另一方面是什么所谓的 实例 一类。这意味着我们采取的"蓝图"的类,并用它来作一个动态复制。这个复制现已具体挂钩的可变它的存在。因此,任何改变 实例 是本地的,例。
$bob = new Person;
$adam = new Person;
$bob->name = 'Bob';
echo $adam->name; // "my name"
我们创新的 实例 一类使用 new
操作员。
因此,我们说,一类是一个全球性结构,对象是当地的结构。别担心搞笑的 ->
语法,我们要走到那一点点。
其他一件事我们该谈论的是,我们可以 检查 如果一个实例是 instanceof
一个特别类: $bob instanceof Person
返回布尔如果 $bob
实例是使用 Person
类, 或 一个孩子的 Person
.
定义国家
所以让我挖一点成什么的一类实际上包含的内容。有5种类型的"事情"这一类包括:
性能 -认为这些变量,每个实例中将包含的内容。
class Foo { public $bar = 1; }
静电特性 -认为这些变量是共用的分类级别。这意味着,他们永远不会被复制,通过每个实例。
class Foo { public static $bar = 1; }
方法 -这些是职能,每个实例中将包含(和操作上的实例)。
class Foo { public function bar() {} }
静态的方法 -这些职能共享跨整个类。他们做的 不 操作上的实例,但是,在静电特性只。
class Foo { public static function bar() {} }
常量 -流得到解决常量。不能让任何更深入这里,但加入为完整性:
class Foo { const BAR = 1; }
所以基本上,我们正在存储信息的类和物容器中使用的"暗示"有关 静 它确定是否共享信息(和因此,静态)或没有(并因此动态的)。
国家和方法
内部的一种方法,一种对象的实例是由 $this
变量。目前的状态,对象是存在的,并改变的(变化)的任何财产将导致改变实例(但不是其他人)。
如果一方法是所谓的静态, $this
变量 是不是定义.这是因为没有实例相关的一个静态的呼吁。
有趣的事情这里是如何静态的呼吁。因此,让我们来谈谈我们如何访问的状态:
访问的状态
所以现在,我们有储存的国家,我们需要进行访问。这可以获得有点棘手(或 方式 多一点),因此让我们分裂这两个观点:从外面的一个实例/类(说从一个正常功能的电话,或者从全球范围),以及内部的一个实例/类别(从方法上对象)。
从外面的一个实例/类
从外面的一个实例/类,我们的规则是相当简单的和可预测的。我们有两个运营商,并且每个告诉我们,如果我们要处理的一个实例或类静态:
->
- 目的-操 -这总是使用当我们在访问一个实例。$bob = new Person; echo $bob->name;
重要的是要注意到呼叫
Person->foo
没有意义的(因为Person
是一类的,不是一个实例)。因此,这是一个分析错误。::
- 范围分辨率运营商 -这总是用于访问一类的静态的财产或方法。echo Foo::bar()
此外,我们可以叫一个静态的方法中的对象相同的方式:
echo $foo::bar()
它的 非常 重要的是要注意的是,当我们这样做 从外面, ,目的是实例是隐藏的
bar()
法。这意味着它完全相同:$class = get_class($foo); $class::bar();
因此, $this
是不是定义中的静态的呼吁。
从内部的一个实例/类
事情变得有点在这里。同一营运者使用,但它们的含义变得明显模糊不清。
的 目的-操 ->
仍然被用来打电话的对象的实例的状态。
class Foo {
public $a = 1;
public function bar() {
return $this->a;
}
}
叫 bar()
方法上的 $foo
(一个实例 Foo
)使用对象的操作员: $foo->bar()
将结果的实例的版本 $a
.
所以这就是我们如何期望。
意思的 ::
操作人员虽然更改。它取决于下文呼吁的当前功能:
在一个静态的上下文
在一个静态的背景下,使用任何电话
::
也将是静态的。让我们看看一个例子:class Foo { public function bar() { return Foo::baz(); } public function baz() { return isset($this); } }
叫
Foo::bar()
会打电话的baz()
方法是静态的,因此$this
将 不 被填充。值得注意的是,在最近的版本的PHP(5.3+),这将触发一个E_STRICT
错误的,因为我们呼吁非静静态的方法.在实例上下文
在实例上下文另一方面,呼吁使用
::
取决于接收器的电话(该方法我们称).如果该方法被定义为static
, 然后将使用一个静态的呼吁。如果不是,它将向该信息的实例。所以,看上述代码、呼叫
$foo->bar()
将返回true
, ,因为"静态"呼内发生的一个实例,上下文。
有意义吗?不这样认为。这是令人困惑。
短切的关键字
因为绑在一起的一切使用类名称而不是肮脏的,PHP提供3个基本的"捷径"的关键词,以使范围解决更容易。
self
-这是指前类名称。所以self::baz()
是一样的Foo::baz()
内Foo
类(任何方法上它)。parent
-这是指父母的当前类。static
-这是指所谓的类。由于继承、子类可以替代方法和静态的性质。所以打电话给他们使用static
而不是一类名允许我们解决那里呼叫的来源,而不是目前的水平。
例
最简单的方法来理解这是开始看一些例子。让我们挑一类:
class Person {
public static $number = 0;
public $id = 0;
public function __construct() {
self::$number++;
$this->id = self::$number;
}
public $name = "";
public function getName() {
return $this->name;
}
public function getId() {
return $this->id;
}
}
class Child extends Person {
public $age = 0;
public function __construct($age) {
$this->age = $age;
parent::__construct();
}
public function getName() {
return 'child: ' . parent::getName();
}
}
现在,我们也在考虑继承这里。忽略一个时刻,这是一个糟糕的对象模型,但是让我们看看会发生什么,当我们玩这个:
$bob = new Person;
$bob->name = "Bob";
$adam = new Person;
$adam->name = "Adam";
$billy = new Child;
$billy->name = "Billy";
var_dump($bob->getId()); // 1
var_dump($adam->getId()); // 2
var_dump($billy->getId()); // 3
所以ID计数是跨越两个实例,儿童(因为我们使用 self
访问。如果我们使用 static
, 我们可以复盖它在一个孩子类)。
var_dump($bob->getName()); // Bob
var_dump($adam->getName()); // Adam
var_dump($billy->getName()); // child: Billy
注意,我们执行 Person::getName()
实例 方法每一次。但是,我们使用 parent::getName()
要做到这一情况下(儿童情况)。这是什么使得这种方法强有力的。
词谨慎的#1
注意,调用的上下文中是什么决定,如果一个实例是使用。因此:
class Foo {
public function isFoo() {
return $this instanceof Foo;
}
}
是不是 总是 真的。
class Bar {
public function doSomething() {
return Foo::isFoo();
}
}
$b = new Bar;
var_dump($b->doSomething()); // bool(false)
现在是 真的 奇怪这里。我们叫一个不同的类,但是 $this
获得通过的 Foo::isFoo()
方法的实例 $bar
.
这可能导致各种各样的错误概念。-红霉素.所以我强烈建议避免的 ::
操作者从实例的方法上的任何东西除了这三个虚拟的"捷径"的关键词(static
, self
, , parent
).
词谨慎的#2
注意到静态的方法和性质是共享的所有人。即使他们基本上全球变量。与所有的同样的问题带来的全局.因此,我将真的不愿储存信息以静态的方法/属性,除非你舒服它真正全球性的。
词谨慎的#3
一般的你会想要使用什么作为迟交的静态约束力通过使用 static
而不是的 self
.但请注意,他们不是同样的事情,所以说"总是用 static
而不是的 self
真是短视的。相反,停止并认为有关称呼你想要做,并认为如果你想要孩子类能够复盖, 静态的解决了 呼叫。
TL/博士
太糟糕了,回去读它。它可能太长,但这是长期的,因为这是一个复杂的主题
TL/DR#2
好的,好的。在短短的, self
是用来参考 当前类的名字 在一个类,在那里因为 $this
指的是目前的对象 实例.注意, self
是一个复制、粘贴的短期削减。你可以安全地替换您的类的名称,并将做工精细。但 $this
是一个动态的变量,不可能确定的时间提前(和甚至可能不是你的类)。
TL/DR#3
如果对象是操作者使用(->
),然后你 总是 知道你正在处理的一个实例。如果范围分辨率运营商用(::
),需要更多的信息的背景下(我们是在对象方面已经?我们之外的对象?等等)。
self
(不是$ self)指的是类的类型,其中 $ this
指的是当前的实例班级。 self
用于静态成员函数,以允许您访问静态成员变量。 $ this
用于非静态成员函数,并且是对调用成员函数的类实例的引用。
因为这个
是一个对象,所以你可以使用它: $ this-&gt; member
因为 self
不是一个对象,它基本上是一个自动引用当前类的类型,你可以使用它: self :: member
$ this-&gt;
用于引用类变量(成员变量)或方法的特定实例。
Example:
$derek = new Person();
$ derek现在是Person的特定实例。 每个Person都有first_name和last_name,但$ derek有一个特定的first_name和last_name(Derek Martin)。在$ derek实例中,我们可以将它们称为$ this-&gt; first_name和$ this-&gt; last_name
ClassName ::用于引用该类型的类及其静态变量,静态方法。如果它有帮助,你可以在心理上取代“静态”这个词。与“共享”。因为它们是共享的,所以它们不能引用$ this,它引用特定的实例(不共享)。静态变量(即静态$ db_connection)可以在一种对象的所有实例之间共享。例如,所有数据库对象共享一个连接(静态$ connection)。
静态变量示例: 假设我们有一个带有单个成员变量的数据库类:static $ num_connections; 现在,把它放在构造函数中:
function __construct()
{
if(!isset $num_connections || $num_connections==null)
{
$num_connections=0;
}
else
{
$num_connections++;
}
}
就像对象有构造函数一样,它们也有析构函数,它们在对象死亡或未设置时执行:
function __destruct()
{
$num_connections--;
}
每次我们创建一个新实例时,它都会将我们的连接计数器增加一个。每次我们销毁或停止使用实例时,它都会将连接计数器减少一个。通过这种方式,我们可以监视我们使用的数据库对象的实例数:
echo DB::num_connections;
因为$ num_connections是静态的(共享),它将反映活动数据库对象的总数。您可能已经看到过这种技术用于在数据库类的所有实例之间共享数据库连接。这样做是因为创建数据库连接需要很长时间,因此最好只创建一个并共享它(这称为单例模式)。
静态方法(即公共静态View :: format_phone_number($ digits))可以在没有首先实例化其中一个对象的情况下使用(即它们不在内部引用$ this)。
静态方法示例:
public static function prettyName($first_name, $last_name)
{
echo ucfirst($first_name).' '.ucfirst($last_name);
}
echo Person::prettyName($derek->first_name, $derek->last_name);
如您所见,public static function prettyName对该对象一无所知。它只是处理你传入的参数,就像一个不属于对象的普通函数。那么,为什么我们不能把它作为对象的一部分呢?
- 首先,将功能附加到对象可以帮助您保持组织有序,因此您知道在哪里找到它们。
- 其次,它可以防止命名冲突。在一个大项目中,您可能有两个开发人员创建getName()函数。如果一个创建一个ClassName1 :: getName(),另一个创建ClassName2 :: getName(),那就没问题了。没有冲突。 Yay静态方法! 醇>
<强> SELF :: 强> 如果您在外部编码具有您想要引用的静态方法的对象,则必须使用对象的名称View :: format_phone_number($ phone_number)调用它; 如果你在里面编码你想要引用静态方法的对象,你可以 使用对象的名称View :: format_phone_number($ pn),或者你可以使用self :: format_phone_number($ pn)快捷方式
静态变量也是如此: 示例:查看:: templates_path与self :: templates_path
在DB类中,如果我们引用某个其他对象的静态方法,我们将使用该对象的名称: 示例: Session :: getUsersOnline();
但是如果DB类想要引用它自己的静态变量,它只会说自己: 示例: self :: connection;
希望有助于澄清事情:)
从 这篇文章:
self
是指当前类self
可以用来打电话静态功能和参考静态部件的变量self
可用于内部的静态功能self
也可以关闭多态性行为绕过虚表$this
指的是目前的对象$this
可以用来打电话静态功能$this
不应当被用来打电话的静态部件的变量。使用self
代替。$this
不能使用内部的静态功能
在PHP中,您使用self关键字来访问静态属性和方法。
问题是你可以在任何地方用 self :: method()
替换 $ this-&gt; method()
,无论 method()
被声明为静态或不是。那么你应该使用哪一个?
考虑以下代码:
class ParentClass {
function test() {
self::who(); // will output 'parent'
$this->who(); // will output 'child'
}
function who() {
echo 'parent';
}
}
class ChildClass extends ParentClass {
function who() {
echo 'child';
}
}
$obj = new ChildClass();
$obj->test();
在此示例中, self :: who()
将始终输出&#8216; parent&#8217;,而 $ this-&gt; who()
将依赖关于对象有什么类。
现在我们可以看到self指的是调用它的类,而 $ this
指的是当前对象的类。
因此,只有在 $ this
不可用时,或者当您不希望允许后代类覆盖当前方法时,才应使用self。
在类定义中,$ this引用当前对象,而self引用当前类。
有必要使用self引用类元素,并使用$ this引用对象元素。
self::STAT // refer to a constant value
self::$stat // static variable
$this->stat // refer to an object variable
这是一个正确使用$ this和self用于非静态的示例 和静态成员变量:
<?php
class X {
private $non_static_member = 1;
private static $static_member = 2;
function __construct() {
echo $this->non_static_member . ' '
. self::$static_member;
}
}
new X();
?>
根据 http://www.php.net/manual /en/language.oop5.static.php 没有 $ self
。只有 $ this
,用于引用类(对象)的当前实例,以及self,可用于引用类的静态成员。对象实例和类之间的区别在这里发挥作用。
self
指当前类(在其中调用它),
$ this
指当前对象。
你可以使用static而不是self。
参见示例:
class ParentClass {
function test() {
self::which(); // output 'parent'
$this->which(); // output 'child'
}
function which() {
echo 'parent';
}
}
class ChildClass extends ParentClass {
function which() {
echo 'child';
}
}
$obj = new ChildClass();
$obj->test();
输出: 亲 子
- 的对象的指针$这指的是当前的对象。
- 类价值"静态"是指目前的对象。
- 类价值"自助"是指精确类定义。
- 类价值"父母"指的是父母的确切类定义。
看到以下的例子,其中显示了超载。
<?php
class A {
public static function newStaticClass()
{
return new static;
}
public static function newSelfClass()
{
return new self;
}
public function newThisClass()
{
return new $this;
}
}
class B extends A
{
public function newParentClass()
{
return new parent;
}
}
$b = new B;
var_dump($b::newStaticClass()); // B
var_dump($b::newSelfClass()); // A because self belongs to "A"
var_dump($b->newThisClass()); // B
var_dump($b->newParentClass()); // A
class C extends B
{
public static function newSelfClass()
{
return new self;
}
}
$c = new C;
var_dump($c::newStaticClass()); // C
var_dump($c::newSelfClass()); // C because self now points to "C" class
var_dump($c->newThisClass()); // C
var_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"
大多数时间你想要提到当前的类这就是为什么你使用 static
或 $this
.然而,有时候当你 需要 self
因为您想要的原类不论什么样的延伸。(非常,非常偶尔)
由于这里没有人谈到表演,这里有一个小基准(5.6):
Name | Time | Percent
----------|---------|---------
$this-> | 0.99163 | 106.23%
self:: | 0.96912 | 103.82%
static:: | 0.93348 | 100%
这是2 000 000次运行的结果,这是我使用的代码:
<?php
require '../vendor/autoload.php';
// My small class to do benchmarks
// All it does is looping over every test x times and record the
// time it takes using `microtime(true)`
// Then, the percentage is calculated, with 100% being the quickest
// Times are being rouned for outputting only, not to calculate the percentages
$b = new Tleb\Benchmark\Benchmark(2000000);
class Foo
{
public function calling_this()
{
$this->called();
}
public function calling_self()
{
self::called();
}
public function calling_static()
{
static::called();
}
public static function called()
{
}
}
$b->add('$this->', function () { $foo = new Foo; $foo->calling_this(); });
$b->add('self::', function () { $foo = new Foo; $foo->calling_self(); });
$b->add('static::', function () { $foo = new Foo; $foo->calling_static(); });
$b->run();
我相信问题不是你是否可以通过调用 ClassName :: staticMember
来调用类的静态成员。问题是使用 self :: classmember
和 $ this-&gt; classmember
之间的区别。
例如,以下两个示例都可以正常运行,无论您使用 self ::
还是 $ this-&gt;
class Person{
private $name;
private $address;
public function __construct($new_name,$new_address){
$this->name = $new_name;
$this->address = $new_address;
}
}
class Person{
private $name;
private $address;
public function __construct($new_name,$new_address){
self::$name = $new_name;
self::$address = $new_address;
}
}
当 self
与 ::
运算符一起使用时,它引用当前类,可以在静态和非静态上下文中完成。 $ this
指的是对象本身。此外,使用 $ this
来调用静态方法(但不是引用字段)是完全合法的。
$ this
指的是当前的类对象, self
指的是当前的类(Not object)。该类是对象的蓝图。所以你定义了一个类,但是你构造了对象。
换句话说,对于非静态成员或方法,使用 self for static
和 this。
也在子/父场景中 self / parent
主要用于识别子类和父类成员和方法。
此外,由于 $ this ::
尚未讨论过。
仅供参考,从PHP 5.3开始处理实例化对象以获取当前作用域值时,与使用 static ::
相反,可以使用 $ this ::
就像这样。
class Foo
{
const NAME = 'Foo';
//Always Foo::NAME (Foo) due to self
protected static $staticName = self::NAME;
public function __construct()
{
echo $this::NAME;
}
public function getStaticName()
{
echo $this::$staticName;
}
}
class Bar extends Foo
{
const NAME = 'FooBar';
/**
* override getStaticName to output Bar::NAME
*/
public function getStaticName()
{
$this::$staticName = $this::NAME;
parent::getStaticName();
}
}
$foo = new Foo; //outputs Foo
$bar = new Bar; //outputs FooBar
$foo->getStaticName(); //outputs Foo
$bar->getStaticName(); //outputs FooBar
$foo->getStaticName(); //outputs FooBar
使用上面的代码不是常见的或推荐的做法,而只是为了说明其用法,并且更像是“你知道吗?”。参考原始海报的问题。
它还表示 $ object :: CONSTANT
的用法,例如 echo $ foo :: NAME;
,而不是 $ this :: NAME; 代码>
我遇到了同样的问题,简单的答案是:
- $this 需要一个类实例
- 自:: 不不
只要你使用 静态的方法 或 静态属性 并想给他们打电话没有目的流化需要使用 自:: 给他们打电话,因为 $this 总是需要在目的创建。
如果要在不创建该类的对象/实例的情况下调用类的方法,请使用 self
,从而保存 RAM (有时为此目的使用self)。换句话说,它实际上是静态调用方法。使用 this
作为对象透视图。
案例1:使用 self
可用于类常量
class classA { const FIXED_NUMBER = 4; self::POUNDS_TO_KILOGRAMS }
如果你想在课外调用它,使用 classA :: POUNDS_TO_KILOGRAMS
来访问常量
案例2:对于静态属性
class classC { public function __construct() { self::案例1:使用
self
可用于类常量class classA { const FIXED_NUMBER = 4; self::POUNDS_TO_KILOGRAMS }如果你想在课外调用它,使用
classA :: POUNDS_TO_KILOGRAMS
来访问常量案例2:对于静态属性
<*>counter++; $this->num = self::案例1:使用
self
可用于类常量class classA { const FIXED_NUMBER = 4; self::POUNDS_TO_KILOGRAMS }如果你想在课外调用它,使用
classA :: POUNDS_TO_KILOGRAMS
来访问常量案例2:对于静态属性
<*>counter; } }
根据php.net,在此上下文中有三个特殊关键字: self
, parent
和 static
。它们用于从类定义中访问属性或方法。
$ this
用于调用任何类的实例和方法,只要该类可以访问。