Когда использовать себя сверх $ this? - PullRequest
1891 голосов
/ 30 сентября 2008

В PHP 5, в чем разница между использованием self и $this?

Когда каждый уместен?

Ответы [ 22 ]

20 голосов
/ 30 сентября 2008

По http://www.php.net/manual/en/language.oop5.static.php нет $self. Существует только $this для ссылки на текущий экземпляр класса (объект) и self, которые можно использовать для ссылки на статические члены класса. Здесь возникает разница между экземпляром объекта и классом.

15 голосов
/ 01 января 2016

self относится к текущему классу (в котором он называется),

$this относится к текущему объекту. Вы можете использовать статические вместо себя. Смотрите пример:

    class ParentClass {
            function test() {
                    self::which();  // output 'parent'
                    $this->which(); // output 'child'
            }

            function which() {
                    echo 'parent';
            }
    }

    class ChildClass extends ParentClass {
            function which() {
                    echo 'child';
            }
    }

    $obj = new ChildClass();
    $obj->test();

Выход: родитель ребенок

14 голосов
/ 18 мая 2009

Я считаю, что вопрос был не в том, можно ли вызвать статический член класса, вызвав 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;
    }
}
14 голосов
/ 31 мая 2015

Поскольку здесь никто не говорил о выступлениях, вот небольшой тест, который я сделал (5.6):

 Name     | Time    | Percent  
----------|---------|---------  
 $this->  | 0.99163 | 106.23%  
 self::   | 0.96912 | 103.82%  
 static:: | 0.93348 | 100%

Это результаты для 2 000 000 прогонов, и вот код, который я использовал:

<?php

require '../vendor/autoload.php';

// My small class to do benchmarks
// All it does is looping over every test x times and record the
//   time it takes using `microtime(true)`
// Then, the percentage is calculated, with 100% being the quickest
// Times are being rouned for outputting only, not to calculate the percentages
$b = new Tleb\Benchmark\Benchmark(2000000);

class Foo
{
    public function calling_this()
    {
        $this->called();
    }

    public function calling_self()
    {
        self::called();
    }

    public function calling_static()
    {
        static::called();
    }

    public static function called()
    {
    }
}

$b->add('$this->',  function () { $foo = new Foo; $foo->calling_this(); });
$b->add('self::',   function () { $foo = new Foo; $foo->calling_self(); });
$b->add('static::', function () { $foo = new Foo; $foo->calling_static(); });

$b->run();
14 голосов
/ 22 марта 2013
  • Указатель объекта $ this ссылается на текущий объект.
  • Значение класса «static» относится к текущему объекту.
  • Значение класса «self» относится к точному классу, в котором оно было определено.
  • Значение класса «parent» относится к родительскому элементу точного класса, в котором он был определен.

См. Следующий пример, показывающий перегрузку.

<?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, потому что вам нужен оригинальный класс, независимо от того, что его расширяет. (Очень, очень редко)

13 голосов
/ 22 марта 2013

Когда self используется с оператором ::, это относится к текущему классу, что может быть сделано как в статическом, так и в нестатическом контексте. $this относится к самому объекту. Кроме того, совершенно законно использовать $this для вызова статических методов (но не для ссылки на поля).

7 голосов
/ 29 сентября 2014

Кроме того, поскольку $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;

.
7 голосов
/ 15 сентября 2014

$this относится к текущему классу объекта, self относится к текущему классу (не объекту). Класс - это план объекта. Итак, вы определяете класс, но создаете объекты.

То есть, другими словами, используйте self for static и this for none-static members or methods.

также в дочернем / родительском сценарии self / parent в основном используется для идентификации дочерних и родительских членов класса и методов.

5 голосов
/ 19 мая 2018

Я столкнулся с тем же вопросом, и простой ответ:

  • $ this требуется экземпляр класса
  • self :: не

Всякий раз, когда вы используете статические методы или статические атрибуты и хотите вызывать их без создания объекта класса, вам необходимо использовать self :: чтобы вызвать их, потому что $ this всегда требует создания объекта.

5 голосов
/ 10 апреля 2013

Используйте self, если вы хотите вызвать метод класса, не создавая объект / экземпляр этого класса, сохраняя, таким образом, RAM (иногда для этой цели используйте self). Другими словами, это фактически вызывает метод статически. Используйте this для перспективы объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...