PHP5 Abstraction for the Rest of Us

Abstraction for the rest of us

Millions of web developers, from those just starting out with sparkling ampersands in their eyes to hardened veterans with ‘’ burned to the back of their retinas, have found a love for PHP and its possibilities but still talk in hushed whispers about the mystery and intrigue of Object Oriented Programming (OOP) in PHP.

This tutorial aims to remove some of the curly-brace-filled haze that often surrounds OOP and by the end of this lesson you will have created a class, instantiated an object, given inheritance to some children and come to understand why OOP is such a powerful tool to have at your disposal. If you have no idea what any of the above means but are shaking with a desire to find out, read on as we look at Abstraction for the rest of us.

What is OOP and why would I use it?

OOP is the process of abstracting (removing and isolating) variables and the actions required to manipulate them. By grouping the code together in a logical manner you are able to create objects – self contained areas of code that will perform the necessary actions allowing you to deal with results separately to the actions that generate them.

Using the Procedural Approach (the name given to a program that runs from top to bottom following a designated procedure), if you wanted to write a script in which you kick a ball and find out where it lands, you would need to create variables (or an array) for the ball, its position, the speed it was kicked etc.. You would then need to write the functions that process these variables and all of this would be included into and/or intermingled with the code that works with outputting or storing results.

In any script that you wanted to kick a ball and see where it lands, the variables would need to be created and the functions to manipulate them would need to be included.

Using the Object Oriented Approach, instead of creating all these variables and functions (which have no explicit ties to each other), you would create a ball object. The ball object would contain variables pertaining only to it (properties) and functions that deal almost exclusively with these properties (methods). You would not have to worry about including the right functions or the scope of your variables, you would only have to tell the ball what you want it to do -- be kicked -- and ask it what you need to know -- where did you land?--.

  • When dealing with the variables of objects, we call them properties as although they behave exactly the same way as variables, they relate specifically to that object.
  • Similarly, when dealing with objects, functions become methods – objects have methods to access and alter properties

Each time you wanted to perform these actions, it would simply be a matter of creating the ball object and asking it what you want it to do. This is where the power of OOP starts to emerge, the flexibility of Abstraction. By grouping the properties and methods together logically, they are isolated and can be included where needed functioning almost like self-contained programs that can be slotted together like blocks of Lego.

OOP allows for flexible, easily expandable and graceful programs.

Okay, how do I do this in PHP?

To create an object, you first need to create a blueprint for the object. The blueprint outlines what properties (variables) the object should possess and what methods (functions) the object should be able to perform. This blueprint is called a class and is best looked at like a cookie cutter. A cookie cutter defines the shape of the cookie and can be used to punch out as many cookies as needed. A class defines the shape of an object and can be used to create as many objects as needed.

DEFINING A CLASS

To create a class in PHP, you use the class keyword and give it a name – similar to way you would declare a function. The class definition is surrounded by curly braces.

class    className
{

// Class definition goes here
}

BUILDING AN OBJECT

Now that you have a blueprint (however useless it is in its present form) you can create an object. This process is called instantiation.

To instantiate an object it’s time to use another PHP keyword that you may not have encountered – new.

<?php
class    className
{
// Class definition here
}
//Instantiate the object
$anObject    = new className;
echo ‘$anObject is now an object built from the’, get_class($anObject), ‘ class’;
?>

That’s it! Obviously this is just the shell but it is all that is required to start building objects.

GIVE YOUR OBJECT SOME IDENTITY

Now it’s time to get your hands dirty and learn how to build objects with properties and methods.
A common task that performed by PHP is to maintain state for a user as he/she moves around the site, the rest of this tutorial will focus on defining a class that will create ‘user’ objects, giving access to and allowing modification of a user’s preferences.

Start by defining the class:

<?php
class    myUser
{
}
?>

A user travelling around your site will have some properties that will change from user to user. Some of these properties might be:

  • First & Last Names
  • User Name (For use on the site)
  • Email address
  • Age
  • Gender

To add these to your blueprint or class, you specify a Visibility Identifier followed by a normal variable declaration.

