Category Archives: PHP

Why PSR-0 may be one of the most significant things to happen to PHP ever

Reposted from old site – original date: Friday 17 February 2012

What is PSR-0?

Very basically, PSR-0 is a recently defined standard for autoloading classes in PHP-5.3.x and above.
If you would like to have a much closer look, a copy of the final document can be found at https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md

I am not going to spend much time on explaining the document or autoloading in general, as that is an exercise best left to the reader, but as a quick introduction to those that have never worked with this kind of thing before, I will explain the very basics and leave it at that.

Basically, in the old days, you would have a class with name, say, User.php to do something with users. Great. Now to use that code you needed to go through certain steps in order to include() it and then instantiate and use it, like so:

require “User.php”;
$user = new User(“Paul”);

So far, so good, right? Right! OK, so skip forward a few years and suddenly we see that there is a magic function called __autoload() in PHP5. Awesome! Let’s look at how that works then:

public function __autoload($className) {
$filename = $className . “.php”;
if (is_readable($filename)) {
require $filename;
}
}

OK, nice. Now we can load up files with a specific file naming structure with relative ease. One very big drawback here is that you could only ever register a single autoloader, which, in many cases was OK, but not the best situation. Skip forward to PHP-5.1.x and we see spl_autoload() being introduced. What this allowed was multiple autoloaders with the spl_autoload_register() function. Cool, now we could have a function to autoload the different components of our frameworks (such as controllers, views and models) with slightly different autoload functions, which tends to increase the security slightly as well as making tracking down bugs a lot easier.

This was all great stuff, and made our lives as large project developers much easier, but we soon started to see some cracks in the glossy sheen of autoloading. What people started to notice very quickly is that everyone was doing it their way. Look at a few examples of class names from projects that I have worked on:

1. Chisimba – user_class_inc.php
2. PEAR – PEAR_User which translates to PEAR/User.php
3. Zend – Zend_Cache which translates to Zend/Cache.php
4. etc. (see class.name.php, class_name.php, class.name.inc.php, classname.inc.php, etc…)

This is part of the reason that PSR-0 was conceived; to try and standardise some of this mess.

What PSR-0 tries to do is to make sure that all classes and reusable objects are kept as such, reusable, across many different frameworks and codebases with minimal effort. These standards are also exploring other aspects of large project codebases such as cache interfaces as well, but those are still in active discussion.

By now, I guess you have read through the PSR-0 standard document as above. Let us take a look at it quickly.

Basically, the way that it all works is that you have to stick to a certain naming convention. That naming convention should implement a certain directory and code file layout according to a fully qualified namespace in your code. PSR-0 compliant autoloaders will then automagically be able to find the files by traversing the directory structure and include them for use in your code. Magic! An example can be found at https://gist.github.com/221634 with a SplClassLoader implementation that sticks to the standard.

In my own project(s), I have adopted the Symfony autoloader component though. You can find a bunch of information, as well as a guide and download link at http://symfony.com/doc/2.0/components/class_loader.html Please go and take a look there for additional information.

So why is this significant?

The actual subject of this post is the significance of PSR-0. Now that we have a pretty good idea of how it works, we can now start thinking of the possibilities associated with it!

Imagine starting a new project which requires a forum, a wiki and a file upload area. OK, not a huge ask, but will take time. These are also not uncommen web applications, so there will be a lot of reusable code lying around in other projects that we can use, but each class may need to be manually edited to work with the overall project, and many other finicky little subtleties may need to be addressed, which could end up taking as long as if you were to have coded everything almost from scratch. Not good.

If, however, we used a bunch of high quality components from any number of fine projects and frameworks out there already, we could simply start adding some, or all, of these components to our own project and simply writing a bit of glue code to hold them all together, which would significantly reduce the dev time on any project. Bug tracking and fixing becomes easier due to the use of namespacing and the overall velocity of the project increases. All good things.

The more projects and people that stick to these standards, (as they become available) the better. The more simple, reusable components that are created and made available via systems like packagist http://packagist.org/ the better. Many projects can now make use of these components by simply adding a line of JSON or two to a file and using a package manager like Composer (http://getcomposer.org/composer.phar) to work with them! Side note: If you do use Composer, it will automatically generate an autoload.php file for you, making this even easier!

