When to use Self vs $this in PHP?
I see as a very frequent doubt:
When should we use self::
, or $this
in PHP. Which shape is more suitable for use and what is the difference of the 2 situations?
5 answers
In simplified Form, $this
refers to the current object (instance), and self
refers to the class. Therefore, as a general rule, one uses $this
to access members (attributes, methods) of the instance and self
to access static members.
Inheritance
When using inheritance, however, there is a difference between using self
and $this
when calling an instance method:
-
self::metodo()
calls themetodo()
of the current class; -
$this->metodo()
calls themetodo()
of the class used to instantiate the object being executed (which can be a subclass of the class where the call is made). You can find out what class this is by usingget_class($this)
.
Example:
<?php
class Animal {
public function teste() {
echo "\$this é instância de " . get_class($this) . "\n";
// chama Animal::fala(), independentemente do
// tipo da instância
echo "self::fala(): ";
self::fala();
// chama fala() na classe usada pra instanciar
// este objeto
echo "\$this->fala(): ";
$this->fala();
}
public function fala() {
echo "Oi\n";
}
}
class Gato extends Animal {
public function fala() {
echo "Miau\n";
}
}
// Nesse caso, self != get_class($this)
// - self == Animal
// - get_class($this) == Gato
$gato = new Gato();
$gato->teste();
echo "\n";
// Nesse caso, self == get_class($this) == Animal
$animal = new Animal();
$animal->teste();
?>
Result:
$this é instância de Gato
self::fala(): Oi
$this->fala(): Miau
$this é instância de Animal
self::fala(): Oi
$this->fala(): Oi
The difference is that self is for when the class (or instance), is in a static context (be it a method or property), and obviously this is when it is not static.
$this
it is used within the class to access object properties / methods.
self
is used to access static members.
$this points to the object and self points to the class itself.
Self can also be used when the class extends another and you want to access its implementation or its relative for example
self::teste();
Or
parent::teste();
But usually self will be used to access static data of the class.
In general, we use $this
to maintain encapsulation and avoid colliding information from one object into the other.
If for some reason you need to share information with all instances of a class, that's where the static variables come in, let's look at an example:
<?php
class Notebook
{
private static $quantidadeDisponivel = 5;
public function getQuantidadeDisponivel()
{
return self::$quantidadeDisponivel;
}
public function comprar()
{
/**
* Realiza o processo de compra do notebook e atualiza quantidade disponivel
*/
self::$quantidadeDisponivel--;
}
}
$carrinhoJoao = new Notebook;
$carrinhoJoao->comprar();
$notebooksRestantes = $carrinhoJoao->getQuantidadeDisponivel();
print $notebooksRestantes; // imprime 4
$carrinhoPedro = new Notebook;
$carrinhoPedro->comprar();
$notebooksRestantes = $carrinhoPedro->getQuantidadeDisponivel();
print $notebooksRestantes; // imprime 3
$carrinhoPaulo = new Notebook;
$carrinhoPaulo->comprar();
$notebooksRestantes = $carrinhoPaulo->getQuantidadeDisponivel();
print $notebooksRestantes; // imprime 2
$carrinhoJoao->comprar();
$notebooksRestantes = $carrinhoJoao->getQuantidadeDisponivel();
print $notebooksRestantes; // imprime 1
$carrinhoPedro->comprar();
$notebooksRestantes = $carrinhoPedro->getQuantidadeDisponivel();
print $notebooksRestantes; // imprime 0
Without the use of variable statica, it would not be so simple to do this control, see:
class Desktop
{
private $quantidadeDisponivel = 5;
public function getQuantidadeDisponivel()
{
return $this->quantidadeDisponivel;
}
public function comprar()
{
/**
* Realiza o processo de compra do notebook e atualiza a quantidade disponível
*/
$this->quantidadeDisponivel--;
}
}
$carrinhoJoao = new Desktop;
$carrinhoJoao->comprar();
$notebooksRestantes = $carrinhoJoao->getQuantidadeDisponivel();
print $notebooksRestantes; // imprime 4
$carrinhoPedro = new Desktop;
$carrinhoPedro->comprar();
$notebooksRestantes = $carrinhoPedro->getQuantidadeDisponivel();
print $notebooksRestantes; // imprime 4
$carrinhoPaulo = new Desktop;
$carrinhoPaulo->comprar();
$notebooksRestantes = $carrinhoPaulo->getQuantidadeDisponivel();
print $notebooksRestantes; // imprime 4
As we have seen, with the use of the static variable we had the result 4,3,2,1,0 and with the common variable we had 4,4,4, the computers would continue to be sold even if they were finished.
(this example is merely educational!)