What’s that? What the hell is a visibility identifier? Good question. In PHP5 there are some special keywords called visibility identifiers that are used to define the scope a property or method of an object is available to.

  1. Public – declaring a property as public means that it can be accessed inside or outside of an object. So any function or any other PHP code can read or set the property.
  2. Private –declaring a property or method as private restricts access and only allows that property or method to be accessed inside the object itself.
  3. Protected – declaring a property or method as protected restricts access and only allows that property or method to be accessed from within the object, or within an object that is from a child class (inheritance and children will be explained below).
  4. Static, Abstract and more – You will see more keywords appearing before properties and methods. These aren’t visibility identifiers but can be used when declaring a property or method.Declaring a property or method as static means that you can access that property or method without creating an object first. It means you can access it straight from the class without having to instantiate an object first.Abstract classes and methods are beyond the scope of this tutorial but in a nutshell, an abstract class/method defines what methods child classes should implement. The children can’t actually use that method; they have to implement it themselves.

The user class now looks like this:

<?php
class    myUser
{
public    $firstName;
public    $lastName;
public    $userName;
public    $email;
public    $age;
public    $gender;
}
// Instantiate the object
$user        = new myUser;
?>

The object in $user now has all of the properties defined in the myUser class. Knowing that $user has these properties is fine, but you need to be able to access them.

To access a public property of an object you use the following syntax:

$user->firstName; // $Variable->propertyName

Notice that when you want the property name you drop the dollar sign and just write the name. You can assign a value to a property using the same syntax:

$user->firstName = ‘Luciano’;

An object property can hold almost any data type including other objects.

NB: Trying to read or write a private or protected property will result in a fatal error.

GET SOME ACTION – DEFINING METHODS

Now that you know how to get and set the properties of an object, you would be able to populate all the properties with values and access them, but using this technique would mean your object wouldn’t be anything more than a glorified array. It is a coding convention – and highly recommended – that you avoid accessing object properties directly, you should instead access and modify object properties using methods written for the task. These methods are usually referred to as getters and setters. One method gets the property value and another sets the value. There are many reasons this practice is preffered including but not limited to:

  • PHP allows you to create properties on the fly which may lead to bugs in your code. For example $user->firstNam = ‘Luciano’; would not throw and error, instead it would create a ‘firstNam’ property in $user. Later, when $user->firstName; doesn’t return the expected result, it may not be easy to find out why.
  • Methods allow you to perform checks and tasks on data before assigning it to a property. Adding an array to the firstName property would not be very useful as people aren’t usually named in arrays. With methods you can check that the data is what the object expects before changing the property.

The code below shows how to add two methods to your user class. One will set the firstName of the user and the other will return it you can use it (eg. Echo it to the screen). As there is now a setter and a getter for the firstName property, the visibility identifier can be changed to private.

<?php
class    myUser
{
private    $firstName;
public    $lastName;
public    $userName;
public    $email;
public    $age;
public    $gender;

public function setFirstName($name)
{
//Check that the data is valid for use as a firstname
if (ctype_alpha($name))
{
$this->firstName = $name;
return true;
}
// Return false if the data is not valid
return false;
}
function getFirstName()
{
// Return the current value of firstName
return $this->firstName;
}
}
//Instantiate the user
$user = new myUser;

// set the user’s first name
if ($user->setFirstName(‘Luciano’))

echo ‘$user now has the first name ’, $user->getFirstName();

else
// If the method returns false, something is up
echo ‘That first name isn’t valid’;

?>

There’s quite a bit happening in the myUser class now so let’s analyse what’s going on. Something obvious is that the only difference between declaring a method and declaring a function is that that a method is declared within a class’s curly braces. The example above declares the public visibility identifier on one function but not the other to illustrate that public is the default visibility of methods. Not declaring an identifier will mean the method is publicly accessible.

function setFirstName($name) defines the method setFirstName that will accept the argument $name, using a simple check to determine if $name contains only letters from the alphabet. If it is alphabetic, $name will be assigned to the firstName property using the special variable $this. $this refers to the current object instance that is calling the method

