在PHP5中,使用self和$this有什么区别?

什么时候合适?


当前回答

简短回答

使用$this表示当前对象使用self指代当前类别。换句话说,使用$this->非静态成员的成员,对静态成员使用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(()成员函数。如果对象是X类型,那么它将调用X::foo()。如果对象类型为Y,则调用Y::foo()。但是对于self::foo(),总是调用X::foo()。

从…起http://www.phpbuilder.com/board/showthread.php?t=10354489:

通过http://board.phpbuilder.com/member.php?145249-激光灯

其他回答

此外,由于$this::尚未讨论。

仅供参考,从PHP 5.3开始,当处理实例化对象以获取当前作用域值时,与使用static::不同,可以选择使用$this::这样。

http://ideone.com/7etRHy

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相反;

当self与::运算符一起使用时,它引用当前类,这可以在静态和非静态上下文中完成$这是指对象本身。此外,使用$this调用静态方法(但不引用字段)是完全合法的。

以下是$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指向当前对象。类值static引用当前对象。类值self引用了它在中定义的确切类。类值父级是指它在中定义的确切类的父级。

请参见以下显示过载的示例。

<?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。只有$this用于引用类(对象)的当前实例,self用于引用类的静态成员。对象实例和类之间的区别在这里发挥作用。