协慌网

登录 贡献 社区

什么时候使用自我超过 $?

在 PHP 5 中,使用self$this什么区别?

什么时候适合?

答案

简答

使用$this来引用当前对象。使用self来引用当前类。换句话说,对非静态成员使用$this->member ,对静态成员使用self::$member

完整答案

以下是对非静态和静态成员变量正确使用$thisself的示例:

<?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();
?>

以下是对非静态和静态成员变量使用$thisself错误示例:

<?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

通过http://board.phpbuilder.com/member.php?145249-laserlight

关键字自不仅仅指的是 “当前类的,至少不会在限制你的静态成员的一种方式。在非静态成员的上下文中, 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::指的是一个类