何时使用自己超过$这?
在PHP 5中,使用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->foo()
调用任何>是当前对象的确切类型的foo()
成员函数。 如果对象是type X
,那么它调用X::foo()
。 如果对象是type Y
,则它调用Y::foo()
。 但是通过> self :: foo(),总是调用X::foo()
。
从http://www.phpbuilder.com/board/showthread.php?t=10354489:
通过http://board.phpbuilder.com/member.php?145249-laserlight
关键字自不仅仅指的是“当前类的,至少不会在限制你的静态成员的一种方式。 在非静态成员的上下文中, 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”,但是我们看到的是“Person is alive”,因为当定义调用self::getStatus()
时,作用域包含原始方法定义。
PHP 5.3有一个解决方案。 static::
resolution操作符实现了“后期静态绑定”,这是一种说法,它被绑定到所调用类的范围上。 将status()
的行更改为static::getStatus()
,结果如您所愿。 在旧版本的PHP中,你必须找到一个kludge来做到这一点。
请参阅PHP文档
所以要回答这个问题并不像问...
$this->
指向当前对象(类的一个实例),而static::
指向一个类