$this->firstName = $name;

is exactly the same as

$user->firstName = $name;

Anytime you need to refer to the current object calling your method (in the case above $user), use the $this special variable – this removes all headaches about how to address a certain object.

The next method is named getFirstName and will return the object’s current firstName property – again note that we are using the special $this variable which is really saying “Return the value of the firstName property for the $user object”.

In the code above you have now instantiated the object $user and called (invoked) the methods defined. So invoking a method is the same as calling a function except you preceed it with the variable name and ->

$user->setFirstName(‘Luciano’); //$variable->methodName($arguments)

ADDING A CONSTRUCTOR

You can now add methods that allow you to set and get all of the properties in a myUser object.
Although this has abstracted the properties and methods, it would be cumbersome to call a method and set every property each time you created an object. To fix this problem you can define what is known as a constructor method. In PHP5, the constructor function is a public method named __construct. As the name suggests, the constructor helps to build an object.

For your user class, define a constructor method to set all the properties at the same time the object is created.

<?php
class    myUser
{
private    $firstName;
private    $lastName;
private    $userName;
private    $email;
private    $age;
private    $gender;

// constructor method, accepts all properties
// to be assigned when myUser object is instantiated

function __construct($firstName, $lastName, $userName, $email, $age, $gender)
{
$this->firstName        = $firstName;
$this->lastName        = $lastName;
$this->userName        = $userName;
$this->email        = $email;
$this->age            = $age;
$this->gender                = $gender;
}

//………………………………..further methods
}

//Instantiate the object using the contructor

$user = new myUser(‘Luciano’, ‘Dinglini’, ‘Rakuli’, ‘rakuli@example.com’, 23, ‘Male’);

echo ‘$user->firstName was set to ’, $user->getFirstName(), ‘ by a constructor method’;

?>

You will see from the above code that the only change to creating the object is to add the arguments accepted by the myUser constructor method – just like a function call only preceded by the new keyword. All of the properties are now set when the object is created.

In the example above, the constructor requires all values to be given when invoked. A user visiting a site might not want to give an email address or their age – you can overcome this by making some or all of the arguments for the constructor optional. By doing this, you can still create an object but fill the properties with default values until set later with methods.

When a user first arrives at your site, you might instantiate a user object from a constructor method that looks like

function __construct($userName = 'Guest', $firstName = '', $lastName = '')
{
$this->firstName    = $firstName;
$this->lastName        = $lastName;
$this->userName        = $userName;
}

This would allow set the userName property as ‘Guest’ if you didn’t include it when creating the object. Later, you could set the user name with a method that might be $user->setUserName(‘Rakuli’);

FLEXING YOUR PROPERTIES

That’s it! The basics of OOP in PHP, with what you know now you can create all of the methods for setting and getting your user’s properties.

The class could now look like this:

<?php
class    myUser
{
private    $firstName;
private    $lastName;
private    $userName;
private    $email;
private    $age;
private    $gender;

// myUser - constructor method, accepts all properties
// to be assigned when object is instantiated
function __construct($userName = 'Guest', $firstName = false, $lastName = false)
{
// delegate the setting of the properties to the defined methods

$this->setUserName($userName);
$this->setFirstName($firstName);
$this->setLastName($lastName);
}

function setFirstName($name)
{
//Check that the data is valid for use as a firstname
if (ctype_alpha($name))
{
$this->firstName = $name;
return true;
}
// Return false if the data is not valid
return false;
}

function setLastName($name)
{
//Check that the data is valid for use as a lastName
// We'll let them get away with having 1 hyphen and 1 apostrophe only
if (substr_count($name, '-') > 1 || substr_count($name, ''') > 1)
{
// Sorry Mr O'reilly-O'brien I know you may be out there but
// I'm keeping it simple for now
return false;
}

if (ctype_alpha(str_replace(''', '', str_replace('-', '', $name))))
{
$this->lastName = $name;
return true;
}
// Return false if the data is not valid
return false;
}

