When to use self over $this?
In PHP 5, what is the difference between using self and $this ?
When is each appropriate?
Short Answer
Use $this to refer to the current object. Use self to refer to the current class. In other words, use $this->member for non-static members, use self::$member for static members.
Full Answer
Here is an example of correct usage of $this and self for non-static and static member variables:
<?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();
?>
Here is an example of incorrect usage of $this and self for non-static and static member variables:
<?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();
?>
Here is an example of polymorphism with $this for member functions:
<?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();
?>
Here is an example of suppressing polymorphic behaviour by using self for member functions:
<?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();
?>
The idea is that $this->foo() calls the foo() member function of whatever >is the exact type of the current object. If the object is of type X , it thus >calls X::foo() . If the object is of type Y , it calls Y::foo() . But with >self::foo(), X::foo() is always called.
From http://www.phpbuilder.com/board/showthread.php?t=10354489:
By http://board.phpbuilder.com/member.php?145249-laserlight
The keyword self does NOT refer merely to the 'current class', at least not in a way that restricts you to static members. Within the context of a non-static member, self also provides a way of bypassing the vtable (see wiki on vtable) for the current object. Just as you can use parent::methodName() to call the parents version of a function, so you can call self::methodName() to call the current classes implementation of a method.
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();
This will output:
Hello, I'm Ludwig the geek
Goodbye from Ludwig the person
sayHello() uses the $this pointer, so the vtable is invoked to call Geek::getTitle() . sayGoodbye() uses self::getTitle() , so the vtable is not used, and Person::getTitle() is called. In both cases, we are dealing with the method of an instantiated object, and have access to the $this pointer within the called functions.
DO NOT USE self:: , use static::
There is another aspect of self:: that is worth mentioning. Annoyingly self:: refers to the scope at the point of definition not at the point of execution . Consider this simple class with two methods:
class Person
{
public static function status()
{
self::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
If we call Person::status() we will see "Person is alive" . Now consider what happens when we make a class that inherits from this:
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Calling Deceased::status() we would expect to see "Person is deceased" however what we see is "Person is alive" as the scope contains the original method definition when call to self::getStatus() was defined.
PHP 5.3 has a solution. the static:: resolution operator implements "late static binding" which is a fancy way of saying that its bound to the scope of the class called. Change the line in status() to static::getStatus() and the results are what you would expect. In older versions of PHP you will have to find a kludge to do this.
See PHP Documentation
So to answer the question not as asked ...
$this-> refers to the current object (an instance of a class), whereas static:: refers to a class
下一篇: 何时使用自己超过$这?
