Broad Network


Visibility in PHP Classes and Objects

Classes and Objects in PHP - Part 4

Foreword: In this part of the series, I talk about the reserved words, public, protected and private in PHP OOP.

By: Chrysanthus Date Published: 24 Nov 2018

Introduction

This is part 4 of my series, Classes and Objects in PHP. In this part of the series, I talk about the reserved words, public, protected and private in PHP OOP. You should have read the previous parts of the series before coming here, as this is the continuation.

Class Structure
The structure of a class is as follows:

    class className
        {
            accessSpecifier1 member for accessSpecifier1
            accessSpecifier2 member for accessSpecifier2
            accessSpecifier3 member for accessSpecifier3
            accessSpecifier4 member for accessSpecifier4
             ...
        }

Remember, a member can be a property or a method.

An access specifier is any of the reserved word, public or protected or private. Every member (property or method) must be under an access specifier. To do this you type the access specifier, then the definition or declaration of the member.

If a method is not preceded by an access specifier, it is considered public.

What accesses the Class Members?
Members of a class can access other members (properties and methods) of the same class. Functions, operators and other classes (corresponding objects) outside the class description of a particular class can also access members of that class. An access specifier decides whether or not a function or operator or class, outside the class description can access the member it is associated with, inside its class definition (description).

I will use functions and classes (objects) in the illustrations of accesses to class members. I will not use operators for the illustrations.

I will be using the phrase, external function. This refers to a function or class method that is not a member of the class description in question. When I say an external function can access a class member, I mean the external function can use the name (name of property or name of method) of the member as its argument or as a variable inside its definition.

The public Access Specifier
With the public access specifier, an external function can access the public members of the class. The following code illustrates this (read the explanation below):

<?php

    class Calculator
        {
            public $num1;
            public $num2;

            public function add()
                {
                    $sum = $this->num1 + $this->num2;
                    return $sum;
                }
        }

    function myFn($par)
        {
            return $par;
        }

    function principal()
        {
            $obj = new Calculator();
            $obj->num1 = 2;
            $obj->num2 = 3;
            $result = $obj->add();
            echo $result, '<br>';
            $myVar = myFn($obj->num1);
            echo $myVar;
        }

    principal();

?>

The output is:

    5
    2

There are two external functions in the code: myFn() and principal(). The first line in the principal function instantiates a class object called, obj. In the principal function definition, lines 2 and 3 use the properties of the class as variables. Because the class members are public, the principal() function can access the members of the class, in its definition. Line 4 of the principal function also demonstrates this. In line 6, the function, myFn() uses the property num1 of the class as its argument. It could do so because the member, num1 is public in the class (object).

The private Access Specifier
With the private access specifier, an external function cannot access the private members of the class. With the private specifier, only a member of a class can access the private member of the class. The following code shows how only a member of a class can access a private member of the class (read the explanation below):

<?php

    class Calculator
        {
            private $num1;
            private $num2;

            public function add()
                {
                    $this->num1 = 2;
                    $this->num2 = 3;
                    $sum = $this->num1 + $this->num2;
                    return $sum;
                }
        }

    function principal()
        {
            $obj = new Calculator();
            $result = $obj->add();
            echo $result, '<br>';
        }

    principal();

?>

The output is:

    5

The class has two private members (properties) and one public member (method). In the class description, the add() method uses the names of the private members as variables. So the add() method, a member of the class has accessed the private members of the class.

The principal function definition (second line) has been able to access the add() method of the class because the add() method is public (it has a public access specifier).

The following code will not compile (not run), because the principal function definition, tries to access (use as variable) a private member of the class:

<?php

    class Calculator
        {
            private $num1;
            private $num2;

            public function add()
                {
                    $this->num1;
                    $this->num2 = 3;
                    $sum = $this->num1 + $this->num2;
                    return $sum;
                }
        }

    function principal()
        {
            $obj = new Calculator();
            $obj->num1 = 2;
            $result = $obj->add();
            echo $result, '<br>';
        }

    principal();

?>

The second line in the principal function is wrong because at that line, it tries to access (use as variable) the private member, $num1. I tried the code in my computer and I had,

    Fatal error: Uncaught Error: Cannot access private property Calculator::$num1 in C:Apache24htdocstemp.php:20 Stack trace: #0 C:Apache24htdocstemp.php(25): principal() #1 {main} thrown in C:Apache24htdocstemp.php on line 20

The protected Access Specifier
If a member of a class is public, it can be accessed by an external function including a derived class. If a member of a class is private, it cannot be accessed by an external function; even a derived class cannot access it.

The question is: should a derived class not really be able to access a private member of its base class (since the derived class and base class are related)? Also, should a base (parent) class not really be able to access a private member of its derived class (since the derived class and base class are related)?

Well, to solve this problem you have another access specifier called, protected. If a member of a class is protected, it can be accessed by a derived class (and vice-versa), but it cannot be accessed by an external function. It can also be accessed by members within the class. The following code illustrates how a derived class can access a protected member of the base class:

<?php

    class Calculator
        {
            protected $num1;
            protected $num2;
        }

    class ChildCalculator extends Calculator
        {
            public function add()
                {
                    $this->num1 = 2;
                    $this->num2 = 3;
                    $sum = $this->num1 + $this->num2;
                    return $sum;
                }
        }

    function principal()
        {
            $cObj = new ChildCalculator();
            $result = $cObj->add();
            echo $result, '<br>';
        }

    principal();

