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

什么时候合适?


当前回答

self(不是$self)指的是类的类型,而$this指的是该类的当前实例。self用于静态成员函数,允许您访问静态成员变量$这用于非静态成员函数,是对调用成员函数的类实例的引用。

因为这是一个对象,所以可以像这样使用它:$this->member

因为self不是一个对象,所以它基本上是一个自动引用当前类的类型。您可以像: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();
?> 

情况1:使用self可以用于类常量

 class classA { 
     const FIXED_NUMBER = 4; 
     self::POUNDS_TO_KILOGRAMS
}

如果要在类外部调用它,请使用classA::POUNDS_to_KILOGAMS访问常量

情况2:对于静态财产

class classC {
     public function __construct() { 
     self::$_counter++; $this->num = self::$_counter;
   }
}

在类定义中,$this引用当前对象,而self引用当前类。

必须使用self引用类元素,并使用$this引用对象元素。

self::STAT // refer to a constant value
self::$stat // static variable
$this->stat // refer to an object variable  

我认为问题不在于是否可以通过调用ClassName::staticMember来调用类的静态成员。问题是使用self::classmember和$this->classmember之间有什么区别。

例如,无论您使用self::还是$this->,以下两个示例都可以正常工作,没有任何错误

class Person{
    private $name;
    private $address;

    public function __construct($new_name,$new_address){
        $this->name = $new_name;
        $this->address = $new_address;
    }
}

class Person{
    private $name;
    private $address;
    public function __construct($new_name,$new_address){
        self::$name = $new_name;
        self::$address = $new_address;
    }
}

关键字self不仅仅指“当前类”,至少不会限制静态成员。在非静态成员的上下文中,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指针。