function setUserName($name)
{
//Check that the data is valid for use as a userName
if (ctype_alpha($name))
{
$this->userName = $name;
return true;
}
// Return false if the data is not valid
return false;
}

function setEmail($email)
{
// Very simple regex to check email validity
if (preg_match(&quot;/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$/&quot;, $email))
{
$this->email = $email;
return true;
}
// Bad email address
return false;
}

function setAge($age)
{
// We'll make sure they're not still in diapers or trying to set a guiness world age records
if (is_numeric($age) &amp;amp;&amp;amp; $age &amp;gt; 5 &amp;amp;&amp;amp; $age < 120)
{
$this->age = (int) $age;
return true;
}
// Lying about your age?
return false;
}

function setGender($gender)
{
// Run a quick switch -- allows for a few methods of declaring your gender identity
switch(strtoupper($gender))
{
case 'MALE' :
case 'M' :
case 'MAN' :
$this->gender = 'M';
return true;
break;
case 'FEMALE' :
case 'F' :
case 'WOMAN' :
$this->gender = 'F';
return true;
break;
}
// Gender remains ambiguous
return false;
}

function getFirstName()
{
// Return the current value of firstName
return $this->firstName;
}
function getLastName()
{
return $this->lastName;
}
function getUserName()
{
return $this->userName;
}
function getEmail()
{
return $this->email;
}
function getAge()
{
return $this->age;
}
function getGender()
{
return $this->gender;
}
}
?>

I can hear you saying now – but this is still only an array that validates data types it allows me to store and retrieve data but I can’t do anything with it. In its present form? Yes, but now you can get creative and start defining methods utilising the variables.

Try creating a method to say hello to your user:

/ This method will return a welcome message for the user

function helloUser()
{
$message = '

';
$message .= 'Hello' . $this->userName; // If userName wasn’t given, this will show ‘Guest’

// If we have first and last names, we'll show those in brackets
if ($this->firstName || $this->lastName)
$message .= ' <span style=&quot;font-size: xx-small;&quot;>(' . ($this->firstName ? $this->;firstName : '') . ($this->lastName ? ' ' . $this->lastName : '') . ')</span>';
$message .= '

';

// Make a remark about their age?
if ($this->age)
$message .= '

It's nice to have a ' . $this->age . ' year old on this site!

';

// return the message
return $message;
}

Now you can see that this method will deal with the context for you. It will display a nice hello and also the user’s real name -- but only if it’s set. This is the Abstraction that OOP allows. Once you have created this class all you ever have to worry about is $user->helloUser() and you will be returned a result without having to worry what’s going on in the object.

Using the ball analogy from earlier, you don’t have to worry about what’s affecting it, you just kick it and it’ll see where it lands – how it gets there is for the ball to sort out.

Now that you have the basics of OOP down you can build objects and work with the properties in any way you like and the beauty is that when you want the result, you never have to do more than $user->askForIt()

PASS THE OBJECT TO YOUR LEFT

Now that you can define classes, build objects and work with the object’s methods you may wonder how you would go about maintaining state as promised above. You can do this using two of PHP’s most useful functions.

serialize() and unserialize()

After instantiating an object and working with the methods to flesh out its properties, you can pass the object through serialize to convert the object – and all of its properties -- to a string. This is nothing more than a normal string that you can pass it from page to page with $_SESSION or even store in a database. When you want to use the object again, you can revive it using unserialize.

PHP5 also has a couple of special methods that you can define that will be run when you serialize and unserialize objects.

  • __sleep – When you serialize an object, __sleep will be run on your object. You can use it to clean up properties or data that doesn’t need to persist. For example, you might disconnect from a database or release resource handles.
  • __wakeup – When you unserialize an object (or wake it up as it may be), you can use this function to restore properties or data lost when sleeping. You may reconnect to a database or grab hold of those resource handles again.

NB: In order to unserialize an object, you must have the class that it was created from included or defined in the current script. This is achieved by simply creating your class in a separate .php file that can be included when needed.

IT RUNS IN THE FAMILY

Inheritance is one of the most powerful philosophies of Object Oriented Programming. The ideological roots are founded in the evolution of the human race.