As a final note, from a performance perspective, we all (should) know that require() and include() etc are pretty heavy operations, but by using SPL, we should even get a bit of a bonus performance boost (on top of the performance boost you get from using PHP-5.3.x and above anyway), as well as making your code more readable and maintainable. What reason could you have for not using it? :)

In conclusion, PSR-0 autoloading is the first of many standards. If you would like to participate in creating these standards, the working group is an open one and your feedback is welcomed.

The fact that these things are being collaboratively created makes for a very exciting time to be a PHP developer! This is one of the most significant things to happen to PHP since PHP5!

Keep an eye out and most importantly, have fun!

Laptop tracking system (cheap)

Reposted from old site – original date: Wednesday 7 September 2011

Following on from a discussion on a work forum, I decided to have a stab at writing a super simple laptop tracking system. The main aim of the system will be to track stolen laptops and (hopefully) recover them somehow.

After a little bit of consideration, I decided to have a look at doing this in a client/server way with a MongoDB back end. The following is a simple, but workable system that uses the python bindings to the DBUS messaging system on Linux (tested on Ubuntu 11.04), so I am doubtful that this could be used for anything other than that. That being said, however, the client bit simply needs to send through wifi access points and MAC addresses to get a triangulation on the position of the laptop, so I am pretty sure that this can be achieved with relative ease on other platforms.

Triangulation is done via a Google API and the coordinates as well as the accuracy level is then inserted to the MongoDB back end for mapping or whatever else needs to be done with the data. Features that the client should also probably support include bricking the machine remotely or something to that effect, as well as possibly sending messages or SOS tweets or something to let people know that it is not in its rightful owners posession.

Enough rambling! To the code!

Client:

As I said, the code uses python-dbus and the standard json and urllib modules. You can install python-dbus with an apt-get install python-dbus.

import dbus
import json
import urllib

NM = 'org.freedesktop.NetworkManager'
NMP = '/org/freedesktop/NetworkManager'
NMI = NM + '.Device'
PI = 'org.freedesktop.DBus.Properties'

def list_ssids(): 
    bus = dbus.SystemBus()
    nm = bus.get_object(NM,NMP)
    nmi = dbus.Interface(nm,NM)
    # Iterate over the devices queried via the interface
    for dev in nmi.GetDevices():
        # get each and bind a property interface to it
        devo = bus.get_object(NM,dev)
        devpi = dbus.Interface(devo,PI)
        if devpi.Get(NM+'.Device','DeviceType') == 2:
            wdevi = dbus.Interface(devo,NMI + '.Wireless')
            wifi = []
            for ap in wdevi.GetAccessPoints():
                apo = bus.get_object(NM,ap)
                api = dbus.Interface(apo,PI)
                wifi.append({'ssid':''.join(["%c" % b for b in api.Get("org.freedesktop.NetworkManager.AccessPoint", "Ssid", byte_arrays=True)]), 'mac':''.join(["%c" % b for b in api.Get("org.freedesktop.NetworkManager.AccessPoint", "HwAddress", byte_arrays=True)])})
                
    return wifi

if __name__ == '__main__':
  ap = list_ssids()
  data = json.dumps(ap)
  params = urllib.urlencode({'wifi': data})
  f = urllib.urlopen("http://127.0.0.1/junk/geo/geopost2.php", params)

You will need to modify the post URL at the end to somewhere meaningful for yourself of course.

Initially, I did the client using the PHP ext/dbus, but decided against that due to the fact that it is hard to install and nobody really uses it…

The server side is just as simple. You will need a Mongodb instance running on the server and then you need a simple script to catch the POSTs. NOTE: This script is just a concept, so if you are actually going to do something like this, clean it up!

<?php
$wifi = $_POST['wifi'];
$wifi = json_decode($wifi);
$request = array( 'version' => '1.1.0', 'host' => 'myurl.com', 'wifi_towers' => $wifi );
$c = curl_init();
curl_setopt( $c, CURLOPT_URL, 'https://www.google.com/loc/json' );
curl_setopt( $c, CURLOPT_POST, 1 );
curl_setopt( $c, CURLOPT_POSTFIELDS, json_encode( $request ) );
curl_setopt( $c, CURLOPT_RETURNTRANSFER, true );
$result = json_decode( curl_exec( $c ) )->location;

