Public, Protected and Private

When and why should I use public, protected and private functions and variables inside a class?

Posted by Alexander Mills on 29 November 2018

Public:

When you declare a method (function) or a property (variable) as public, those methods and properties can be accessed by:

  • The same class that declared it.
  • The classes that inherit the above declared class.
  • Any foreign elements outside this class can also access those things.

Protected:

When you declare a method (function) or a property (variable) as protected, those methods and properties can be accessed by

  • The same class that declared it.
  • The classes that inherit the above declared class.

Outsider members cannot access those variables. "Outsiders" in the sense that they are not object instances of the declared class itself.

Private:

When you declare a method (function) or a property (variable) as private, those methods and properties can be accessed by:

  • The same class that declared it.

Outsider members cannot access those variables. Outsiders in the sense that they are not object instances of the declared class itself and even the classes that inherit the declared class.

Why Visibility Matters

So far I’ve discussed the rules of visibility, but I haven’t really addressed why we care about it and should use it with intent.

There are a few reasons to use visibility in our OOP PHP code:

  • It helps us show the intent of our code
  • It reduces our need to validate properties when used internally
  • And it helps dictate how classes should be used.

For example, consider this class:

class Dog {
    public $name;

    protected $color;

    public function setName(string $name) {
        $this->name = $name;
    }

    public function setColor(string $color) {
        $this->color = $color;
    }
}

In this case, we can set the property name to anything. For example:

$myDog = new Dog();
$myDog->name = 1472;

This is a problem if we want to write code later that uses $name and assumes it is a string. We would have to make sure it was a string every time we used that property.

Conversely, the property color is protected. It has a public set function that validates if it is a string before setting. Now we can assume when calling that property internally that it is a string. Assuming the type of variable is a dangerous assumption in a dynamically typed language, but this is one way to reduce that risk.

If we were to try the above example with color, we'd get the following result:

$myDog = new Dog();
$myDog->color = 'brown';

PHP Fatal error: Cannot access protected property Dog::$color

Also, by having public functions for getting protected or private properties, we make it clear what the utility of a class was. For example, if I have a class that has a constructor that takes in a bunch of data, creates some markup and puts it in a protected variable called $html, and then has a public method to get that variable, it is pretty clear the point of the class was to make HTML markup.

A Few Last Words

I want to make two last points.

The first is that the complexity of these rules is one of the many reasons why you should be using an IDE with a PHP interpreter included. I use PHPstorm and when I was writing the example code for this article the “bad examples” caused PHPStorm to add red underlines to my illegal code and gave me a little pop-up explaining why I was wrong when I moused over the bad code. It also did not auto-complete the properties and methods that I couldn’t use.

The other thing to keep in mind is not to overuse visibility. As I said in the last section, visibility helps us clarify the intent of our code, but by being overly-pedantic you can make life more difficult for yourself, or another developer working with your code, down the road.

Now that you know how visibility works and why it works, you will be able to write better code with clearer intent. You should also be able to take better advantage of PHP’s ability to extend classes, which makes a big difference in writing more reusable code.