Back to Blog
Lesson 26 of the PHP: Modern PHP from the Ground Up course
PHPAugust 13, 20264 min read

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.

PHPOOPEncapsulationVisibilityBackend
A close-up view of PHP code displayed on a computer screen, highlighting programming and development concepts.

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.

KeywordWho can access it?
publicAnyone (inside the class, subclasses, and outside code).
protectedOnly the class itself and its child classes (inheritance).
privateOnly 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

Close-up of clear capsules on a vibrant yellow surface, offering potential for health-related content

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.

PHP
class 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).

  1. Change that property's visibility to private.
  2. Create a public getter method to retrieve the value.
  3. Try to access the property directly from your index.php or controller. You should see a PHP error confirming that the property is inaccessible.

Common Pitfalls

Close-up of a triangular warning sign indicating a slippery surface, fixed to a wooden post.

  • Over-using Public: It’s tempting to make everything public because 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, or protected.

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

Team members presenting a project in a modern office setting with a focus on collaboration.

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.

Similar Posts