Skip to main content

Simple examples of working with PHP classes.

---
title: Introducing PHP Classes
author: Codular
date: July 14, 2012
source: http://codular.com/introducing-php-classes
---

## Introduction

Working with classes in PHP is a great way to streamline your code, and make it
awesome. Classes or object oriented (OO) programming are sometimes seen as
behemoths of satan, but actually they're easy. Once you understand all the
various levels of privacy, extensions and more recently magic methods. For the
sake of simplification we'll be using PHP, and modelling a man and a woman as
classes, with a few basic attributes of varying privacy levels.

## Man + Woman = Person

Men and women are pretty similar - a lot more similar than people think, but
there are some crucial differences. Some of the shared attributes are things
like eye colour, hair colour, height and weight. But there are a couple of
glaring differences between the two such as reproductive organs, gender and
chromosomes.

The way that inheritance works in classes is that you put as many common items
within one class and then extend that parent class for each sub-class. Sound
complicated? Let me clarify, we have a class of `Person` that will be extended
to create `Man` and `Woman`. There will be some specifics that we set by default
when we create a new `Man` or `Woman`.

To run an action on initialisation of a class, we look to add a _constructor_,
this means that when you create a new man using `new Man()` the constructor will
run and we can set the gender specific attributes:

```php
class Person {
    private $alive = true;

    protected $gender = '';
}

class Man extends Person {
    public function __construct(){
        $this->gender = 'male';
    }
}
```

As you can see, we have used the word `extends` to show that `Man` is an
extension of the `Person` class. You can imagine this as the variables within
`Person` being copied to a new class called `Man` so they are available to use
if their privacy allows.

### Privacy

What you'll see in the above code is words such as `protected`, `public` and
`private`, these are varying levels of privacy and dictate where these
attributes can be altered, or functions called:

* **Public** \- Can be called anywhere, outside of the class, inside the class,
  or even in a child.
* **Protected** \- Can be called from only within the current class or any
  children of that class (eg: `gender` can be altered by `Person` or `Man`)
* **Private** \- Can only be called by the containing class. (eg: `alive` can
  only be altered by `Person`)

### $this, parent, self, static

Above, you'll see reference to `$this`, this just refers to the current instance
of the object that you're in, `$this` can and does creep up the chain, so I can
access inherited variables using `$this` as above.

If I have overwritten a method within a child class, I can call the parent
method by using `parent::method()`, so for example if we had a constructor
within the `Person` class we would call that from our `Man` class by using
`parent::__construct()`

`static` methods of classes can cause some complications. A static method is one
that you can call without having to instantiate an instance of the object that
you're using. For example if we had a class, `Site`, which has a helpful static
function, `relativeTime`, we could call that function by using the code
`Site::relativeTime()`. Some things are clearer with examples:

```php
class Site {
    public static function relativeTime(){
        return 'Yesterday';
    }
}

Site::relativeTime()
/*
    If we had to instantiate the class we'd do
    $site = new Site;
    $site->relativeTime();
*/
```

When within a static function we can't use the `$this` notation, as that refers
to instantiated objects only, so we will want to use the keyword `self`, this
works very much the same as the `parent` keyword that is mentioned above. One
thing to note is, if you're attempting to modify a static variable, you will
have to use a `$` as well before the variable name - see the differences below:

```php
// Set static variable 'name' of 'Person':
Person::$name = 'bob';
// Set variable of instance of 'Person':
$person = new Person();
$person->name = 'bob';
```

## Magic Methods

Sometimes referred to as _Overloading_, this is the instance by where you can
have a generic function that is called if you try to get or set a variable that
doesn't exist, or try to call a function that doesn't exist. There are 4 that
I'll run through, and they're all very similar they are `__get()`, `__set()`,
`__call()` and `__callStatic()`. Make sure that you declare all of these as
public.

### Set and get

