protected
A palavra-chave "protected" no PHP declara um membro de classe como protegido, acessível apenas dentro da própria classe e de suas subclasses.
A Palavra-chave protected do PHP
protected é um dos três modificadores de acesso do PHP (ao lado de public e private). Ele controla a visibilidade — quem tem permissão para ler ou chamar um membro de classe.
Um membro declarado como protected pode ser acessado:
- dentro da classe que o declara, e
- dentro de qualquer classe que herda dela (uma subclasse).
Ele não pode ser acessado "de fora" — ou seja, a partir de código comum que apenas possui um objeto ($obj->member). Esse meio-termo é exatamente o que torna o protected útil: ele oculta detalhes de implementação do mundo exterior, ao mesmo tempo que permite às subclasses construir sobre eles. Para a comparação completa, veja Modificadores de Acesso PHP.
Esta página aborda a sintaxe, como o protected se comporta ao longo da herança, os erros comuns e quando usá-lo em vez de private ou public.
Sintaxe
Coloque a palavra-chave protected na frente de uma declaração de propriedade ou método:
class MyClass {
protected $myProtectedProperty;
protected function myProtectedMethod() {
// Code here
}
}Você também pode marcar um membro estático como protegido:
class Config {
protected static $instances = 0;
protected static function register() {
self::$instances++;
}
}protected vs private vs public
Os três modificadores diferem apenas em onde um membro é visível:
| Modificador | Mesma classe | Subclasse | Código externo |
|---|---|---|---|
public | sim | sim | sim |
protected | sim | sim | não |
private | sim | não | não |
A distinção principal: membros private são invisíveis mesmo para subclasses, enquanto membros protected são compartilhados ao longo da cadeia de herança. Escolha protected quando uma subclasse precisa legitimamente dos dados ou do auxiliar, mas você ainda quer mantê-los fora da API pública.
Exemplos
Os exemplos abaixo mostram membros protected sendo usados por uma subclasse (permitido) — em seguida veremos o que acontece quando código externo tenta o mesmo.
<?php
// Example 1
class Animal
{
protected $name;
public function __construct($name)
{
$this->name = $name;
}
protected function getName()
{
return $this->name;
}
}
class Dog extends Animal
{
public function bark()
{
$name = $this->getName();
echo "$name barks!" . PHP_EOL;
}
}
$dog = new Dog("Rufus");
$dog->bark(); // Output: Rufus barks!
// Example 2
class BankAccount
{
protected $balance = 0;
public function deposit($amount)
{
$this->balance += $amount;
}
protected function canWithdraw($amount)
{
return $amount <= $this->balance;
}
}
class SavingsAccount extends BankAccount
{
public function withdraw($amount)
{
if ($this->canWithdraw($amount)) {
$this->balance -= $amount;
echo "Withdrawal successful!" . PHP_EOL;
} else {
echo "Insufficient funds!" . PHP_EOL;
}
}
}
$savingsAccount = new SavingsAccount();
$savingsAccount->deposit(100);
$savingsAccount->withdraw(50); // Output: Withdrawal successful!
$savingsAccount->withdraw(100); // Output: Insufficient funds!Em ambas as classes, a subclasse (Dog, SavingsAccount) chama livremente o membro protegido do seu pai. Os dados e a lógica auxiliar permanecem reutilizáveis por meio da herança, sem nunca serem expostos ao código externo.
Acessar membros protected de fora falha
No momento em que você tenta acessar um membro protegido a partir de código comum, o PHP lança um erro fatal:
<?php
class Animal {
protected $name = "Rufus";
}
$animal = new Animal();
echo $animal->name; // Fatal error: Cannot access protected property Animal::$nameEssa é a proteção em ação — a propriedade simplesmente não faz parte da superfície pública do objeto.
Atenção: uma subclasse pode acessar irmãos do mesmo tipo
Uma surpresa comum é que a visibilidade é verificada pela classe, não pelo objeto individual. Um objeto pode acessar os membros protegidos de outro objeto, desde que ambos sejam instâncias da mesma classe (ou de uma classe relacionada que possa ver o membro):
<?php
class Wallet {
protected $balance = 100;
public function isRicherThan(Wallet $other): bool
{
// $other->balance is protected, but we're inside Wallet, so it's allowed
return $this->balance > $other->balance;
}
}
$a = new Wallet();
$b = new Wallet();
var_dump($a->isRicherThan($b)); // bool(false)Quando usar protected
Use protected quando:
- Uma subclasse precisa reutilizar ou substituir estado interno ou métodos auxiliares, mas o código externo não deve ter acesso.
- Você está projetando uma classe base destinada a ser estendida (veja Classes Abstratas PHP), e deseja oferecer métodos de "bloco de construção" apenas para subclasses.
Prefira private quando mesmo subclasses não devem depender de um detalhe interno — isso lhe dá liberdade para alterá-lo posteriormente sem quebrar classes filhas. Prefira public apenas para a API intencional e documentada da classe.
Resumo
- Membros
protectedsão visíveis dentro da classe declarante e suas subclasses, mas não para código externo. - É o meio-termo entre
public(visível em todo lugar) eprivate(visível apenas na classe declarante). - A visibilidade é aplicada por classe, portanto objetos do mesmo tipo podem ver os membros protegidos uns dos outros.
- Use-o para compartilhar internos reutilizáveis ao longo de uma cadeia de herança, mantendo-os fora da API pública.
Para aprofundar, continue com Herança PHP, Classes e Objetos PHP e Propriedades Estáticas.