aprender PHP logo

Hoje iniciaremos uma parte muito essencial na programação, a orientação a objetos. Para dar início ao seu aprendizado, vou explicar como criar classes em PHP, e nos próximos artigos aprofundaremos mais nesse paradigma da programação.

Quando falamos em Orientação a Objetos (Programação Orientada a objetos, OOP, etc…) estamos falando no método utilizado para criar sua aplicação em qualquer linguagem de programação. Ao invés de criar um programa como um todo, criamos classes e objetos que podem ser reutilizados em milhares de funções específicas do programa.

Seria como criarmos várias engrenagens que fazem um motor inteiro funcionar. As engrenagens seriam as classes, e o motor, o programa que você está criando.

Este conceito é essencial para aproveitar o conceito DRY (Don't repeat yourselfem português: Não repita a si mesmo), que basicamente, significa que você não precisa fazer a mesma coisa duas vezes.

Por exemplo: Recentemente criei uma função que valida CPFs. Ela utiliza várias funções, variáveis e operadores para funcionar corretamente. Imagine se você tivesse que escrever todo aquele código todas as vezes que fosse criar um formulário com um campo de CPF. Seria perda de tempo e dinheiro, e você estaria repetindo algo que você já escreveu anteriormente.

A partir dessa aula, espero que você nunca precise escrever o mesmo código mais de uma vez, e utilize-se da Orientação a Objetos em PHP em todos os seus novos sites, programas, ou aplicativos.

Como criar classes em PHP

Para programar com orientação a objetos, primeiramente é necessário que você entenda o que é uma classe e o que é um objeto.

Uma classe é uma estrutura com propriedades e métodos, porém, sem um objeto (uma instância) ela não faz nada. Um objeto é uma instância de uma classe, ou seja, possui as mesmas propriedades e métodos da classe, porém, pode realizar ações com essas propriedades e métodos.

Para criar uma classe em PHP, simplesmente digite a palavra class, dê um espaço e digite o nome da sua classe. As ações da sua classe devem vir entre chaves.

<?php
class NomeDaClasse
{

}
?>

Recomenda-se que você inicie nomes de classes com letra maiúscula, e evite o caractere _ (underscore). Ou seja, escreva NomeDaClasse ao invés de nome_da_classe.

Também é recomendado que o nome da sua classe seja descritivo, ou seja, especifique o que a classe faz.

Objetos (instância da classe)

Para criar um objeto (que vai realizar as ações), utilize a palavra new e o nome da classe.

class NomeDaClasse
{

}

// Instância da classe (Objeto)
$objeto = new NomeDaClasse;
?>

Até aqui, não fizemos nada, apenas criamos a classe e um objeto, porém, se nossa classe não tem propriedades nem métodos, nosso objeto também não terá.

Para entender melhor, vamos ver o que são propriedades e métodos.

Propriedades de uma classe

Uma propriedade da classe é como uma variável comum, possui um valor mas não realiza nenhuma ação:

<?php
class NomeDaClasse
{
	// Propriedades da classe
	public $propriedade = 'Valor';
}

// Instância da classe (Objeto)
$objeto = new NomeDaClasse;

// Acessando uma propriedade da classe
echo $objeto->propriedade;
?>

Para acessar uma propriedade ou método de uma classe, é necessário que você acesse o objeto seguido de um traço (-) e um sinal de maior que (>), ou seja: ->.

Métodos de uma classe

Os métodos de uma classe realizam ações, ou seja, são funções que fazem algo que você queira. Veja outro exemplo:

<?php
class NomeDaClasse
{
	// Propriedades da classe
	public $propriedade = 'Valor';
	
	// Método da classe
	public function escreve () {
		echo $this->propriedade;
	}
}

// Instância da classe (Objeto)
$objeto = new NomeDaClasse;

// Acessando um método da classe
echo $objeto->escreve();
?>

Perceba que, quando vamos criar uma propriedade ou método de uma classe, devemos adicionar uma palavra extra antes. Em nossos exemplos acima, você já deve ter percebido a palavra public, vamos ver o que todas as palavras significam.

Public, protected e private

As palavras-chave public, protected e private indicam a visibilidade dos métodos ou propriedades. Antes de criar um método ou propriedade, é necessário indicar a visibilidade.

Propriedades e métodos podem ser:

  • public – Indica que a propriedade ou método estará disponível em qualquer local, ou seja, diretamente na classe, em classes descendentes, ou diretamente pelo programa.
  • private – Indica que a propriedade ou método somente estará disponível dentro da classe em que foi criado. Não estará acessível em classes descendentes, nem pelo programa.
  • protected – Indica que a propriedade ou método estará disponível dentro da classe que foi criado, em classes descendentes, mas NÃO estará disponível diretamente no programa.

Se pegarmos nosso exemplo anterior, e alterarmos a palavra public para protected, não conseguiremos mais acessar o método "escreve" fora da classe.

<?php
class NomeDaClasse
{
	// Propriedades da classe
	public $propriedade = 'Valor';
	
	// Método da classe
	protected function escreve () {
		echo $this->propriedade;
	}
}

// Instância da classe (Objeto)
$objeto = new NomeDaClasse;

// Acessando um método da classe
echo $objeto->escreve();
?>

Se você tentar utilizar o trecho acima, verá um erro na tela falando que você tentou acessar um método protegido da classe.

Porém, podemos criar um outro método público que utiliza o método protegido escreve.

<?php
class NomeDaClasse
{
	// Propriedades da classe
	public $propriedade = 'Valor';
	
	// Método protegido da classe
	protected function escreve () {
		echo $this->propriedade;
	}
	
	// Método público que utiliza o método protegido
	public function publico () {
		$this->escreve();
	}
}

// Instância da classe (Objeto)
$objeto = new NomeDaClasse;

// Acessando um método da classe
echo $objeto->publico();
?>

Perceba que fiz a utilização de uma pseudovariável chamada $this várias vezes. $this significa que estamos acessando o objeto (instância) atual da classe, isso porque podemos ter várias instâncias de uma mesma classe. Para exemplificar melhor, vamos modificar nossa classe para algo mais comum, uma pessoa, que tem nome e sobrenome.

<?php
class Pessoa
{
	// Propriedades da classe
	public $nome;
	public $sobrenome;
	
	// Método protegido da classe
	protected function escreve () {
		echo $this->nome;
		echo ' ';
		echo $this->sobrenome;
		echo '<br />';
	}
	
	// Método público que utiliza o método protegido
	public function publico () {
		$this->escreve();
	}
}

// Primeira instância da classe
$pessoa_1 = new Pessoa;

// Altera o valor das propriedades da primeira instância
$pessoa_1->nome      = 'Luiz Otávio';
$pessoa_1->sobrenome = 'Miranda';

// Segunda instância da classe
$pessoa_2 = new Pessoa;

// Altera o valor das propriedades da segunda instância
$pessoa_2->nome      = 'Letícia';
$pessoa_2->sobrenome = 'Barbosa';

// Utiliza o método público das duas classes
$pessoa_1->publico();
$pessoa_2->publico();
?>

No exemplo acima, além de criar duas instâncias de uma mesma classe, também alteramos os métodos ao longo do código. Isso é muito utilizado na programação orientada a objetos.

Construtor e destrutor de classe

Você pode definir construtores e destrutores para uma classe, ou seja, uma ação que acontece quando a classe é instanciada ou finalizada.

Construtor

Para definir um construtor para uma classe, basta criar uma função chamada de __construct, veja:

<?php
class Pessoa
{
	// Construtor
	function __construct () {
		echo 'Ação';
	}
}

// Objeto
$pessoa = new Pessoa;
?>

Assim que você cria um objeto, a função __construct é acionada, e todas as suas ações são executadas.

Destrutor

Um destrutor faz exatamente o contrário de um construtor, ou seja, assim que a classe é finalizada, a ação é executada.

Para definir um destrutor de uma classe PHP, basta criar uma função chamada __destruct, veja:

<?php
class Pessoa
{
	// Construtor
	function __destruct () {
		echo 'Ação';
	}
}

// Objeto
$pessoa = new Pessoa;
?>

Observação: Objetos PHP são finalizados automaticamente quando o código termina de ser executado. Se você quiser finalizar um objeto ao longo da execução do código, basta configurar um valor null para ele.

Construtor e destrutor

Veja um exemplo completo sobre construtores e destrutores:

<?php
class Pessoa
{
	// Propriedades da classe
	public $nome;
	public $sobrenome;
	
	// Construtor
	function __construct(){
		echo '<i>Classe instanciada...</i> <br >';
	}
	
	// Método protegido da classe
	protected function escreve () {
		echo $this->nome;
		echo ' ';
		echo $this->sobrenome;
		echo '<br />';
	}
	
	// Método público que utiliza o método protegido
	public function publico () {
		$this->escreve();
	}
	
	// Destrutor
	function __destruct(){
		echo '<i>Classe finalizada...</i> <br >';
	}
}

// Primeira instância da classe
$pessoa_1 = new Pessoa;

// Altera o valor das propriedades da primeira instância
$pessoa_1->nome      = 'Luiz Otávio';
$pessoa_1->sobrenome = 'Miranda';

// Utiliza o método público da classe
$pessoa_1->publico();

// Finaliza a classe
$pessoa_1 = null;

// Segunda instância da classe
$pessoa_2 = new Pessoa;

// Altera o valor das propriedades da segunda instância
$pessoa_2->nome      = 'Letícia';
$pessoa_2->sobrenome = 'Barbosa';

// Utiliza o método público da classe
$pessoa_2->publico();
?>

Perceba que na última instância da classe, não precisei finalizá-la, já que o PHP faz isso automaticamente pra mim.

Exemplo real de classe em PHP

Lembra da nossa função que valida CPFs? Vamos agora transformá-la em uma classe:

<?php
class ValidaCPF
{
	/**
	 * Multiplica dígitos vezes posições
	 *
	 * @param string $digitos Os digitos desejados
	 * @param int $posicoes A posição que vai iniciar a regressão
	 * @param int $soma_digitos A soma das multiplicações entre posições e dígitos
	 * @return int Os dígitos enviados concatenados com o último dígito
	 *
	 */
	protected function calc_digitos_posicoes( $digitos, $posicoes = 10, $soma_digitos = 0 ) {
		// Faz a soma dos dígitos com a posição
		// Ex. para 10 posições:
		//   0    2    5    4    6    2    8    8   4
		// x10   x9   x8   x7   x6   x5   x4   x3  x2
		//   0 + 18 + 40 + 28 + 36 + 10 + 32 + 24 + 8 = 196
		for ( $i = 0; $i < strlen( $digitos ); $i++  ) {
			$soma_digitos = $soma_digitos + ( $digitos[$i] * $posicoes );
			$posicoes--;
		}

		// Captura o resto da divisão entre $soma_digitos dividido por 11
		// Ex.: 196 % 11 = 9
		$soma_digitos = $soma_digitos % 11;

		// Verifica se $soma_digitos é menor que 2
		if ( $soma_digitos < 2 ) {
			// $soma_digitos agora será zero
			$soma_digitos = 0;
		} else {
			// Se for maior que 2, o resultado é 11 menos $soma_digitos
			// Ex.: 11 - 9 = 2
			// Nosso dígito procurado é 2
			$soma_digitos = 11 - $soma_digitos;
		}

		// Concatena mais um dígito aos primeiro nove dígitos
		// Ex.: 025462884 + 2 = 0254628842
		$cpf = $digitos . $soma_digitos;
	   
		// Retorna
		return $cpf;
	}
	
	/**
	 * Valida CPF
	 *
	 * @author Luiz Otávio Miranda <contato@todoespacoonline.com/w>
	 * @param string $cpf O CPF com ou sem pontos e traço
	 * @return bool True para CPF correto - False para CPF incorreto
	 *
	 */
	protected function valida_cpf( $cpf = false ) {
		// Exemplo de CPF: 025.462.884-23
	   
		// Verifica se o CPF foi enviado
		if ( ! $cpf ) {
			return false;
		}

		// Remove tudo que não é número do CPF
		// Ex.: 025.462.884-23 = 02546288423
		$cpf = preg_replace( '/[^0-9]/is', '', $cpf );

		// Verifica se o CPF tem 11 caracteres
		// Ex.: 02546288423 = 11 números
		if ( strlen( $cpf ) != 11 ) {
			return false;
		}  

		// Captura os 9 primeiros dígitos do CPF
		// Ex.: 02546288423 = 025462884
		$digitos = substr($cpf, 0, 9);
	   
		// Faz o cálculo dos 9 primeiros dígitos do CPF para obter o primeiro dígito
		$novo_cpf = $this->calc_digitos_posicoes( $digitos );
	   
		// Faz o cálculo dos 10 dígitos do CPF para obter o último dígito
		$novo_cpf = $this->calc_digitos_posicoes( $novo_cpf, 11 );
	   
		// Verifica se o novo CPF gerado é idêntico ao CPF enviado
		if ( $novo_cpf === $cpf ) {
			// CPF válido
			return true;
		} else {
			// CPF inválido
			return false;
		}
	}
	
	// Executa a validação
	function valida( $cpf ) {
		return $this->valida_cpf( $cpf );
	}
}
?>

Para utilizar, basta fazer o que foi detalhado nessa aula:

<?php
// CPF qualquer
$cpf = '865.714.290-21';

// Instância de ValidaCPF
$valida = new ValidaCPF;

if ( $valida->valida( $cpf ) ) {
	echo 'CPF válido';
} else {
	echo 'CPF inválido';
}
?>

Simples assim.

Arquivos de classes em PHP

Tudo o que foi descrito nessa aula, foi criado em um único arquivo. Isso não é interessante na área da programação orientada a objetos. Normalmente, cada classe tem seu próprio arquivo com um nome específico.

Se você olhar nosso artigo "Padrões de codificação WordPress", vai ver várias dicas sobre os nomes. Uma que achei bem interessante, é criar uma pasta chamada "Classes", e dentro dela colocar cada classe em um arquivo único com o seguinte nome:

class-nome-da-classe.php

Ou seja, o arquivo da classe tem o mesmo nome da classe.

Por exemplo, nossa classe ValidaCPF, estaria em um arquivo único chamado de class-validacpf.php.

Para utilizá-la, bastaria utilizar a função include do PHP para incluir o arquivo da classe:

<?php
// Inclui o arquivo
include('classes/class-validacpf.php');

// CPF qualquer
$cpf = '865.714.290-21';

// Instância de ValidaCPF
$valida = new ValidaCPF;

if ( $valida->valida( $cpf ) ) {
	echo 'CPF válido';
} else {
	echo 'CPF inválido';
}
?>

Simples assim!

Concluindo

Nossa aula sobre classes ainda não termina por aqui, veremos muitas coisas legais ainda, porém, creio que deixei muito campo para você treinar hoje.

Não deixe de ler as outras aulas do nosso curso gratuito de PHP.

Te vejo amanhã!