If we try to set or get a variable that doesn't exist, inherently PHP will throw
an error, here we can gracefully handle that by actually using a method to
handle that. This is very useful if - as with active record methodology -
variabes are stored within an array called `data` in the class:

```php
class Demo
{
    private $data = array();

    public function __set($variable, $value)
    {
        echo 'Setting '.$variable.' to '.$value;
        $this->data[$variable] = $value;
    }

    public function __get($variable)
    {
        if (isset($this->data[$variable])) {
            return $this->data[$variable];
        } else {
            die('Unknown variable.');
        }
    }
}

$d = new Demo();
// Set a non-existent variable
$d->test = 'Test Variable';
// Get what we just stored
echo $d->test;
// Get a non-existant variable
echo $d->testFail;
```

Overloading will not overload on a variable that already exists. So for example
if we had a variable defined called `$test`, our code before would use that
variable instead of storing in the `$data` array. Also, if you try to use a set
or get on a variable that you don't have access to, ie: accessing a private
variable outside the object, it will call the overloading methods.

### Call and callStatic

These two do the same thing, except that one is for static methods, and the
other not. You can use these to call special functions that don't actually exist
in the class, for example we could use a class to set or get instead of using
the earlier methods:

```php
class Demo
{
    private $data = array();

    public function __call($name, $arguments)
    {
        switch (substr($name, 0, 3)) {
            case 'get':
                if (isset($this->data[substr($name, 3)])) {
                    return $this->data[substr($name, 3)];
                } else {
                    die('Unknown variable.');
                }
            break;
            case 'set':
                $this->data[substr($name, 3)] = $arguments[0];

                return $this;
            break;
            default:
                die('Unknown method.');
        }
    }
}

$d = new Demo();
// Set a non-existent variable
$d->settest('Test Variable');
// Get what we just stored
echo $d->gettest();
// Get a non-existant variable
echo $d->gettestFail();
```

The logic is exactly the same for `__callStatic()`. One thing to note is that I
have included the line `return $this;` within the `set` case, this will mean
that you can chain your sets:

```php
$d->settest('test')->settest2('test2')->settest3('test3');
```

## Singletons

A singleton class is a class that should only be instantiated once and never
instantiated again, for example if you had a class for database interfacing you
would only want that instantiated once. This is normally achieved by having a
static variable within the class sometimes named `instance`, and a static method
called `getInstance` \- this will check if and instance exists, if it doesn't,
it will create one, then return the instance:

```php
class DemoSingleton {
    private static $instance = NULL;

    public static function getInstance(){
        if(is_null(self::$instance)){
            self::$instance = new self();
        }
        return self::$instance;
    }
}

$class = DemoSingleton::getInstance();
```

## Autoloading

Autoloading is very nifty, and is used in a lot of large frameworks - it allows
you to load the file that a class is written in automatically when you try to
instantiate it. The advantage of this is that only classes that you want to
instantiate & use will be included in your page and will keep memory usage
down.

The best way to autoload a class is to use a global function called
`spl_autoload_register()`, there are two ways to use it - my favourite is using
an anonymous function, but this is only possible in PHP 5.3.0+. The other way is
a named function, both below do the same thing:

```php
// Using a named function
function autoload_class($class){
    include_once('includes/' . $class . '.class.php');
}
spl_autoload_register('autoload_class');

// Using an anonymous function
spl_autoload_register(function($class){
    include_once('includes/' . $class . '.class.php')
});
```

These will both look in a directory called _includes_ for a file with the same
name of the class you're trying to instantiate. So trying to instantiate a class
called `Person` would look to include a file called `Person.class.php`.

## Final Thoughts

Object oriented programming is an amazing feature and is definitely something
that you should use, whether exploiting extensions and magic methods or not. OO
can go so much further than what I have explained here, such as the use of
Factories and abstract functions - which I've only ever had the need to use
once. For further reading take a browse through the [PHP Classes & Objects
Manual][1].

[1]: http://www.php.net/manual/en/language.oop5.php