Saturday, January 24, 2009

QueryPath: It's like jQuery PHP.

I have just posted "my winter project." Its name is QueryPath, and it's something like jQuery PHP (or is that PHP jQuery?).

While writing the Drupal 6, JavaScript, and jQuery book, I started looking for something like jQuery in the PHP world. I found several projects that implemented small subsets of the jQuery API, but nothing approaching the complexity I had in mind.

So I went back a step, and started looking for a good CSS 3 Selector implementation. I didn't find one of those, either. At best, I found some simple regex-style tools that supported a small portion of the CSS 3 Selector standard.

There was nothing else to do but start coding.

First I wrote a recursive descent parser for CSS 3, including support for XML namespaces and other ill-defined yuckiness.

Then I wrote an event-based API similar to SAX2 -- only for CSS 3 Selectors. And I wrote an implementation of the API.

From there, I began constructing a PHP equivalent of jQuery. Not all of the jQuery API is relevant in PHP. After all, an event model glue layer is not of general interest in a single-threaded PHP app. But HTML/XML traversing and manipulating certainly are. So I borrowed as much of the jQuery API as seemed appropriate.

While I used the same function names (except for empty, which is a PHP reserved word), and tried to follow as closely as possible in parameters and return values, the internals are almost completely different. Why not? After all, JavaScript and PHP are very different languages.

The coding process was interesting. I'm too busy to write something like this in one go. So I spread it out... in 15-30 minute increments. In fact, I developed most of QueryPath while riding Chicagoland trains to and from work. Even with this bizarre and disjointed development path, I eventually finished. QueryPath's main library has 58 public methods, almost all of which are from jQuery's API (though I added some, like an XPath query and tools to use PHP delta and callback functions).

But I wasn't happy. I wanted some cool extensions (plugins), too. It didn't take me long to figure out the obvious: QueryPath needed a database layer. Using PHP's PDO library, I constructed a simple database library, QPDB, that allowed various ways of merging SQL results into XML/HTML. Take a query and turn it into a table or a list. Or get get more detailed -- you can put database results (in whole or in part) wherever you want! There's even a simple template language (I like to call it HTML) that you can use to format results in sophisticated ways.

I am so happy with the library that I have released it under LGPL or MIT License (your choice). You can head over to (or skip straight to the downloads and docs at to try it out for yourself.)

N.B. A huge thanks to the Fedora Hosted folks for (a) inviting me to host there, (b) providing an unbelievable array of VCS and bug tracking tools, and (c) being more than congenial all along.