何时使用自己超过$这?

在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()成员函数。 如果对象是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::指向一个类

链接地址: http://www.djcxy.com/p/6445.html

上一篇: When to use self over $this?

下一篇: How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ?