LEARN PHP IN A DAY: The Ultimate Crash Course to Learning the Basics of PHP in No Time (2015)

Chapter 10. Object Oriented Programming

Introduction

Starting with PHP 5, the object model was rewritten to allow for better performance and more features. This was a major change from PHP 4. PHP 5 has a full object model.

Among the features in PHP 5 are the inclusions of visibility, abstract and final classes and methods, additional magic methods, interfaces, cloning and typehinting.

Object-oriented programming is a style of coding that allows developers to group similar tasks into classes. This helps keep code following the tenet "don't repeat yourself" (DRY) and easy-to-maintain.

One of the major benefits of DRY programming is that, if a piece of information changes in your program, usually only one change is required to update the code. One of the biggest nightmares for developers is maintaining code where data is declared over and over again, meaning any changes to the program become an infinitely more frustrating game of “Where's Waldo?” as they hunt for duplicated data and functionality.

OOP is intimidating to a lot of developers because it introduces new syntax and, at a glance, appears to be far more complex than simple procedural, or inline, code. However, upon closer inspection, OOP is actually a very straightforward and ultimately simpler approach to programming.

Basics

Before you can get too deep into the finer points of OOP, a basic understanding of the differences between objects and classes is necessary. This section will go over the building blocks of classes, their different capabilities, and some of their uses.

Right off the bat, there's confusion in OOP: seasoned developers start talking about objects and classes, and they appear to be interchangeable terms. This is not the case, however, though the difference can be tough to wrap your head around at first.

A class, for example, is like a blueprint for a house. It defines the shape of the house on paper, with relationships between the different parts of the house clearly defined and planned out, even though the house doesn't exist.

An object, then, is like the actual house built according to that blueprint. The data stored in the object is like the wood, wires, and concrete that compose the house: without being assembled according to the blueprint, it's just a pile of stuff. However, when it all comes together, it becomes an organized, useful house.

Classes form the structure of data and actions and use that information to build objects. More than one object can be built from the same class at the same time, each one independent of the others. Continuing with our construction analogy, it's similar to the way an entire subdivision can be built from the same blueprint: 150 different houses that all look the same but have different families and decorations inside.

Class

Basic class definitions begin with the keyword class, followed by a class name, followed by a pair of curly braces which enclose the definitions of the properties and methods belonging to the class.

The class name can be any valid label, provided it is not a PHP reserved word. A valid class name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: ^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$.

A class may contain its own constants, variables (called "properties"), and functions (called "methods").

The pseudo-variable$thisis available when a method is called from within an object context.$this is a reference to the calling object (usually the object to which the method belongs, but possibly another object, if the method is called statically from the context of a secondary object).

New

To create an instance of a class, the new keyword must be used. An object will always be created unless the object has a constructor defined that throws an exception on error. Classes should be defined before instantiation (and in some cases this is a requirement).

If a string containing the name of a class is used with new, a new instance of that class will be created. If the class is in a namespace, its fully qualified name must be used when doing this.

In the class context, it is possible to create a new object by new self and new parent.

When assigning an already created instance of a class to a new variable, the new variable will access the same instance as the object that was assigned. This behaviour is the same when passing instances to a function. A copy of an already created object can be made by cloning it.

Extends

A class can inherit the methods and properties of another class by using the keyword extends in the class declaration. It is not possible to extend multiple classes; a class can only inherit from one base class.

The inherited methods and properties can be overridden by redeclaring them with the same name defined in the parent class. However, if the parent class has defined a method as final, that method may not be overridden. It is possible to access the overridden methods or static properties by referencing them with parent::.

When overriding methods, the parameter signature should remain the same or PHP will generate an E_STRICT level error. This does not apply to the constructor, which allows overriding with different parameters.

Properties

Class member variables are called "properties". You may also see them referred to using other terms such as "attributes" or "fields", but for the purposes of this reference we will use "properties". They are defined by using one of the keywords public, protected, or private, followed by a normal variable declaration. This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.

Within class methods non-static properties may be accessed by using -> (Object Operator): $this->property (where property is the name of the property). Static properties are accessed by using the :: (Double Colon): self::$property.

The pseudo-variable $this is available inside any class method when that method is called from within an object context. $this is a reference to the calling object (usually the object to which the method belongs, but possibly another object, if the method is called statically from the context of a secondary object).

Constants

It is possible to define constant values on a per-class basis remaining the same and unchangeable. Constants differ from normal variables in that you don't use the $ symbol to declare or use them.

The value must be a constant expression, not (for example) a variable, a property, a result of a mathematical operation, or a function call.

As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value cannot be a keyword (e.g. self, parent and static). Let’s look at some examples:

Autoloading Classes

Many developers writing object-oriented applications create one PHP source file per class definition. One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class).

A good way to avoid having to write multiple includes is to use thespl_autoload_register() function. Here is an example:

In the example, above, "MyClass" is the name of the class that you are trying to instantiate, PHP passes this name as a string to spl_autoload_register(), which allows you to pick up the variable and use it to "include" the appropriate class/file. As a result, you don't specifically need to include that class via an include/require statement...

Just simply call the class you want to instantiate like in the example above, and since you registered a function (via spl_autoload_register()) of your own that will figure out where all your class are located, PHP will use that function.

