echo "hey, it works" > /dev/null

just enough to be dangerous

Quality PHP: Laura Thomson


PHP quality background.

Laura is the co-author of the hugely successful PHP and MySQL Web Development, and a Senior Software Engineer at Mozilla Corporation. Thanks for being the first respondent, Laura.

In terms of PHP, what does quality mean to you?
This is a great question, and one I often ask in interviews. Quality PHP is free of the usual set of code smells. It's been through code review and has a set of meaningful tests with a reasonable level of code coverage. It has minimal but sufficient documentation. You can detect good quality PHP by looking for:
  • happy developers
  • new developers becoming productive quickly
  • other users forking or contributing to your projects
  • your application being robust and not failing in odd and intermittent ways
  • devs are able to modify the code and add features quickly, without forensic spelunking to understand how it works
  • your code lacking that fragile library that nobody wants to maintain or modify in case they break it
What tools and processes do you use in your development to ensure quality?
The main things we do are:
  • Patch review. (This is common among open source projects.) Writing code that you know will be read by others ups the quality in general.
  • Security review for new projects or features.
  • Continuous integration and automated test-on-build.
  • Mozilla's awesome WebQA team run a set of automated tests using Selenium, fuzzers, and also do a lot of manual testing.
Are there tools or processes that you'd like to include in your toolbox that you haven't used yet?
We're looking at moving towards continuous deployment during the next few months and are currently exploring the requirements for that.

Quality PHP


The great thing about PHP is that it lets people put together web sites easily and quickly. Along with the vibrant community, it's one of the main reasons for the language's popularity. A side effect of this ease of production is that PHP hasn't developed a culture of quality, in the business sense.

What do I mean by quality? That software does what it's supposed to do, reliably and repeatably. It's maintainable and it's not fragile, so isn't prone to breaking when changes are made. Despite the lack of a culture of quality, some of the biggest web sites on the Web use PHP, and internally they must have processes to ensure quality.

I'd love the quality tools and processes to become more widely used in PHP, and so I've asked three questions of a bunch of Important People in the PHP community, people I respect and admire. In terms of PHP, what does quality mean to you? What tools and processes do you use in your development to ensure quality? Are there tools or processes that you'd like to include in your toolbox that you haven't used yet?

I'll post responses as I get them.

Laura Thomson

If you have a suggestion of someone I should ask, please let me know; identica, twitter, email

Logging Lithium queries


A nice tip from Nate yesterday on #li3 IRC. If you want to know the actual queries that Lithium issues, you can use a filter to dump them.

Connections::get("default")->applyFilter(
  "_execute",
  function($self, $params, $chain) {
    var_dump($params['sql']);
    return $chain->next($self, $params, $chain);
  }
);

Things I learnt today


First, some PHP stuff.

The e modifier of the preg_replace() function escapes things. It can be round tripped, but it seems silly that you have to do so manually.

It's possible to call a method using preg_regex_callback(), which does not escape things, but you have to pass it array('objectname','methodname').

And, other stuff.

I like Blonde Redhead, Quite Village, and Santogold. Thanks to @turtlepark for the recommendation, and Chris Dahl for seconding.

Lastly, I get grumpy when I haven't had enough sleep.

Anonymous functions


I've been working on Habari a bit recently, so have been writing more PHP than Ruby lately. Given that Habari's code quality is pretty good, that hasn't been too terrible. However, I recently had to prepend a URL to a bunch of file paths, and was thinking in Ruby, where I would have done something like this:

url = "http://twofishcreative.com/"
resources = %w[one two three]
resources.map! { |resource| url + resource }
puts resources

The beauty of this is that it keeps the callback code with the calling code, making it easier to read. PHP doesn't have blocks, but it does have the create_function() function, which lets you create an anonymous function, so you can have your callback inline too.

$url = "http://twofishcreative.com/";
$resources = array("one", "two", "three");
array_walk($resources, 
  create_function('&$resource,$k,$url',
    '$resource = $url.$resource;'), $url);
print_r($resources);

Ouch! That quoted function! Deity forbid you actually want to do anything complex in there. And you get a completely new scope, so you have to pass in any variables you need. And if you want to use more than one variable you need to do some horrible kludge like passing an array of variables.

I'll leave it as an exercise for the reader to work out which I prefer.

PHP's errors


PHP's errors have always struck me as being particularly impenetrable. There doesn't seem to be any explanation of the errors on the PHP site either. What the hell does Parse error: syntax error, unexpected ';', expecting T_FUNCTION in blah.php on line 145 mean? Well, the most likely explanation for that error is that you forgot the close brace on a class, so you have a function close brace immediately followed by ?>.

Alternative PHP syntax for control structures, take 2


I previously dismissed PHP's alternative syntax for control structures, but after spending some time working on themes for WordPress and Habari, I've come to realise that it's actually very useful from a readability point of view. The point is that if you have a mix of code and HTML, as themes do, then it can be very difficult to work out what control structure that lone dangling close brace is actually closing. By spelling it out with a endif, endwhile or endforeach the code is made just a little bit clearer.

So, for templating, okay, I'll accept it. For other code, it's still at terrible idea.

Alternative PHP syntax for control structures


Reading through the WordPress source, I found some syntax I didn't recognize.

if ( !function_exists('wp_set_current_user') ) :
function wp_set_current_user($id, $name = '') {
  global $current_user;
  if ( isset($current_user) && ($id == $current_user->ID) )
    return $current_user;
  $current_user = new WP_User($id, $name);
  return $current_user;
}
endif;

A hunt revealed that this was an example of PHP's alternative syntax for control structures. You can replace an opening brace with a colon on some control structures, the closing brace with an end*;, where * is the control structure, and have blocks of multiple lines. Why would one use this? One example in the WordPress is a conditional function definition, which, okay, that's unusual, so maybe the unusual syntax makes it stand out, but in general I think using this is a terrible idea.

PHP as a CGI


In a previous post I talked about getting HTTP authentication working when PHP is intalled as a CGI. That, however, begged the question; why install PHP as a CGI? Performance is going to take a substantial hit, after all. The answer I got from the sys admin of one of the servers I was trying was:

- Better security
If a PHP process is compromised, it's only compromised for the duration of the request.

- Upgrades are easier
Upgrading an Apache module requires restarting the Apache server after the module has been replaced. Upgrading a CGI binary simply requires replacing the binary.

Sounds reasonable for low traffic sites. The other server is a run by a hosting company, so low traffic isn't really something on which they can or should rely.

AtomPub and WordPress


So, WordPress 2.3 beta adds support for AtomPub. All good. I installed it (separately to this blog, I'm just playing around), but all I could get out of the APE was a 401, even though I'd provided the correct authentication credentials. Looking at the code, with liberal use of the logging therein, I worked out that PHP_AUTH_* weren't being set, so I pulled out some auth code and tried it on it's own. No luck. Weird. I then grabbed a previously working snippet and tried that, but it was broken too. On both the servers to which I have easy access. I sent the snippet to Donal, and the snippet worked for him. WTF?

Turns out, that both the servers I was testing on are running PHP as a CGI, not using mod_php, and if PHP is being run as a CGI PHP_AUTH_* aren't available. Who knew? Well, someone, but not me. And they knew a workaround too.

Thanks for your help, Donal! And to all the cool people who are working on this (Elias Torres, Pete Lacey, Sam Ruby, Tim Bray get special mention).

The APE now exercises my beta blog. Now I have to work out why it can't delete stuff ...