$fields = array(
            'lat'=>urlencode($result->latitude),
            'lon'=>urlencode($result->longitude),
            'accuracy'=>urlencode($result->accuracy),
            'laptopid' => urlencode('16cptl-pscott'),
            'wifi'=>urlencode(json_encode($wifi)),
        );


// connect
$m = new Mongo();
// select a database
$db = $m->laptoptrack;
$collection = $db->lappoints;

// add a record
$obj = array( "loc" => array("lon" => floatval($fields['lon']), "lat" => floatval($fields['lat'])), "lon" => floatval($fields['lon']), "lat" => floatval($fields['lat']), "accuracy" => intval($fields['accuracy']), "laptopid" => $fields['laptopid'], "wifi" => json_encode($wifi));
$collection->ensureIndex(array('loc' => "2d"));
$collection->insert($obj, array('safe'=>true)); 

So from the above code, you will see that we create a 2d geospatial index on the Mongodb instance as well. Not sure if this is useful, but it will probably help in speeding up queries like “Gimme all the laptops that Company X owns in area Y” or something – if that is something that you would like to add to your query interface of course…

Also, I am not 100% sure of the legality of storing SSID’s with a location, so check that one first too!

Dead simple, works well.

I would say that the client bit should be on a cron job or something that pings the service every hour or something.

Remember: Mongodb works best on 64bit OS. If you are using a 32bit arch, then you will only be able to store around 2GB data at a time. Depending on the need for historical records etc, keep that in mind…

Most importantly, HAVE FUN!

PHP GD and Ubuntu

Reposted from old site – original date: Saturday 18 December 2010

It seems that the maintainers over at Ubuntu regard the PHP5 bundled GD version a fork of Boutells GD library (I understand why) and that forks = security risks (again, the logic is there). However, I am working on an application that requires a higher level of GD functions than the “older” GD library provides, chief amongst them the imageantialias() function (amongst others).

The only recourse was to recompile PHP, build a php5-gd package from that and then replace the current php5-gd deb with the new one. Luckily if you link against the standard system GD library (not the PHP shared lib) you get the full deal!

Sounds simple enough, and so it is! Here are the steps required:

1. Completely remove your old php5-gd with an:

apt-get remove --purge php5-gd

2. You then need a fakeroot and build environment (if you don’t already have one) so install that with the following:

# Install build tools, debian helpers and fakeroot
    apt-get install build-essential debhelper fakeroot
    # source code should reside in /usr/src
    cd /usr/src
    # Download PHP source
    apt-get source php5
    # Install all packages required to build PHP5
    apt-get build-dep php5
    cd php5-5.3.2

3. Next up we have to modify the debian rules as to how the package is compiled. All that you need to do here is to open up the debian/rules file in your favourite text editor and find the line that looks like:

--with-gd=shared,/usr --enable-gd-native-ttf 

and replace it with:

--with-gd=shared --enable-gd-native-ttf 

4. You can then go ahead and rebuild the deb with the following:

# build the php5-* packages
    dpkg-buildpackage -rfakeroot
    cd ..
    # Install the new php5-gd package
    dpkg -i php5-gd_5.3.2-1ubuntu4.5_i386.deb 

5. Restart apache with

/etc/init.d/apache2 force-reload

and you should be smiling!

That’s it. Told you it would be simple!

HOWTO get the Yaz libraries up and running in your PHP5 installation

Reposted from old site – original date: Friday 6 August 2010
YAZ is a programmers toolkit supporting the development of Z39.50/SRW/SRU clients and servers. Z39.50-2003 (version 3) as well as SRW/SRU version 1.1 are supported in both the client and server roles.

The current version of YAZ includes support for the industry standard ZOOM API for Z39.50. This API vastly simplifies the process of writing new clients using YAZ, and it reduces your dependency on any single toolkit.

The PECL extension is described as:

PHP/YAZ is an extension to the popular web server language PHP that implements Z39.50 origin (client) functionality as well as the SRW/SRU protocols.

The following Z39.50 services are supported by this extension: init, search, present, scan and sort. The extension can handle GRS-1, MARC, SUTRS and XML. The module also allows you to convert MARC in ISO2709 to MARCXML on the client side.

The PHP/YAZ extension is part of PHP 4.0.1 and later but has now been moved to PECL. As a PECL module, PHP/YAZ is now independent of PHP versions. It works with both PHP 4 and PHP 5.

You need to install the YAZ dev libraries as well to get the headers so that the PECL extension can build against them. So now we install the lot with:

