Encapsulation in PHP

Target Audience: Beginners to Object Oriented Programing who use PHP.  Anyone looking for a detailed explanation of what encapsulation is and examples of how it’s used. Languages Used: PHP 5+ Related Material: PHP Manual – Class PHP Good Practices 1 – Naming Conventions PHP Good Practices 2 – Self-Documenting Code Class Design in PHP OOP in PHP Introduction:

encapsulation 2. The ability to provide users with a well-defined interface to a set of functions in a way which hides their internal workings. In object-oriented programming, the technique of keeping together data structures and the methods (procedures) which act on them. (1998-09-07) Taken from dictionary.comComputing Dictionary.

In order to understand the purpose of encapsulation you first need to  understand the purpose of classes.   Classes are the blueprints for objects, but more then that they are like the building blocks and tools used to make your application.  Your classes should be designed to represent specific characteristics and functionality.  In order for them to be used properly as they were designed, you will need to limit how users of the class can interact with those characteristics and functionality. When I speak of ‘users of the class’ I am talking about anyone who uses the class within their application, including you.  After all these ‘tools’ and ‘materials’ were designed to help you build an application, and that is how they should be thought of when you design them. Encapsulation is the process of creating that interface for users of your class to use.  This is done through the use of visibility modifiers, and interface functions that strictly define how a user can interact with your class.  By doing this you ensure your class is being used as you intend for it, and limit the possibilities of miss-use and unexpected run-time errors. Below we will go over the process of encapsulating a class and explain in detail the purpose of each step with examples of use. Visibility Modifiers In PHP there are three visibility modifiers; private, protected, and public.  These modifiers are used to define what level of visibility a variable or function within your class has.  Each of the modifier keywords represent a level at which the variable or function can be seen outside and within the class. When we talk about ‘seen outside’ the class, I am referring to the interaction with an object that was instantiated from your class.   If your class represents a dog and I create a new dog object from your class, I can then interact with the dog characteristics that are visible outside of the class. If you think of it just like in the real world, if you have a dog in front of you, you can interact with that dog.  You can clearly see the dogs visible characteristics such as size, color, and probably even breed.  You can also perform actions with the dog such as petting it, giving it a command, playing fetch, etc.   Other characteristics and activity is not so visible however such as the dogs temperament or health, or the actions that keep the dogs heart beating and lungs working.   They are very important to the makeup of the dog, however your interaction with the dog is limited only to what is visible to you. Public keyword modifier is used to define a variable or function as being visible to everyone, everywhere.  When this modifier is used the variable or function following is visible to the users using your class as well as all the inner workings of your class.  This modifier is the only modifier that allows interaction outside of the class. Private keyword modifier is used to define a variable or function as being visible only to the inside of the class.  When this modifier is used the variable or function following is invisible to the users using your class, but all the code that you write inside your class will be able to see it. Protected keyword modifier is similar to the Private keyword modifier in that it is visible inside of the class but not to users outside the class.  In addition to that however, the protected keyword also allows child classes that extend the class to see the characteristics as well.  This is useful when inheriting characteristics from a more generic class.  See Inheritance. Interface Functions An interface function is nothing more then a public function inside your class that interfaces with a private or protected member of the class.  This is where encapsulation comes in.   When you want users of your class objects to interact with the internal workings of your class, you do so by providing them an interface function that has public visibility. These interface functions can be used to either return data about the class to the user in a controlled fashion, or to allow the user to change or add data to the class object.  This is done to give you, the author of the class, control over what can be changed, how it can be changed, and even when it can be changed. So what is the benefit?  Stable Code!  If you have a class variable that is an integer , and you have a function in your class that uses that integer to calculate a value, that function will break if the value is anything but an integer.   If you create your interface function so that it checks the users input and makes sure it is an integer before setting the private data field, you know your calculation function will work when called. Lets Apply It! To apply this concept we are going to create a quick and simple person class.  This class will contain a very basic data structure.  We need a variable to hold this person’s name and age.  We will need to supply a constructor so that we can assign the person a name and optional age when we create the object.  We will also need to be able to change the person’s age from outside the class.  Finally we will need to create a public function that will tell us how many years the person has until retirement. Step 1. Build Class Structure.   Our first step is to simply define the structure of our class.  This includes defining our private data fields or members.

class Person
{
    private $_name;
    private $_age;
}

Step 2. Build Class Constructor.  We need a way to assign a name to our person and an optional age when we create our object.  To do this we must have a class constructor.

class Person
{
    private $_name;
    private $_age;

    function __construct($name, $age = 0)
    {
        if (!is_int($age))
        {
            throw new Exception("Cannot assign non integer value to integer field, 'Age'");
        }

        $this->_age = $age;
        $this->_name = $name;
    }
}

Explanation: Our constructor function takes two parameters, $name and $age, where age is a default parameter, meaning if the user does not specify an $age, it will use the default value of 0.  The if statement at the beginning of the constructor checks to make sure age is an integer before setting it.  If it is NOT an integer, which would create problems, we are throwing an error, forcing our users to use the class the way we intend for them to use it. Step 3. Encapsulate $_age, giving the  user a way to change or set the person’s age through a interface function.   This is done simply be creating a public function the user can call.

     public function setAge($age )
    {
        if (!is_int($age))
        {
            throw new Exception("Cannot assign non integer value to integer field, 'Age'");
        }

        $this->_age = $age;
    }

Explanation: The setAge() function only requires a single parameter, $age. We know age must be an integer so we check the user’s input to make sure it is a integer first.  If it isn’t we throw an error, forcing the user to use our interface function the way we intend it be used.  If the condition passes then our private age variable is set to the value of the user’s input $age. Step 4. Provide an interface to retirement years.  To do this we will create another public function for our user to interface with.  This function will use the person’s age to figure out how many years they have left to retire.

    public function yearsToRetire()
    {
        return 67 - $this->_age;
    }

Explanation: This function does not require any parameters.  Amusing retirement age will be 67, simply return the result of 67 – the person’s age.  Since we know that age is always going to be an integer, we can safely execute this function any time! Put It All Together!

class Person
{
    private $_name;
    private $_age;

    function __construct($name, $age = 0)
    {
        if (!is_int($age))
        {
            throw new Exception("Cannot assign non integer value to integer field, 'Age'");
        }

        $this->_age = $age;
        $this->_name = $name;
    }

   public function setAge($age)
    {
        if (!is_int($age))
        {
            throw new Exception("Cannot assign non integer value to integer field, 'Age'");
        }

        $this->_age = $age;
    }

   public function yearsToRetire()
    {
        return 67 - $this->_age;
    }
}

$person = new Person("Wes");
$person->setAge(31);

echo $person->yearsToRetire();

Take It Further. So now you have a Person class with an encapsulated $age filed and a interface function that allows you to find out when the person retires.  The problem is, retirement age is not set.  If the age ever changes we need a way for the user to change it.   See if you can change our yearsToRetire function so that the user can pass the retirement age into the function.  Something to consider; check your users input and make sure you are working with integers. — Live, Learn, Share — Helpful Books: