使用
$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->foo()
调用foo()
成员函数 of whatever > 是当前对象的确切类型。如果对象是type X
,那么它 > 调用X::foo()
。如果对象是type Y
,则调用Y::foo()
。但是使用 > self :: foo(),总是调用X::foo()
。
来自http://www.phpbuilder.com/board/showthread.php?t=10354489 :
关键字自不仅仅指的是 “当前类的,至少不会在限制你的静态成员的一种方式。在非静态成员的上下文中, self
还提供了绕过当前对象的 vtable( 请参阅 vtable on vtable )的方法。正如您可以使用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”。现在考虑当我们创建一个继承自 this 的类时会发生什么:
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
调用Deceased::status()
我们希望看到 “Person is deceased” 但是我们看到的是 “Person is alive”,因为当定义调用self::getStatus()
时,scope 包含原始方法定义。
PHP 5.3 有一个解决方案。 static::
resolution 运算符实现了 “后期静态绑定”,这是一种说法,它被绑定到被调用类的范围。将status()
的行更改为static::getStatus()
,结果就是您所期望的。在旧版本的 PHP 中,你必须找到一个 kludge 来做到这一点。
请参阅PHP 文档
所以回答问题不是问...
$this->
指的是当前对象(类的一个实例),而static::
指的是一个类