Welcome to my site

Post statistics

Magically dynamic PHP

These two functions are designed to replace the setXyz() and getXyz() calls for each and every variable which could possibly be changed. It also simplifies the programming logic and allows us to perform some pretty neat tricks. So without further ado, let’s jump into an example.

A simple example

To take full advantage of these two functions, you need data whose name will not change but their value can. The first thing that springs to mind is license plates. Here in the UK we have unique license plate numbers which belongs to a car; license plates can be moved from car-to-car… sorry about the boring subject, fluffy cats and dogs would have much more fun.

<?php
class LicensePlate
{
    private $plate = array('ABC123' => 'Ford Focus');
 
    public function __set($plate, $car)
    {
        $this -> plate[$plate] = $car;
    }
 
    public function __get($plate)
    {
        return $this -> plate[$plate];
    }
}

So what is going on here? Well, we have the plate array which will be the repositary for any license plates we create, the __set function to set them, and the __get function to, well, get them. Not hard really. Now, we need to write the code to access this class, and it couldn’t be simpler.

<?php
$plates = new LicensePlate();
$plates -> ABC123 = 'Mini Cooper';
echo($plates -> ABC123);

Line 3 is the first magic method, and as you can see, we refer directly to the array index of the license plate ‘ABC123’. Since there is nothing in the class such as a function called ‘ABC123’, and since we are setting a value, the __set() function kicks into action. The function accepts 2 parameters, the actual licence plate (in this case ‘ABC123’, and the value, in this case ‘Mini Cooper’. The setter then simply writes these details to the class array. Line 4 uses the same technique except that it is not trying to set anything; rather it is trying to output something. PHP knows this, and so fires up the __get() function. This function only accepts one parameter, the license plate. The function simply returns the value of that license plate, ‘Mini Cooper’.

This example is extremely basic and contains lots of holes. For instance, what if the array index of ‘ABC123’ doesn’t exist? The next script shows a fully working script which has a logger to show you what is going on under the hood.

<?php
class LicensePlate
{
    private $log = array();
    private $plate = array();
 
    public function addPlate($plate, $car)
    {
        if (array_key_exists($plate, $this -> plate))
            $this -> plate[$plate] = $car;
            $this -> setLogItem('Added ' . $plate . ' as a ' . $car);
        }
        else
        {
            $this -> setLogItem('The plate ' . $plate . ' already exists.');
        }
    }
 
    public function __set($plate, $car)
    {
        if (array_key_exists($plate, $this -> plate))
        {
            $this -> plate[$plate] = $car;
            $this -> setLogItem('Changed ' . $plate . '\'s car to ' . $car);
        }
        else
        {
            $this -> setLogItem('Could not set the car for ' . $plate);
        }
    }
 
    public function __get($plate)
    {
        if (array_key_exists($plate, $this -> plate))
        {
            $this -> setLogItem('Returned ' . $plate . '\'s car');
            return $this -> plate[$plate];
        }
        else
        {
            $this -> setLogItem('Could not return the car for ' . $plate);
        }
    }
 
    private function setLogItem($item)
    {
        $this -> log[] = $item;
    }
 
    public function getLog()
    {
        return print_r($this -> log);
    }
}
 
$plates = new LicensePlate();                // Create the instance
$plates -> addPlate('ABC123', 'Ford Focus'); // Create ABC123
$plates -> ABC123 = 'Mini Cooper';           // Amend ABC123
$foo = $plates -> ABC123;                    // Get ABC123's car
$plates -> XYZ789 = 'Land Rover';            // Should produce an error
 
$plates -> getLog();                         // Let's see what we did

Whilst running this code (why not give it a try?) should produce the following:

Array
(
    [0] => Added ABC123 as a Ford Focus
    [1] => Changed ABC123's car to Mini Cooper
    [2] => Returned ABC123's car
    [3] => Could not set the car for XYZ789
)

Advantages

No one likes creating loads and loads of getters and setters—they make the script bigger and harder to navigate whilst all providing the same functionality. These two functions dispose of all those functions and allow for streamlined applications. But what happens when an attribute of a class needs special attention? Well you can create a unique getter and setter for that sole attribute.

They really start to shine though when dealing with data which is constant and require only a set amount of variables. One such case is a database table. A database table only accepts a strict set of fields; creating the __get() and __set() functionality in a higher class would save a lot of hassle.

Date posted June 11th, 2007
Comments Disabled
Categories PHP
Author Christopher Hill

