Daily Archives: April 8, 2006

Lazy wrapping with PHP5’s __call method

The overloading features in PHP5 allow you to intercept calls to unknown methods at runtime. I recently used this feature to rapidly develop a class wrapper for Xapian, and it’s interesting to see how the technique works and what it achieves.

In this article, I’ll explain how you can use __call to wrap a flat function-based PHP5 library into a set of classes with minimal effort. I’ll use Xapian as an example – it has a SWIG generated binding which flattens the library’s C++ class interface into a set of functions.

Using a wrapper we can turn code like this…

$enquire = new_Enquire($database);
Enquire_set_query($enquire, $query);
$matches = Enquire_get_mset($enquire, 0, 10);

…into code like this…

$enquire = new XapianEnquire($database)
$enquire->set_query($query);
$matches = $enquire->get_mset(0, 10);

This allows you to use the library in a similar way to others using different languages, aiding communication, but also allows you to realise all the usual benefits of OO software design, such as deriving from these classes to provide specialised functionality.

So far so good, but wait until you see how lightweight the implemention of that XapianEnquire wrapper class is…

class XapianEnquire extends XapianWrapper { }

That’s not a typo. That’s all you need. Instantiate one of those and you can call all the methods you would expect from the Xapian documentation. Try and call a method which doesn’t exist and it will throw an exception.

Voodoo, surely?
Continue reading