A definição de uma classe começa com a palavra chave class, seguida do nome da classe, seguido de um par de colchetes que englobam as definições de propriedades e métodos pertecentes à classe.
O nome de uma classe tem de ser válido, que não seja uma palavra reservada do PHP. Um nome de classe válido começa com uma letra ou sublinhado, seguido de qualquer sequência de letras, números e sublinhados. Como uma expressão regular, pode ser expressada assim: ^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$.
Uma classe pode conter suas próprias constantes, variáveis (chamadas de "propriedades") e funções (chamadas de "métodos").
Exemplo #1 Definição Simples de uma Classe
<?php
class SimpleClass
{
// declaração de propriedade
public $var = 'um valor padrão';
// declaração de método
public function displayVar() {
echo $this->var;
}
}
?>
A pseudo-variável $this está disponível quando um método é chamado a partir de um contexto de objeto. $this é uma referência ao objeto chamado (normalmente o objeto ao qual o método pertence, mas possivelmente outro objeto, se o método é chamado estaticamente a partir do contexto de um objeto secundário).
Exemplo #2 Alguns exemplos da pseudo variável $this
<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this está definida (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this não está definida.\n";
}
}
}
class B
{
function bar()
{
// Nota: a próxima linha pode lançar um warning E_STRICT.
A::foo();
}
}
$a = new A();
$a->foo();
// Nota: a próxima linha pode lançar um warning E_STRICT.
A::foo();
$b = new B();
$b->bar();
// Nota: a próxima linha pode lançar um warning E_STRICT.
B::bar();
?>
O exemplo acima irá imprimir:
$this está definida (A) $this não está definida. $this está definida (B) $this não está definida.
Para criar uma instância de uma classe, a instrução new deve ser utilizada. Um objeto sempre será criado a não ser que a classe tenha um construtor definido que dispare uma exceção em caso de erro. Classes devem ser definidas antes de instanciadas (e em alguns casos isso é obrigatório).
Se uma string contendo o nome da classe é utilizado com new, uma nova instância da classe será criada. Se a classe estiver dentro de um namespace, o nome completo e qualificado deve ser utilizado para fazer isso.
Exemplo #3 Criando uma instância
<?php
$instance = new SimpleClass();
// Também pode ser feito com uma variável:
$className = 'SimpleClass';
$instance = new $className(); // new SimpleClass()
?>
No contexto da classe, é possível criar um novo objeto com new self e new parent.
Ao atribuir uma instância de uma classe já criada, a uma variável nova, a variável nova irá acessar a mesma instância do objeto que foi atribuído. Este comportamento se mantém ao se passar instâncias a uma função. Uma cópia de um objeto criado pode ser feita clonando o mesmo.
Exemplo #4 Atribuição de Objetos
<?php
$instance = new SimpleClass();
$assigned = $instance;
$reference =& $instance;
$instance->var = '$assigned terá esse valor';
$instance = null; // $instance e $reference tornam-se nulos
var_dump($instance);
var_dump($reference);
var_dump($assigned);
?>
O exemplo acima irá imprimir:
NULL NULL object(SimpleClass)#1 (1) { ["var"]=> string(30) "$assigned terá esse valor" }
O PHP 5.3.0 introduziu algumas novas formas de criar instâncias de um objeto:
Exemplo #5 Criando novos objetos
<?php
class Test
{
static public function getNew()
{
return new static;
}
}
class Child extends Test
{}
$obj1 = new Test();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2);
$obj3 = Test::getNew();
var_dump($obj3 instanceof Test);
$obj4 = Child::getNew();
var_dump($obj4 instanceof Child);
?>
O exemplo acima irá imprimir:
bool(true) bool(true) bool(true)
Propriedades e métodos de classe vivem em "namespaces" separados, de forma que é possível ter uma propriedade e método com mesmos nomes. A referência a propriedades e métodos tem a mesma notação, e a decisão de se uma propriedade será acessada ou uma chamada a um método feita, depende somente do contexto, ou seja, se está tentando acessar uma variável ou chamar um método.
Exemplo #6 Acesso a propriedade vs. chamar um método
class Foo
{
public $bar = 'propriedade';
public function bar() {
return 'métod';
}
}
$obj = new Foo();
echo $obj->bar, PHP_EOL, $obj->bar(), PHP_EOL;
O exemplo acima irá imprimir:
propriedade método
Isto significa que chamar diretamente uma função anônima atribuída a uma propriedade não é possível. Em vez disso, por exemplo, a propriedade deve primeiro ser atribuída a uma variável. A partir do PHP 7.0.0, é possível chamar uma propriedade diretamente a colocando entre parênteses.
Exemplo #7 Chamando uma função anônima armazenada em uma propriedade
class Foo
{
public $bar;
public function __construct() {
$this->bar = function() {
return 42;
};
}
}
$obj = new Foo();
// a partir do PHP 5.3.0:
$func = $obj->bar;
echo $func(), PHP_EOL;
// alternativamente, a partir do PHP 7.0.0:
echo ($obj->bar)(), PHP_EOL;
O exemplo acima irá imprimir:
42
Uma classe pode herdar métodos e propriedades de outra classe usando a palavra-chave extends na declaração da classe. Não é possível herdar múltiplas classes; uma classe só pode herdar uma classe base.
Os métodos e propriedades herdados podem ser sobrescritos redeclarando-os com o mesmo nome definido na classe base. Entretanto, se o método foi definido na classe base como final esse método não poderá ser sobrescrito. É possível acessar os métodos sobrescritos ou propriedades estáticas referenciado-os com parent::.
Ao sobrescrever métodos, a assinatura de parâmetros deve permanecer a mesma ou
o PHP gerará um erro de nível E_STRICT
. Isto não se
aplica ao construtor, que permite a sobrescrita com parâmetros
diferentes.
Exemplo #8 Herança da Classe Simples
<?php
class ExtendClass extends SimpleClass
{
// Redefine o método pai
function displayVar()
{
echo "Classe Herdeira\n";
parent::displayVar();
}
}
$extended = new ExtendClass();
$extended->displayVar();
?>
O exemplo acima irá imprimir:
Classe Herdeira um valor padrão
Desde o PHP 5.5, a palavra-chave class também pode ser utilizada para resolução de nome de classes. Pode-se obter uma string contendo o nome completo e qualificado da classe ClassName utilizando ClassName::class. Isso é particularmente útil em classes com namespaces.
Exemplo #9 Resolução de nome da classe
<?php
namespace NS {
class ClassName {
}
echo ClassName::class;
}
?>
O exemplo acima irá imprimir:
NS\ClassName
Nota:
A resolução de nomes de classe através de ::class é uma transformação em tempo de compilação. Significando que a string com nome é criada antes que o autoloading tenha acontecido. Como consequência, os nomes de classe são expandidos mesmo que a classe não exista. Neste caso, nenhum erro será emitido.