Interfaces em PHP
1. O que são Interfaces em PHP?
Interfaces em PHP são contratos de implementação que definem quais métodos uma classe deve obrigatoriamente conter, sem especificar como esses métodos funcionam. Elas estabelecem um compromisso entre o código que define a interface e o código que a implementa.
A principal diferença entre interfaces e classes abstratas está no propósito: enquanto classes abstratas podem conter implementações parciais e propriedades, interfaces são puramente contratos — não podem conter implementações de métodos (até o PHP 8.0) nem propriedades.
<?php
// Sintaxe básica de uma interface
interface Pagavel {
public function processarPagamento(float $valor): bool;
public function gerarRecibo(): string;
}
2. Declarando e Implementando Interfaces
A declaração de uma interface usa a palavra-chave interface, e a implementação em classes concretas usa implements. Uma classe pode implementar múltiplas interfaces, característica que contorna a ausência de herança múltipla em PHP.
<?php
interface Logavel {
public function registrarLog(string $mensagem): void;
}
interface Exportavel {
public function exportarCSV(): string;
}
class Pedido implements Pagavel, Logavel {
public function processarPagamento(float $valor): bool {
// Lógica de pagamento
return true;
}
public function gerarRecibo(): string {
return "Recibo gerado";
}
public function registrarLog(string $mensagem): void {
// Registrar em arquivo ou banco
echo "[LOG] $mensagem";
}
}
3. Métodos e Constantes em Interfaces
Todos os métodos declarados em uma interface são abstratos (não possuem corpo) e devem ter visibilidade public obrigatoriamente. Além disso, interfaces podem conter constantes, que são acessíveis globalmente através da interface.
<?php
interface Configuravel {
const VERSAO_API = '2.0';
const TIMEOUT_PADRAO = 30;
public function configurar(array $parametros): void;
}
class API implements Configuravel {
public function configurar(array $parametros): void {
echo "Configurando API versão " . self::VERSAO_API;
}
}
// Acesso direto às constantes
echo Configuravel::VERSAO_API; // 2.0
Regras importantes:
- Métodos devem ter mesma assinatura na implementação
- Constantes não podem ser sobrescritas por classes que implementam
- A partir do PHP 8.1, interfaces podem declarar constantes com visibilidade (public, protected, private)
4. Herança entre Interfaces
Interfaces podem estender outras interfaces, criando hierarquias de contratos. Uma interface filha herda todos os métodos e constantes da interface pai.
<?php
interface BancoDados {
public function conectar(): void;
public function desconectar(): void;
}
interface BancoDadosTransacional extends BancoDados {
public function iniciarTransacao(): void;
public function confirmarTransacao(): void;
public function reverterTransacao(): void;
}
class MySQL implements BancoDadosTransacional {
public function conectar(): void { /* ... */ }
public function desconectar(): void { /* ... */ }
public function iniciarTransacao(): void { /* ... */ }
public function confirmarTransacao(): void { /* ... */ }
public function reverterTransacao(): void { /* ... */ }
}
Resolução de conflitos: Se duas interfaces pai declararem métodos com o mesmo nome, a classe implementadora deve fornecer uma única implementação que satisfaça ambas as interfaces.
5. Tipagem com Interfaces
Interfaces são fundamentais para type hinting e polimorfismo em PHP. Você pode declarar parâmetros e retornos como interfaces, permitindo que diferentes classes sejam usadas de forma intercambiável.
<?php
interface FormaGeometrica {
public function calcularArea(): float;
}
class Circulo implements FormaGeometrica {
private float $raio;
public function __construct(float $raio) {
$this->raio = $raio;
}
public function calcularArea(): float {
return pi() * $this->raio ** 2;
}
}
class Quadrado implements FormaGeometrica {
private float $lado;
public function __construct(float $lado) {
$this->lado = $lado;
}
public function calcularArea(): float {
return $this->lado ** 2;
}
}
function imprimirArea(FormaGeometrica $forma): void {
echo "Área: " . $forma->calcularArea();
}
// Polimorfismo em ação
$formas = [new Circulo(5), new Quadrado(4)];
foreach ($formas as $forma) {
if ($forma instanceof FormaGeometrica) {
imprimirArea($forma);
}
}
6. Interfaces Pré-definidas do PHP
O PHP fornece diversas interfaces nativas que permitem que objetos se comportem como estruturas da linguagem:
<?php
// ArrayAccess - permite acessar objeto como array
class Colecao implements \ArrayAccess {
private array $itens = [];
public function offsetExists(mixed $offset): bool {
return isset($this->itens[$offset]);
}
public function offsetGet(mixed $offset): mixed {
return $this->itens[$offset] ?? null;
}
public function offsetSet(mixed $offset, mixed $value): void {
$this->itens[$offset] = $value;
}
public function offsetUnset(mixed $offset): void {
unset($this->itens[$offset]);
}
}
// Iterator - permite iteração com foreach
class ListaNumeros implements \Iterator {
private array $numeros;
private int $posicao = 0;
public function current(): mixed {
return $this->numeros[$this->posicao];
}
public function key(): mixed {
return $this->posicao;
}
public function next(): void {
$this->posicao++;
}
public function rewind(): void {
$this->posicao = 0;
}
public function valid(): bool {
return isset($this->numeros[$this->posicao]);
}
}
Outras interfaces importantes: Traversable (base para Iterator), Serializable (controle de serialização), Stringable (PHP 8.0, para objetos que podem ser convertidos para string).
7. Boas Práticas e Padrões com Interfaces
Programe para interfaces, não para implementações
Este princípio fundamental do design orientado a objetos reduz o acoplamento e facilita testes e manutenção:
<?php
// Ruim: dependência direta de implementação concreta
class ProcessadorPagamento {
private PayPal $gateway;
public function __construct() {
$this->gateway = new PayPal();
}
}
// Bom: dependência de interface
class ProcessadorPagamento {
public function __construct(
private GatewayPagamento $gateway
) {}
}
Injeção de Dependência e Inversão de Controle
Interfaces são essenciais para IoC, permitindo que containers de dependência substituam implementações sem alterar o código cliente:
<?php
interface RepositorioUsuario {
public function buscarPorId(int $id): ?Usuario;
public function salvar(Usuario $usuario): void;
}
class ServicoUsuario {
public function __construct(
private RepositorioUsuario $repositorio
) {}
}
Quando usar interfaces vs. classes abstratas vs. traits
| Característica | Interface | Classe Abstrata | Trait |
|---|---|---|---|
| Implementação de métodos | Não (até PHP 8.0) | Sim | Sim |
| Propriedades | Não | Sim | Sim |
| Herança múltipla | Sim (várias interfaces) | Não | Sim |
| Construtor | Não | Sim | Não |
Use interfaces quando: precisar definir contratos que diferentes classes não relacionadas possam implementar.
Use classes abstratas quando: classes relacionadas compartilham implementação parcial.
Use traits quando: precisar reutilizar implementação em classes sem relação hierárquica.
Referências
-
PHP Manual: Interfaces de Objetos — Documentação oficial completa sobre interfaces em PHP, incluindo sintaxe, herança e exemplos.
-
PHP The Right Way: Interfaces — Guia prático sobre boas práticas com interfaces e padrões de design em PHP.
-
PHP 8.1: Constantes em Interfaces — Artigo técnico detalhando as novas capacidades de constantes em interfaces no PHP 8.1.
-
Refactoring Guru: Strategy Pattern em PHP — Exemplo prático de uso de interfaces no padrão Strategy, demonstrando polimorfismo e type hinting.
-
PHP.net: SPL Interfaces — Documentação das interfaces da Standard PHP Library (SPL), incluindo
ArrayAccess,IteratoreCountable.