aptitude install libyaz3 libyaz3-dev yaz-doc
pecl install yaz

Once the YAZ extension is built properly, you must then remember to add your new extension to the php.ini file so that PHP knows about it. I am using Apache, so I add it to the apache2/php.ini file.

extension=yaz.so

Restart/Reload Apache and then check for the new extension with

 
php -i | grep yaz

on the commandline, or use a regular phpinfo() call within a PHP script. Remember that if you use the commandline only, you will also need to add the yaz extension line to your cli.ini file!

With that, you should be up and running with YAZ in PHP5

HipHop the PHP Compiler for/from Facebook

Reposted from old site – original date: Wednesday 3 February 2010

So I have seen literally thousands of tweets about HipHop from many many (reputable) sources and it seems that they are mostly wrong, FUD or oversimplified.

The next few lines will dispell those myths and will make you understand what it is, and if it is good for you or not.

First, some background:

HipHop is a C++ compiler. It converts PHP code into C++ and compiles that into a binary using GCC. This is where you get the speed increase (Facebook now claim 50%), which makes perfect sense.

OK great, sounds wonderful, lets grab the source code and deploy like mad! Err, no, lets not, and here is why not:

1. HipHop works on a certain custom set of extensions only

2. HipHop doesn’t work with PHP-5.3.x (yet)

3. It works with a very limited set of functions and extensions, all of which require maintenance, yes, by you!

4. If you make a change, you need to rebuild and recompile. This is OK if you do that once every now and then, but remember how long it takes to recompile C++? Yeah, a loooooong time. That means that for your smaller project(s) this is completely useless and lets face it, most PHP projects are not huge (except the huge ones like the frameworks and Yahoo! and Facebook)

5. If you are runnin your PHP from Windows, you are out of luck (twice IMO, but that is another post).

6. If you use eval() see point 5 above. (Thank goodness IMO)

So, if you are willing to put up with all of the above, it is a great product (in theory). Some larger frameworks could benefit from using it, but I doubt they will. The divergence between “native” PHP and it’s own evolution and the HipHop’ified PHP will get bigger and bigger until there is a fork and well, you have to choose.

In summary, you are going to run faster, much faster and use less resources (besides compile time), but there is quite a big tradeoff. Be wary of that!

There are other points, of course, but I will leave that for someone else for now. (Think, hmm, PHP is C, this is C++…)

CHISIMBA_(portrait)_250x170

Chisimba event based messaging framework

As of January 2009, I have now committed the code to the core classes of Chisimba that
enables an event based messaging framework. This is useful in many ways,
so use it with innovation in mind… :)

The framework creates an observer pattern that can be used pretty
globally. I have added an example to the phpinfo module for a test. It
is really an arbitrary example, but I think it should give you all a
rough idea on how it works. The following example is the same code in
case you miss it, but annotated with many more comments:

The first thing that you need to do is in your init() function (or
wherever else I suppose) you need to create the observer. I have left
this pretty open so that it is super flexible:

$this->eventDispatcher->addObserver ( array ($this, 'modaccess' ) );
$this->eventDispatcher

is a property from the core, so that will always
be the case. You are calling the addObserver() function, which sets up a
callback function that you specify in an array. This particular example
is calling a callback in the same class, but you can specify any module
you like (such as a class that logs to the db or something for site wide
notes about current activity?). The function that I am calling is called
modaccess, which is defined as:

public function modaccess($notification) {
    if ($notification->getNotificationName () == 'test') {
       log_debug("PHPInfo module was accessed");
    }
}

The events system creates a referenced $notification object that is
passed through Chisimba to your module and then callback, so that will
always be the argument. There are a couple of properties in
$notification that you can use such as:

getNotificationName() - gets the name of the notifier
getNotificationObject() - get the name of the object that sent the note
getNotificationInfo() - any info that you have added
getNotificationCount() - a count
isNotificationCancelled() - well, is it?

There are some others, but I will doc them properly soon and let you
know.

The function then simply logs the notification to the error_log, but
this could fire off almost anything (db insert, xmpp message, forum
post, etc etc)

The only thing left is to actually post a notification to our messaging
system now, which is done like so:

this->eventDispatcher-post($this, "test");

This then sets the notification name and posts away. This could be done
in any function or in any action as well. as an example…

Any questions, please don’t hesitate to ask!