Modificadores de Acesso no PHP OOP: Um Guia Completo
Aprenda os modificadores de acesso do PHP (public, protected, private), como funcionam com herança e os padrões comuns de encapsulamento em OOP.
Os modificadores de acesso (também chamados de palavras-chave de visibilidade) definem quem pode ler, alterar ou chamar um membro de uma classe. Eles são o mecanismo por trás do encapsulamento — um dos conceitos fundamentais da Programação Orientada a Objetos: você expõe uma interface pública pequena e segura e oculta os detalhes internos que os chamadores não devem acessar.
Este capítulo aborda as três palavras-chave de visibilidade do PHP — public, protected e private — o que cada uma permite, o que acontece quando as regras são violadas, como a visibilidade se comporta na herança e os padrões comuns (getters, setters e promoção de construtor) que dependem delas. Se classes são novidade para você, leia primeiro Classes e Objetos PHP.
Os três modificadores de acesso em resumo
| Modificador | Dentro da mesma classe | Em uma classe filha | De fora (ex.: $obj->member) |
|---|---|---|---|
public | ✅ | ✅ | ✅ |
protected | ✅ | ✅ | ❌ |
private | ✅ | ❌ | ❌ |
Você pode aplicar um modificador a propriedades, métodos e constantes de classe. Se você omitir o modificador em um método, o PHP o define como public por padrão; em uma propriedade, você deve escrever um explicitamente (a antiga palavra-chave var é um alias para public).
Modificador de acesso public
public é o nível mais permissivo. Um membro público pode ser acessado de qualquer lugar — dentro da classe, de classes filhas e de qualquer código que possua o objeto. Use-o para a interface pretendida da sua classe: os métodos que os chamadores devem usar.
<?php
class User {
public $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
$user = new User();
$user->setName("Ada"); // calling a public method
echo $user->getName(); // Ada
echo "\n";
$user->name = "Grace"; // touching a public property directly
echo $user->name; // GraceA saída é:
Ada
GraceComo $name é público, os chamadores podem alterá-lo diretamente com $user->name = ..., ignorando setName(). É exatamente por isso que propriedades públicas são frequentemente desencorajadas: você perde a oportunidade de validar o valor. Marcar a propriedade como protected ou private e expô-la por meio de métodos restaura esse controle.
Modificador de acesso protected
protected fica no meio-termo. O membro é acessível de dentro da classe e de qualquer subclasse, mas não de código externo. Use-o quando uma subclasse legitimamente precisa dos dados, mas chamadores externos não devem tê-los.
<?php
class User {
protected $email;
protected function setEmail($email) {
$this->email = $email;
}
public function getEmail() {
return $this->email;
}
}
$user = new User();
echo $user->getEmail(); // works: getEmail() is public
$user->setEmail("[email protected]"); // Fatal error: Call to protected method User::setEmail()Executar isso não imprime nada na primeira linha (o e-mail ainda é null) e depois para com:
PHP Fatal error: Uncaught Error: Call to protected method User::setEmail() from global scopeO erro é o ponto: membros protegidos protegem a classe de ser mal utilizada por código externo, mantendo ainda a cooperação com a cadeia de herança mostrada abaixo.
Modificador de acesso private
private é o nível mais restritivo. O membro é visível apenas dentro da classe que o declara — nem mesmo subclasses podem vê-lo. Use private quando um detalhe é puramente interno e pode mudar a qualquer momento, como um hash de senha ou um cálculo em cache.
<?php
class User {
private $password;
public function setPassword($password) {
// hide the real value behind validation
$this->password = password_hash($password, PASSWORD_DEFAULT);
}
public function check($attempt) {
return password_verify($attempt, $this->password);
}
}
$user = new User();
$user->setPassword("s3cret");
var_dump($user->check("s3cret")); // bool(true)
var_dump($user->check("wrong")); // bool(false)A saída é:
bool(true)
bool(false)Tentar ler $user->password de fora da classe gera Error: Cannot access private property User::$password. O chamador só pode interagir pelos métodos públicos setPassword() e check() — o hash bruto fica selado.
Modificadores de acesso e herança
Quando uma classe filha estende uma classe pai, ela herda os membros do pai junto com sua visibilidade. Membros public e protected são utilizáveis dentro da filha; membros private não são visíveis para a filha.
<?php
class User {
protected $email;
protected function setEmail($email) {
$this->email = $email;
}
public function getEmail() {
return $this->email;
}
}
class Admin extends User {
// Admin can call the protected setEmail() because it is a subclass
public function updateEmail($email) {
$this->setEmail($email);
}
}
$admin = new Admin();
$admin->updateEmail("[email protected]");
echo $admin->getEmail(); // [email protected]A saída é:
Uma classe filha também pode ampliar a visibilidade (protected → public) ao sobrescrever um membro, mas não pode restringi-la — sobrescrever um método público como private gera um erro fatal. Para mais informações sobre construção de hierarquias de classes, veja Herança PHP.
Visibilidade em constantes e promoção de construtor
Constantes de classe aceitam os mesmos modificadores (desde o PHP 7.1). Isso permite expor algumas constantes enquanto oculta valores de configuração:
<?php
class Order {
public const STATUS_PAID = "paid";
private const TAX_RATE = 0.2; // internal detail
public function total(float $net): float {
return $net * (1 + self::TAX_RATE);
}
}
echo Order::STATUS_PAID; // paid
echo "\n";
echo (new Order())->total(100); // 120A saída é:
paid
120Desde o PHP 8.0, a promoção de propriedade no construtor permite declarar uma propriedade e sua visibilidade diretamente na assinatura do construtor, eliminando código repetitivo:
<?php
class Point {
public function __construct(
public int $x = 0,
private int $y = 0, // declared, assigned, and made private in one line
) {}
public function describe(): string {
return "x={$this->x}, y={$this->y}";
}
}
echo (new Point(3, 4))->describe(); // x=3, y=4A saída é:
x=3, y=4Veja Constantes de Classe PHP e Construtor PHP para uma visão completa dessas funcionalidades.
Escolhendo o modificador correto
- Comece com o nível mais restritivo (
private) e afrouxe apenas quando houver uma necessidade real. Isso mantém sua API pública pequena e fácil de modificar posteriormente. - Use
publicquando o membro faz parte da interface que os chamadores dependem. - Use
protectedquando subclasses — mas não código externo — precisam do membro. - Use
privatequando é um detalhe de implementação que pode mudar sem aviso. - Prefira propriedades privadas/protegidas com métodos públicos getter/setter em vez de propriedades públicas, para manter controle sobre como os valores são lidos e escritos. Essa ideia faz parte do que é OOP.
Resumo
Os modificadores de acesso controlam a visibilidade dos membros de uma classe: public permite acesso de qualquer lugar, protected da classe e suas subclasses, e private apenas da classe declarante. Eles se aplicam a propriedades, métodos e constantes, e são como o PHP aplica o encapsulamento. Usados corretamente — ocultando detalhes por trás de uma pequena superfície pública — tornam seu código mais seguro de alterar e mais fácil de compreender.