Visibility Modifiers: Mastering Encapsulation in PHP
Learn to use public, private, and protected keywords in PHP to control access to class properties and methods, ensuring robust encapsulation in your code.

Previously in this course, we covered Classes and Objects: Mastering OOP Foundations in PHP, where we defined the basic blueprints for our objects. While those objects worked, we left their internal data wide open to modification from anywhere in our application.
In this lesson, we’ll move beyond simply "having" data to "protecting" it. By using visibility modifiers, we can enforce encapsulation—the practice of bundling data with the methods that operate on it and restricting direct access to that data. This prevents the rest of your application from accidentally corrupting an object's internal state.
The Three Pillars of Visibility
PHP provides three keywords to control access to properties and methods. Think of these as the security clearance levels for your code.
| Keyword | Who can access it? |
|---|---|
| public | Anyone (inside the class, subclasses, and outside code). |
| protected | Only the class itself and its child classes (inheritance). |
| private | Only the class itself. |
Public: The Default Gateway
When you define a property or method as public, you are saying, "The world can see and change this." If you omit a modifier, PHP defaults to public, though it is best practice to be explicit.
Private: Protecting Internal State
private is your strongest tool for encapsulation. If you have a User class with an email property, you don’t want external code setting that email to an invalid string like "not-an-email". By making it private, you force external code to use a method (a "setter") where you can validate the data first.
Protected: Balancing Inheritance
protected is useful when you have a parent class and child classes. It allows the child to "see" the property or method, but keeps it hidden from the rest of your application.
Encapsulation in Practice

Let’s refine our User model for our MVC project. Instead of letting anyone change the user's ID or email directly, we'll lock them down.
PHPclass User { #6A9955">// Private properties: hidden from the outside private int $id; private string $email; public function __construct(int $id, string $email) { $this->id = $id; $this->email = $email; } #6A9955">// Public method: the only way to get the email public function getEmail(): string { return $this->email; } #6A9955">// Public method: a controlled way to change the email public function updateEmail(string $newEmail): void { if (filter_var($newEmail, FILTER_VALIDATE_EMAIL)) { $this->email = $newEmail; } else { throw new Exception("Invalid email format."); } } } $user = new User(1, "dev@example.com"); #6A9955">// This works: echo $user->getEmail(); #6A9955">// This would cause a fatal error: #6A9955">// echo $user->email; #6A9955">// This is the correct, safe way to change data: $user->updateEmail("new@example.com");
Hands-on Exercise
Modify your current project's Model class. Identify one property that should not be changed from the outside (like a database connection string or an internal ID).
- Change that property's visibility to
private. - Create a
publicgetter method to retrieve the value. - Try to access the property directly from your
index.phpor controller. You should see a PHP error confirming that the property is inaccessible.
Common Pitfalls

- Over-using Public: It’s tempting to make everything
publicbecause it’s easier to type. Avoid this. If every property is public, your application loses its structural integrity, and you won't know which part of your code changed a value when a bug occurs. - Confusing Protected and Private: If you don't intend to use inheritance, always default to
private. It provides the strictest security for your objects. - Forgetting to define visibility: While PHP allows omitting the keyword, explicit code is readable code. Always type
public,private, orprotected.
FAQ
Q: Why not just make everything private?
A: You need public methods (the "interface") so that other parts of your app can interact with your object. Without public methods, your object is a "black box" that does nothing.
Q: Can I change visibility in a subclass?
A: You can change protected to public, but you cannot make a member more restrictive (you cannot turn a public method into private in a child class).
Q: Is encapsulation just for security? A: No, it’s primarily for maintainability. Encapsulation allows you to change the internal implementation of your class (e.g., how you store the email) without breaking the code that uses your class.
Recap

Encapsulation is the cornerstone of robust object-oriented programming. By using private for internal data and public for your interface, you create a system where internal state is protected, validation is centralized, and your application is much easier to debug and extend.
Up next: We will apply these concepts to our MVC architecture by refactoring our procedural code into structured, encapsulated classes.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs — the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

FilamentPHP Admin Panel & Dashboard Development
A powerful admin panel for your Laravel app — built with FilamentPHP so you can manage everything without touching the database.