?>

The output is:

    5

The base class has just two properties and no method; these properties are protected. The derived class has one method and no property. Inside the derived class, the protected properties of the base class are used as internal function variables. In other words, the method definition has accessed the protected properties. Generally, when a derived class is using a member of a base class, it is a method of the derived class that is using the member, as in this example. The above code is OK.

The following code will not compile, because line 2 in the principal() function tries to access a protected member of the base class:

<?php

    class Calculator
        {
            protected $num1;
            protected $num2;
        }

    class ChildCalculator extends Calculator
        {
            public function add()
                {
                    $this->num1;
                    $this->num2 = 3;
                    $sum = $this->num1 + $this->num2;
                    return $sum;
                }
        }

    function principal()
        {
            $obj = new Calculator();
            $obj->num1 = 2;
            $cObj = new ChildCalculator();
            $result = $cObj->add();
            echo $result, '<br>';
        }

    principal();

?>

I tried the code and I had,

    Fatal error: Uncaught Error: Cannot access protected property Calculator::$num1 in C:Apache24htdocstemp.php:23 Stack trace: #0 C:Apache24htdocstemp.php(29): principal() #1 {main} thrown in C:Apache24htdocstemp.php on line 23

An external function cannot access a protected member of a class; however, a derived class (method) can access a protected member of the base class (and vice-versa).

Note: A member of a class can access any member of the same class independent of whether the member is public, protected or private. This would take place in the class description (definition).

You should now know the role of the access specifiers: public, protected and private as applied to classes and objects.

A public member of a class is accessible by external functions and a derived class. A private member of a class is accessible only by other members of the class; it is not accessible by external functions and it is not accessible by a derived class. A protected member of a class is accessible by a derived class (and other members of the class); it is not accessible by an external function.

Accessing with External Function Argument
As indicated above, if an external function receives a class member as argument, and uses it successfully within its definition, then the member is visible (public) to the function. Try the following code, which shows how an external function (myFn) accesses a public member, through the argument.

<?php

    class Calculator
        {
            public $num1;
            public $num2;

            public function add()
                {
                    $sum = $this->num1 + $this->num2;
                    return $sum;
                }
        }

    function myFn($par)
        {
            return $par->num1 = 20;
        }

    $obj = new Calculator();

    $myVar = myFn($obj);
    echo $myVar;

?>

The output is:

    20

The argument-passing here, is different from that of a similar code above. Here, the object is passed and the value of the property is assigned within the function. Above, the value is passed, but as an expression that has both the object and the property. The effect of visibility for both casses are the same.

Try the following code, which shows how an external function (myFn) cannot access a private member, through the argument.

<?php

    class Calculator
        {
            private $num1;
            private $num2;
        }

    function myFn($par)
        {
            return $par->num1 = 20;
        }

    $obj = new Calculator();

    $myVar = myFn($obj);
    echo $myVar;

?>

I tried the code, and I had the following output:

    Fatal error: Uncaught Error: Cannot access private property Calculator::$num1 in C:Apache24htdocstemp.php:11 Stack trace: #0 C:Apache24htdocstemp.php(16): myFn(Object(Calculator)) #1 {main} thrown in C:Apache24htdocstemp.php on line 11

Now, it is not only an external function that would want to use the private or protected member of a class or object. A method of an object would also want to use the private or protected member of another object, of the same class. Try the following code:

<?php

    class Calculator
        {
            private $num1;
            private $num2;

            public function mthd($par1, $par2)
                {
                    return $par1->num1 = $par2;
                }
        }

    function principal()
        {
            $objA = new Calculator();
            $objB = new Calculator();

            $myVar = $objA->mthd($objB, 20);
            echo $myVar;
        }

    principal();

?>

There are 2 private variables and 1 public method in the class definition. The method is public, so that it can be seen as a call inside the definition of the principal() function. The principal() function instantiates (creates) 2 objects from the same class. Object-A ($objA) calls its method to access the private member of Object-B ($objB). The first argument of the method is an object and the second is an integer. The output is:

    20

The script worked!

Note: Objects of the same type will have access to each others private and protected members, though they are not the same instances.

Before we leave this tutorial, note that code in the script that is not in any block, needs to be aware, that a class (object) member is private, protected or public.

Time to take a break. We stop here and continue in the next part of the series.

Chrys


Related Links

Basics of PHP with Security Considerations
White Space in PHP
PHP Data Types with Security Considerations
PHP Variables with Security Considerations
PHP Operators with Security Considerations
PHP Control Structures with Security Considerations
PHP String with Security Considerations
PHP Arrays with Security Considerations
PHP Functions with Security Considerations
PHP Return Statement
Exception Handling in PHP
Variable Scope in PHP
Constant in PHP
PHP Classes and Objects
Reference in PHP
PHP Regular Expressions with Security Considerations
Date and Time in PHP with Security Considerations
Files and Directories with Security Considerations in PHP
Writing a PHP Command Line Tool
PHP Core Number Basics and Testing
Validating Input in PHP
PHP Eval Function and Security Risks
PHP Multi-Dimensional Array with Security Consideration
Mathematics Functions for Everybody in PHP
PHP Cheat Sheet and Prevention Explained
More Related Links

Cousins

BACK NEXT

Comments