When a child is born, it inherits various features (properties) and behaviours (methods) from its parent. It isn’t a carbon copy of the parent though. It may behave slightly differently and will have some different features. This child may then have children of its own, with features and behavior slightly different again.

In OOP, the premise is exactly the same. There are parent classes, these can then be extended by child classes. The child class inherits most of the properties and methods from the parent but can also re-declare them so they behave differently to the parent.

The concept can be quite obscure initially so an example may be best. Take your myUser class and change the declared properties to protected. (Remember that protected properties can be accessed within an object instance and also within child object instances.)

It’s now time to create a child class that will extend the parent class:

<?php
class    myChildUser extends myUser
{
//myChildUser extends myUser so there is no need to declare
// all the properties again, just declare properties that are unique to the child class
private    $petsName;
private    $twitterName;

// Child constructor will also call parent constructor
function __construct($petsName, $twitterName, $firstName, $lastName, $userName, $email, $age, $gender)
{
$this-&amp;gt;petsName        = $petsName;
$this-&amp;gt;twitterName        = $twitterName;
//use the parent constructor to set the remaining properties
parent::__construct($firstName, $lastName, $userName, $email, $age, $gender);

}
// override the getLastName function to return pet name instead (sneaky)
function getLastName()
{
return $this-&amp;gt;petsName;
}

//………………………………..further methods
}

//Instantiate the child object

$user = new myChildUser(‘Luciano’, ‘Dinglini’, ‘Rakuli’, ‘rakuli@example.com’, 23, ‘Male’);

echo ‘$user->firstName was set to ’, $user->getFirstName(), ‘ by even though the logic to do so is not in this class’;

?>

On initial inspection, this class looks just like the others that have been created so far but the differences are important to note.

The first is the way the class is declared. The declaration is normal at first you will notice that there is the additional extends myUser. The keyword extends means that this class extends (or inherits properties and methods from) the class myUser. So without anything more than this class declaration and some curly braces, you would have a full working class that does everything the parent myUser class does.

A child class that simply mimics its parent isn’t entirely useful though. The next part in this class declaration defines some properties that are private to the child. $petsName and $twitterName will only be available to instances of myChildUser. These properties will not be available in instances of the parent class.

You’re probably wondering what the deal is with the next part of the class declaration. Normally, PHP does not allow two functions to have the same name but myChildUser is declaring __construct after myUser already declared it. This very powerful concept is known as overriding a parent method. It allows you to have a child class with identical method names, just different results. For example, if you were getting the age from myChildObject, you may wish to convert years to months if the child is young enough. This processing isn’t required by the myUser class because you know all instances are of adults.

The final noteworthy difference from the simple child class above is shown inside the __construct method. It comes in the form of another PHP keyword parent. Just like the $this special variable, parent is only available inside an object instance of a class. parent allows you to run methods of the parent, including methods that are overridden in the child. The __construct method in myChildUser runs the parent::__construct method meaning that the one act of instantiating the myChildUser class, also achieves the effects of instantiating a myUser obj.

Inheritance will be one of the most revolutionary discoveries you will make in programming so I suggest playing with objects and inheritance, trying overrides and multiple generations of inheritance (where you create a child class of a child class) to show just how useful the concept is.

Popular PHP frameworks like CakePHP, use inheritance with almost all classes inheriting from one base class.

STATIC ELECTRICITY

One last concept to look at with the possibilities introduced by PHP5 objects is the use of static properties and methods to implement namespaces. (This is not true namespace support as found in other languages but a means to achieve a similar effect.)

What’s a namespace you ask? Think of a namespace as a library. The library has a name “Uptown Public Library” and inside it there is a book called “Special Book”. One town over, there is a library called “Downtown Library”, it also has a book called “Special Book”. Each library has a different edition of the book and they are very different in all but name. “Special Book” from one library would be very different to “Special Book” from another.

This is the concept of namespaces. You can have functions and variables with the same name, except they are part of a different namespace.

Again, this is an abstract idea at first and an example will help.