Constructors and destructors

PHP 5 allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used.

Important!

Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call toparent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private).

PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.

Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly callparent::__destruct() in the destructor body. Also like constructors, a child class may inherit the parent's destructor if it does not implement one itself.

The destructor will be called even if script execution is stopped usingexit(). Callingexit() in a destructor will prevent the remaining shutdown routines from executing.

Object Inheritance

Inheritance is a well-established programming principle, and PHP makes use of this principle in its object model. This principle will affect the way many classes and objects relate to one another.

For example, when you extend a class, the subclass inherits all of the public and protected methods from the parent class. Unless a class overrides those methods, they will retain their original functionality.

This is useful for defining and abstracting functionality, and permits the implementation of additional functionality in similar objects without the need to reimplement all of the shared functionality.

Scope Resolution Operator (::)

The Scope Resolution Operator (also called Paamayim Nekudotayim) or in simpler terms, the double colon, is a token that allows access to static, constant, and overridden properties or methods of a class.

When referencing these items from outside the class definition, use the name of the class.

As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. self, parent and static).

Three special keywords self, parent and static are used to access properties or methods from inside the class definition.

When an extending class overrides the parents definition of a method, PHP will not call the parent's method. It's up to the extended class on whether or not the parent's method is called. This also applies to Constructors and Destructors, Overloading, and Magic method definitions.

Conclusion

Let’s look at a few exercises for Classes and Objects before we close this book.

Exercise 1

In this PHP exercise, you will build the beginnings of a user registration form. To do this, you will create a class for making the select field, then use an object derived from the class in the form.

First of all, write an array that includes browser types: Firefox, Chrome, Internet Explorer, Safari, Opera, Other.

Then begin to write the class Select. You will need two properties,$namefor the name of the select field, and$value, an array to provide the option values. You will also need four methods in addition to the two methods you will adapt: setName, getName, setValue, getValue. Checking to be sure the value is an array belongs in the setValue method, so write that here, and delete it from makeSelect .

Now we come to the two functions you wrote to generate the select field. Change the makeOptions function to iterate over the array argument's values rather than keys. This will be your fifth method. Then revise the makeSelect function to be the sixth method in your class.

Next comes the HTML. Write a user registration form asking for name, username, email, browser. Use text fields to collect the user data for the first three, then instantiate an object based on your class for the select field. When the user clicks the submit button, return the data as confirmation.

If you were creating a registration form to use on the Web, you would want to collect the data in a database. However, using PHP with mySQL or other databases is beyond the scope of this website.

Exercise 2

In the last PHP exercise, the Select class may have seemed like an awful lot of code to write for a simple select field. The real value of classes and objects doesn't become apparent until you have reason to reuse the code. So this time, you will expand your user registration form to use several select fields.

Assume that you have good reason to need data about your users' browsing capabilities. Either you want to tune your site, the content of your site concerns these issues, or something similar. Using your select class, you can reuse the class code as often as you like to create select fields.

To build this new version of the registration form, start with the script you wrote for Classes Ex. #1. Add the value of None as the first value in the $browsers array. Write two more arrays: $speeds, including values Unknown, DSL, T1, Cable, Dialup, Other; and $os, including Windows, Linux, Macintosh, Other. (Of course, these could be screen resolution or flash version or any other relevant capability.)

You want data for how the user browses both at home and work. Above the browser select field, add the subheading Work Access, and rename the browser label Primary Browser. (We all know that many people use more than one.) Below that, add labels and select field objects for Connection Speed and Operating System. Next, add the subheading Home Access, with three new select fields corresponding to the ones you created for Work Access.

Since you are using so many objects in this script, it's a good idea to destroy each one after it has done its work. This will free up the memory the object occupied.

When the user hits the submit button, return the user's select field choices in two bulleted lists under the same headings (Work Access, Home Access).

Exercise 3

If you completed PHP Classes Ex. #1 and #2, you have now written a working user registration form. Time to tweak it and make it better.

First of all, it would be preferable to have the message --Select one-- at the top of each select field. Add a line to the makeSelect() method to accomplish this. The value should be No response. You won't need the "None" value at the top of the $browsers array, so delete that. With this change to class Select, you can see how using a class can simplify your work. One line of code, and all the select fields update.

Your user responses won't be very useful without some basic information, so the next task is to make three of the fields required. Above the form, add * Indicates required field. Then add an asterisk to the Name, Username, and Email fields.

Next, add code to validate the data in those three fields. This code will appear in the second half of the script, after you have retrieved data from the $_POST[] variable. The function empty() will let you know if there is data in the field. To help the user supply missing information, include a back button with the error message. (If you completed Forms Ex. #3, you have already written one of those.)

The email field is a special case. Not only can you check for the presence of data, you can check for an @(at symbol), which would be included in any valid email address. So here the data must satify two conditions to be acceptable. You can use the strpos() function to confirm the presence of the @ character.

Congratulations! You did it. This was the last chapter in our PHP course. You should now be able to create your own applications and tackle all sorts of projects. We hope you enjoyed this book as much as we did writing it. Hopefully you found it useful and you took away some useful concepts and techniques.