PHP Keywords: private, protected and public

9 March 2019 - 10:03am

Welcome to my series on every PHP keyword and its usage. Today's items: private, protected and public.

These keywords are collectively known as visibility, and describe where a class constant, property or method can be accessed from.

  • A private constant, property or method can only be accessed from within the class that defines it.
  • A protected constant, property or method can only be accessed from within the class that defines it, or a descendant of that class.
  • A public constant, property or method can be accessed from anywhere.

By default, all constants, properties and methods are public unless specified otherwise.

As a general rule, it's best to give everything the lowest visibility possible. It's a lot easier to refactor when you know that the only code calling a method is in the current class.

Notes:

  • Visibility works the same way for static and instance properties/methods, and an instance of a class can call that class' private constants, static properties and static methods.
  • Constants, properties and methods with private visibility cannot be overridden.
  • Visibility isolates calls between classes, not between instances. An object can call another object's private method, provided that they are the same type of object.
  • Traits are not inherited so much as applied. This means that a private constant, property or method in the trait will be copied onto any object using that trait, and can be called directly from the object.

Usage

<?php
class Example
{
    private const PRIVATE_CONSTANT = "private";
    protected const PROTECTED_CONSTANT = "protected";
    public const PUBLIC_CONSTANT = "public";

    private static $privateStaticProperty = "private";
    protected static $protectedStaticProperty = "protected";
    public static $publicStaticProperty = "public";

    private $privateProperty = "private";
    protected $protectedProperty = "protected";
    public $publicProperty = "public";

    private static function privateStaticMethod(){}
    protected static function protectedStaticMethod(){}
    public static function publicStaticMethod(){}

    private function privateMethod(){}
    protected function protectedMethod(){}
    public function publicMethod(){}

    public static function callPrivateStatic()
    {
        // This class has access to its own private constants, static
        // properties and static methods
        echo self::PRIVATE_CONSTANT;
        echo self::$privateStaticProperty;
        self::privateStaticMethod();
    }

    public static function callProtectedStatic()
    {
        // This class has access to its own protected constants, static
        // properties and static methods
        echo self::PROTECTED_CONSTANT;
        echo self::$protectedStaticProperty;
        self::protectedStaticMethod();
    }

    public static function callPublicStatic()
    {
        // This class has access to its own public constants, static properties
        // and static methods
        echo self::PUBLIC_CONSTANT;
        echo self::$publicStaticProperty;
        self::publicStaticMethod();
    }

    public function callPrivate()
    {
        // This class has access to its own private properties and methods
        echo $this->privateProperty;
        $this->privateMethod();
    }

    public function callProtected()
    {
        // This class has access to its own protected properties and methods
        echo $this->protectedProperty;
        $this->protectedMethod();
    }

    public function callPublic()
    {
        // This class has access to its own public properties and methods
        echo $this->publicProperty;
        $this->publicMethod();
    }
}

class ExampleChild extends Example
{
    public static function callProtectedStatic()
    {
        // This class has access to, and can override, its ancestors' protected
        // constants, static properties and methods
        echo parent::PROTECTED_CONSTANT;
        echo parent::$protectedStaticProperty;
        parent::protectedStaticMethod();
    }

    public static function callPublicStatic()
    {
        // This class has access to, and can override, its ancestors' public
        // constants, static properties and methods
        echo parent::PUBLIC_CONSTANT;
        echo parent::$publicStaticProperty;
        parent::publicStaticMethod();
    }

    public function callProtected()
    {
        // This class has access to, and can override, its ancestors' protected
        // properties and methods
        echo $this->protectedProperty;
        $this->protectedMethod();
    }

    public function callPublic()
    {
        // This class has access to, and can override, its ancestors' public
        // properties and methods
        echo $this->publicProperty;
        $this->publicMethod();
    }
}

class Other
{
    public static function callPublicStatic()
    {
        // This class has access to Example's public constants, static
        // properties and static methods
        echo Example::PUBLIC_CONSTANT;
        echo Example::$publicStaticProperty;
        Example::publicStaticMethod();
    }

    public function callPublic()
    {
        // This class has access to Example's public properties and methods
        $example = new Example();
        echo $example->publicProperty;
        $example->publicMethod();
    }
}

// The global scope also has access to Example's public constants, static
// properties, properties, static methods and methods.
echo Example::PUBLIC_CONSTANT;
echo Example::$publicStaticProperty;
Example::publicStaticMethod();
$example = new Example();
echo $example->publicProperty;
$example->publicMethod();