<? php
class namespace1 {
static $val = 1;
static function method () {
return 1;
}
}
class namespace2 {
static $val = 2;
static function method () {
return 2;
}
}
echo namespace1::$val, namespace1::method();
echo namespace2::$val, namespace2::method();
// Output will be 1122
?>

So by defining static properties and methods of classes, you can treat them just like variables and functions in procedural programming. To access a class’s static properties and methods you use the class name two colons plus the property or variable name. classname::$staticprop classname::staticmethod()

You cannot use the parent or $this keywords inside static properties because they are not attached to an object instance. Trying to use these keywords will result in a PHP error.

Using classes as namespaces means you can define multiple variables and functions that have the same name. You can then use them by calling them statically through their class name.

Okay, better recap

So to sum up what we have covered in this basic introduction to OOP.

Why Use It?

OOP allows you to create individual blocks of self maintained code. The objects can take care of the processing and context, leaving you to work with the results.

How Do I Use It?

In PHP you use the class keyword to define the blueprint – or cookie cutter – and fill this class with properties (using the Visibility Identifiers to define where the property or method can be accessed from) and methods (defined just like normal functions) that your object will contain. When you’re ready to create an object, you use the new keyword with your class name.

If you want a method to be invoked when instantiating an object, you define a constructor method using the special __construct method name, you can then pass arguments that will be attached to variables or used for other actions when creating an object.

Another look at a class definition:

<? php
class className
{
// Although it's not advisible, I can access and change this property
// Using the following syntax on the variable that holds my object
// $myObject->property = 'Setting the value';
// $value = $myObject->property . ' getting the value';
public $property;

function __construct()
{
// This will be run when I create an object
// I put the object in a variable using the new keyword
// $myObject = new className();
}

function method()
{
// I can use this method with the syntax
// $variable->method();
}
}
?>

Won’t you think of the children?

You can create a class that extends another, inheriting its properties by using the extends keyword. Inside of a child class, you can add new properties and methods, as well as overriding methods defined in the parent class. If you want to access a method found in the parent, you can use the parent keyword to call it. parent::methodname()

Statically Speaking

Using classes full of static properties and methods gives you a way of grouping data by namespace (where the name is the name of the class)

Anything Else I Should Know?

To store your objects as a string to move around in the $_SESSION superglobal or save to a database you can use the serialize function.

$string = serialize($myObject);

$myObject = unserialize($string);

You need to make sure PHP can find the class definition when using unserialize.

That concludes this quick overview of Abstraction For The Rest of us. Using the tools above, you should be able to take advantage of the logical programming OOP allows.

Glossary of OOP terms

Abstraction
The process of grouping together and isolating variables and functions and tying them together into an object that can be dealt with separately to the results they produce.
Child
A child class is a class inheriting objects and methods from another class – the parent.
Class
(noun)The blueprint for an object. Comparable to a cookie cutter – a class can be used to create many objects with predefined attribute.
(php keyword)Used to tell PHP that you are declaring a class.
Constructor
A method that is invoked at the same time an object is Instantiated (see Instantiation). A constructor can be used to set properties of objects when created.
Extends
(php keyword) Used to define a class that is an extension of another class. The class being extended becomes the parent and the extending class becomes the child.
Instantiation
The process of creating an object from a class. Instantiation is comparable to using a cookie cutter to cut a cookie from some dough.
Invoke
The functions of an object, know as methods, are run using the syntax $variable->methodName(). To call an object function is to invoke and object method.
Method
Functions of an object are known as methods. Methods handle the conditional processing in order to retrieve and modify object properties.
New
(php keyword) New is the keyword used to instantiate and object. The syntax $myObject = new className();
Overriding
Overriding is the processing of declaring a method in a child class that has the same name as a method in the parent class. This allows the child to process data differently to the parent when that method is invoked.
Parent
(noun) A parent class is the base class. When it is extended by another class it becomes the parent class allowing child classes to inherit its properties and methods.
(php keyword) a keyword that can be used in a child class to address methods in the parent. Most often used to access a class that the child may have overridden. The syntax for using the keyword is parent::methodName();
Properties
Variables of an object are known as its properties. A property relates solely to that object.
Visibility Indentifier
(php keyword) Used to define the visibility of class properties and methods. There are three private, protected and public.
Static
(php keyword) A static property or method can be accessed through the class, instead of through an object created by the class.
Namespace
A way of group data and behviours under a common name. The gives data and behviour a context and it also avoids issues arising from name clashes.