I'm Christopher. A twenty-something graduate, star gazer, aspiring triathlete, vegetarian, reader and writer, cinemaniac and lover of life in general

From the journal

From the deep

Obligatory links

Create simple UML diagrams on-the-fly

yUML is an online tool for creating and publishing simple UML diagrams. It’s makes it really easy for you to: Embed UML diagrams in blogs, emails and wikis, Post UML diagrams in forums and blog comments, Use directly within your web based bug tracking tool and Copy and paste UML diagrams into MS Word documents and Powerpoint presentations.

Javascript Tidy

One thing I often need to do is to tidy javascript from it’s packed state. Often to fix the developers bugs, add new features or to modify it slightly. I give you, the Javascript Tidy, a tool I couldn’t live without.

jQuery Slider plugin (Safari style)

A pretty awesome slider. Haven’t tried it out yet but the new version seems pretty easy to skin, so you can style it however-the-hell you want (note: click the ‘jQuery Slider update’ link).

MySQL Format Date

MySQL Format Date helps you format your dates using the MySQL DATE_FORMAT function. Just select a common date format and then change it to your suit your needs. The MySQL DATE_FORMAT code will be generated at the bottom of the page which you can then copy into your query.

The future of wireframes?

I have a love hate relationship with wireframes. In the last 10 years they’ve been a part of every web project I’ve worked on. There have been times when I can’t imagine how we would have solved a particular problem without them. Yet there are also times when I’ve been completely exasperated at the amount of time and energy they’ve consumed, seemingly to very little reward.

So you need a typeface?

A pretty humorous look into how you could choose your typeface for your next project.

New global visual language for BBC

We decided to embark on an ambitious project, called Global Visual Language 2.0, with the aim of unifying the visual and interaction design of bbc.co.uk and the mobile website.

jQuery plugin: Nivo Slider

A really cool image slider than has some unique transitional effects without using Flash.

MooTools plugin: DatePicker

jQuery has the best functioning plugins. MooTools has the best looking plugins. Whenever I want to add in a datepicker I always find this and think: “Oooh. Pretty. Do want.”. Then realise it’s MooTools only. Real shame.

jQuery plugin: Sparklines

I know, I know. This plugin has been around for, what seems like, years. But I thought I would give it a little bit of a spotlight. And yes, so I can easily find it again.

jQuery plugin: asmSelect

asmSelect is a jQuery plugin providing progressive enhancement to select multiple form elements. It provides a simpler alternative with several advantages. This new version includes several bug fixes and enhancements.

How coupon codes can lead to lost revenue

In this post we’ll be looking at how coupon codes (used synonymously here with promo and discount codes) can cause retailers to lose revenue. I’ll share some (hopefully) interesting trends that I’m seeing with a client I work with, and hopefully start a discussion with how to turn lost revenue into gained revenue.

A good browser should be able to reproduce itself

This is an interesting project which aimes to completely reproduce the visual aspect of Safari in pure HTML+CSS with zero images. There are a few caveats at the moment, such as no refresh button, but they say they are working on it. Once again this really shows the power that HTML5 and CSS3 brings to the Web.

jQuery plugin: gameQuery

gameQuery is a jQuery plug-in to help make javascript game development easier by adding some simple game-related classes. It’s still in an early stage of development and may change a lot in future versions.

CSS/Javascript Word Clock

A lit­tle ex­per­i­ment I built: a word clock using CSS3 trans­forms and a lit­tle Javascript to run the ac­tu­al clock. Use­ful? Maybe not. Fun? Def­i­nite­ly.

CSS Border Radius Web Page

It’s one of those things that makes you think “Doh! I should have made that agaes ago”. A simple Web page that allows you to simply get the CSS for the exact border radius you want.

The main thing is not to install Flash

A security expert who has won the Pwn2Own contest for 2 years running said, basically, that Flash is insecure. Well, we all knew that which is why we add Flashblock and the like. Right?

Pure CSS3 Bokeh effect

One of the best apps made using CSS3, that’s for sure. A few more options would be nice, such as changing colours of the circles and being able to place them manually.

EZ-CSS: An easy to use, lightweight, CSS framework

It is light (1kb), flexible, browser-friendly and easy to use! ez-css is a different kind of CSS framework. Authors are not bound to a “grid”. Plus, columns and gutters can be of any width.

jQuery plugin: Quicksand

I love Mac apps, especially for their attention to detail. CoreAnimation makes it so easy to create useful and eye-pleasing effects. Quicksand aims at providing a similar experience for users on the web.