Understanding Access Modifiers in PHP

Like many OOP-capable languages, PHP has a feature called Access Modifiers. These help with principles of encapsulation, maintainability, and reducing complexity.

What do they do? They define the visibility of class properties and methods (members of a class), controlling how these members are accessed by other parts of your code.

There are three access modifiers that can be used in a class:

1. Public

Members declared as public can be accessed from anywhere, both inside and outside the class.

php
class Example {
    public $name = "Public Property";
}

$example = new Example();
echo $example->name; // Accessible

2. Private

Members declared as private can only be accessed within the class where they are defined.

The following code would throw an error:

php
class Example {
    private $name = "Private Property";
}

$example = new Example();

echo $example->name; // WILL THROW ERROR (Cannot access private property)

It's typical for a PHP developer to want to have a property that cannot be modified by outside code but can still be read. A common way to do this is to make a "getter" method such as this:

php
class Example {
    private $name = "Private Property";

    public function getName() {
        return $this->name; // Accessible within the class
    }
}

$example = new Example();

echo $example->getName(); // Accessible through a public method

3. Protected

Members declared as protected can only be accessed within the class itself and by classes that inherit from it.

php
class ParentClass {
    protected $name = "Protected Property";
}

class ChildClass extends ParentClass {
    public function getName() {
        return $this->name; // Accessible within child class
    }
}

$child = new ChildClass();
echo $child->getName(); // Accessible through a public method

What's this useful for?

There are many reasons access modifiers are useful, but here is one good example:

Let’s say you want to make a service in PHP that handles a team draft. You might write something like this:

php
<?php

class TeamDraft
{
    private array $names;
    private array $pickedNames = [];

    public function __construct(array $names = [])
    {
        // Default list of names if none are provided
        $this->names = !empty($names) ? $names : [
            'Alice',
            'Bob',
            'Charlie',
            'Diana',
            'Eve',
            'Frank'
        ];
    }

    public function selectName(string $name): string
    {
        // Validate that the name exists in the list
        if (!in_array($name, $this->names)) {
            throw new Exception("The name '{$name}' does not exist in the list.");
        }

        // Check if the name has already been picked
        if (in_array($name, $this->pickedNames)) {
            throw new Exception("The name '{$name}' has already been picked.");
        }

        // Add the name to the pickedNames list and remove it from the available names
        $this->pickedNames[] = $name;
        $this->names = array_diff($this->names, [$name]);

        return $name;
    }

    public function getPickedNames(): array
    {
        return $this->pickedNames;
    }

    public function getRemainingNames(): array
    {
        return $this->names;
    }
}

So now, if we use this class, we can do a few things. We can select names and, therefore, indirectly manipulate the values of the two private members of the class. However, the class defines the rules for doing so. As a user of this code, I can't just change the list myself and potentially make mistakes, like adding names that don't exist. I'm restricted, and that's a good thing—it avoids unintentional misuse of the class.

Summary

  • Use public for members that need to be accessed outside the class.
  • Use protected for members that should only be accessible within the class or classes that extend it.
  • Use private for members that should remain strictly internal to the class.

Thanks for reading! I encourage you to think about how you can apply this to code you've already written to make it better and easier for others to use!