21 Comments on "PHP5 Abstraction for the Rest of Us"

  1. Two great articles in less than a week! Nice one.

    The one thing I would like to point out is that PHP does not support multiple inheritance as generally defined (i.e. one class with multiple parents). The way you’ve defined it IS supported, but multiple inheritance means something different to some people.

    Cheers!

  2. Jack F says:

    Really awesome post Rakuli, I never really “got” OOPHP and it was a similar tut by you back at WF that got me into it, so glad I did!

  3. Robbe says:

    Really nice intro to OOP in php, enjoyed reading it.

  4. Luke Dingle says:

    @Christopher Hyne – You make a good point. True multiple inheritance is not available in PHP yet (where a class can inherit from more than one parent class) but it could possibly confuse people coming from languages that support it. I will update the post changing my description to multiple generations of inheritance. Thanks!

    @Jack F – Cheers mate. The tutorial for Webforumz was on PHP4 objects so I thought I would update to PHP5. Glad it helped you.

    @Robbe – Thanks, I’m glad you liked it.

  5. Jeff Gran says:

    This was very helpful for me, thanks for a great introduction to OOP concepts in PHP. I’ve been hacking around in Joomla and WordPress for a while now and this helps me understand exactly how some of that code I’ve been writing really works under the hood. :)

    I noticed a couple of typos (I think) that I thought I would point out:

    The line: “if ($user->setFirstName(‘Luciano’)” is missing a ).

    Also, when you’re introducing the child class constructor, it could be that I’m not understanding how it works, but it looks like it’s a mistake. you have:

    function __construct($firstName, $lastName, $userName, $email, $age, $gender)

    and then:

    parent::__construct($firstName, $lastName, $userName, $email, $age, $gender);

    Should the constructor have the new (child-only) properties as arguments as well?

  6. Luke Dingle says:

    Hi Jeff. Thanks for the kind words, I’m glad it helped you get an understanding.

    My apologies, your eyes have indeed picked out a couple of typos. You’re correct in both cases :)

    I have updated them (would hate someone to have a bug due to my mistake).

    Thanks for taking the time to point them out.

  7. You have an error in your example with static properties/methods. Methods are accessed via Class::method(), that’s right, but properties have a $ before the name or to talk php: Class::$property

    Right now the output of your static electricity script would not be 1122 but “Fatal error: Undefined class constant ‘val’” as he tries to access a class constant which would have to be initialized with const var = ‘abc’ ;-)

    Also note, that protected methods/properties cannot only be accessed by child-classes but also by the parent classes. Try this:

    <?php

    class ClassA
    {
    public function output()
    {
    print($this->var);
    }
    }

    class ClassB extends ClassA
    {
    protected $var = ‘Hello World’;
    }

    $class = new ClassB();
    $class->output();

  8. Luke Dingle says:

    Oh dear. It seems that I proof-read this post with a blindfold on. Another update :D

    As for the protected variables, this isn’t mentioned as not being possible, as the inference is that a child will inherit the method being able to use it. The practice itself would not be very logical though.

    Thanks for pointing out the problems though, much appreciated.

  9. Bogdan Popa says:

    Good article but I don’t see the reasoning behind writing the “getSomething” methods in the User class when all of the variables you’ve written the methods for are public anyway. Just using $x = $user->var; would be about 10x as fast and you wouldn’t have to write the methods in the first place, saving you some time.

  10. Luke Dingle says:

    @Bogdan – I explain some of my reasoning in the article but there are more reasons. You are correct, it’s faster to code (and a bit faster to execute) by getting properties directly when working with instances of the object, but not nearly as much as you say. My example class — the full one — declares all properties as private so getting them as you suggest would cause fatal errors.

    If you’re coding in a small environment then having public properties all over the place may work for you but as soon as you start writing the classes, with someone else writing the code that works with them, setters and getters become much more important. If all these properties are hard coded everywhere, changing the property in the class would require all references be updated in client code. With a getter, it’s a simple matter of returning the new property value with the same function and then updating the change log with a deprecated notice. Also, the work you’re able to do with the value is not being fully exploited by simply fetching public properties. PHP5 does have methods that can be run when a non-existent property is read, the same for methods, but in my opinion, the benefits of getters and setters outweigh the benefit of the alternative (not in 100% of cases but, in my experience, most) and not using getters and setters will cause you trouble the day you change a lot of the class.

  11. Shawn says:

    You sort of got namespaces completely wrong. Namespaces aren’t being introduced until 5.3 and they will use the \ as the separator, not the static/scope (::) operator. Also, the static keyword means much more than just being able to access it without instantiation.

  12. Luke Dingle says:

    Hi Shawn. Yes I am aware that namespaces do not exist in current versions of PHP. What I speak of above is a way of getting some of the benefits of namespaces in the current PHP architecture — this
    is nothing like namespace support in other languages nor is it like upcoming support in PHP 5.3.

    An introduction to OOP cannot cover everything in detail and the many uses for static is not all that I have not gone into. This article is not meant as a reference for OOP in PHP but an overview shedding
    some light on the topic.

  13. rich97 says:

    Holy moly Luke, you’ve done it again. Thanks a lot for this. Very clear and concise.

  14. Student says:

    I’ve tried to use the code and follow along. A couple of issues are when you use ”’. I’m not sure if that’s valid. I have to use quotes or a backslash to escape them. Also once I get to the __construct with default values. I can no longer get my code to output the variables passed into the object. Has anyone else tested this and had the same results? Could we get the source code all zipped up to test? I hope its just something dum I’m doing. I’ve been looking at it for hours.

  15. Luke Dingle says:

    Hi Student,

    Sometimes these code syntax highlighters can insert strange characters. Can you explain exactly where it’s going wrong and I may be able to help.

    I’ll try find time to zip up a copy too if I can.

  16. Andres says:

    hi, excellent article,I’m asp.net programmer and I’m so far beginning with PHP, I see that the new OOP features are excellent, as I am a bit confused with the syntax, but it is normal, very good article!

  17. cc says:

    Hey there. Just thought I’d say thanks for giving a rundown on this topic. Brings back memories of my Java days. Look forward to more on this topic in the future.

  18. Alberto says:

    Hello. Good tutorial. Thanks.
    Need a help.
    If I want to create an object with generic standard class, I can do :

    $myObject = new stdClass();

    I can set a data member (property) as :

    $myObject->myProperty = ‘hello world’;

    how can I set a method?

    Thanks.
    Alberto

    note
    the instinct way doesnt work.

    function fun1 (){
    echo “Im fine”;
    }

    myObject->fun1; //doesnt work

  19. Alberto says:

    I mean :

    function fun1 (){
    echo “Im fine”;
    }

    myObject->myMethod = fun1; //doesnt work

    thanks

  20. Luke Dingle says:

    Hi Alberto,

    There are ways to dynamically add methods to an object at runtime but you would need to have a very strong case for doing so. If the fingerprint of the class is going to change at runtime then you may not be looking at OOP in the correct way.

    In PHP 5.3, Lambda functions (and closures) are being introduced which allow creation of functions at runtime with a syntax much more similar to that seen in other languages. It has been possible to do this previously but you have to use the clunky create_function. There is a great overview of this new implementation at http://fabien.potencier.org/article/17/on-php-5-3-lambda-functions-and-closures

    I must point out that the original draft for Lambda functions in PHP specifically said “This is not intended as a way to dynamically add methods to objects”

    If you define a class yourself, there is a way to add functions dynamically, a great tutorial can be seen here.

    If you’re bound to using the standard class (stdclass), you probably won’t be able to do what you want. An instance of the stdclass isn’t much more than an array with different syntax.

Got something to say? Go for it!