Archive for the 'Web development' Category

Consistently smaller

If you’re anything like me then you’ll hand-craft your code to give you a fine-grained control over how things are done. Like a lot of geeks, I’m a bit of a code-snooper and the OCD side of me feels more than a little violated when I see the butt-ugly source code that is invariably generated by drag-and-drop WYSIWYG HTML editors.

I’m afraid I can’t remember who originally mooted this idea on Twitter a good while back: does having your HTML tag attributes in a consistent order give your webpage a smaller file size after it’s been compressed?

After thinking about it and playing around with some examples myself the other day I can confirm that it’s true. I’ve also found some corroboration from Google.

What’s the hold up?

The other day in the office we noticed that one of our servers was performing a little sluggishly. We rolled up our sleeves, fired up a terminal window and prepared to take a look under the hood.

There were a lot of database jobs backing up in the process list and this confused me – our connections are implemented as singleton classes and I was pretty sure that all of the queries had been examined with some EXPLAIN ANALYZE attention.

After some head-scratching I came up with this command line script that will list the five most CPU intensive SQL queries for the current user in the process list:

ps aux --sort=pcpu | grep "postgres: $USER" | tail -5 | awk '{ print $2 }' | xargs -I{} psql -c 'select procpid, current_query, query_start, backend_start from pg_stat_activity where procpid = {}'

Behind the scenes

The PQP profiler from Particletree is a very handy thing to have in your development toolbox. However, it doesn’t deal with the ever-increasing amount of work done via Ajax requests. Or, at least, it didn’t.

Back in the days when FireBug actually worked reliably, FirePHP was a very handy plugin that enabled you to view trace statements and debug information generated by PHP scripts requested by an XMLHttpRequest object. It occurred to me that I could use the same method of piggybacking JSON encoded messages in the HTTP headers, parse them with JavaScript and dynamically update the PQP Console. This way also means that a native cross-browser solution would be available.

The Prototype library has great Ajax support. Two features in particular allowed me to implement this new functionality extremely quickly: it adds a header that identifies requests as being of type XMLHttpRequest (as does jQuery) and has a global responders object (which jQuery lacks) that means any Ajax request created can automatically have the required callbacks registered. In short, you won’t need to change your code – as long as you’re using Prototype as well that is, although I’m sure one of you clever jQuery types can knock something up fairly quickly!

I made some fairly minimal changes to the PQP classes to add the new functionality (and to satisfy my obsession with coding standards). I also tidied up the JavaScript to ensure that the Prototype library would be available and take advantage of it for tab switching and DOM manipulation.

I’ll polish it a little, integrate it with my ongoing PDO work and document it properly later on but for now you can go and have a look at an example over at my playground.

A telling position

I ran into some issues while developing a site recently. Specifically, implementing an RSS feed of the clients news items. The XML validated perfectly fine and opened up in my testbed of various online and dedicated feed readers. However, the client insisted that something was broken. After much head-scratching and self-doubt I ascertained that the issue came down to the use of IE7 to view the news feed.

I never knew this before but IE7 will refuse to display any feed that uses a DTD. Apparently DTDs are insecure and every single one is untrusted. Yes, even those provided by the W3C.

I think that this says everything that you need to know about Internet Explorer’s attitude toward the foundation that develops free and open web standards.

Restoring PDO functionality

A few years ago, while PHP 5 was still in a state of flux, a change was made to the way that PDO handles parameters bound to prepared statements. Somewhere between versions 5.2.0 and 5.2.1 a change was made that gave rise to much annoyance and debate in bug 40417. Long story short, it used to be acceptable to reuse a placeholder in statement several times and bind a single variable to all of the instances thusly:

< ?php

	// Connect to the database with defined constants
	$dbh = safePDO_Factory::getInstance(PDO_DSN, PDO_USER, PDO_PASSWORD);
	$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

	try {

		// Construct SQL query
		$query  = '
			SELECT
				*
			FROM
				tblnews
			WHERE
				title ILIKE :search
				OR content ILIKE :search
		';

		// Prepare the statement
		$stmt = $dbh->prepare($query);

		// Bind the search string variable to the statement
		$smt->bindParam(':search', $search, PDO::PARAM_STR);

		// Execute the query
		$stmt->execute();

		// Check to see if we have any results
		if ($stmt->rowCount() > 0) {
			// Process the results here . . .
		} else {
			echo 'No search results were returned.';
		}
	} catch (Exception $e) {
		echo $e->getMessage();
	)

	// Destroy the database connection
	$dbh = null;

?>

But all of a sudden the above rudimentary news searching code would cease to work if you upgraded to PHP 5.2.1 and there was no notice in the PHP change log at the time, which obviously led to much confusion. The issue was that it was no longer acceptable to bind a single variable to multiple placeholders – each placeholder required a unique name and explicit variable binding.

In much the same way that I subclassed the PDO connection class, the individual PDO Statement class can be extended to restore this multiple placeholder / single variable behaviour.

Continue reading ‘Restoring PDO functionality’

PHP Development with Snow Leopard

I spend most of my working day developing with PHP and Apache on a Postgres database back-end. Mac OS X coming complete with two out of these three things is great but traditionally the standard installs have been a little out-dated leaving most developers to rely on people like Marc Liyanage to take care of building the packages for us. Ironically, it was a remnant of a previous entropy install that was causing me grief with Apache earlier in the week1.

With Snow Leopard I was very happy to see PHP 5.3 installed but Postgres was still notable by it’s absence. In order to replicate my day-to-day environment, I’d have to roll up my sleeves and get a little dirty with the Terminal – but not too dirty!

I also upgraded PEAR to install PHPUnit, PhpDocumentor and Phing. I had been meaning to play around with some more advanced debugging and profiling tools for a while and found the instructions for installing Xdebug very helpful.

Finally, I installed some pretty GUIs makes my life easier and shinier:

1 In case you’re curious, an extra and obsolete configuration file in /private/etc/apache2/users/ cascaded down to httpd-userdir.conf and httpd.conf which meant that Apache would not start.

I am the one and only

After previously explaining how to harden PDO I’m going to expand on the basic class I developed with the help of some design patterns.

A large part of using design patterns lies in recognising the situations in which each one should be used. The temptation is to implement the safePDO database class as a singleton so that only one instance of the object is used and extra connections are not made. An issue arises immediately as the constructor must be defined as public – the same as the parent PDO class – and therefore it will be able to be instantiated from anywhere. Besides, occasionally, you may also need to connect to another database which renders the singleton pattern useless.

A better choice for this situation, in my opinion, is the flyweight pattern. This is ordinarily used where a large number of similar items are to be used but can easily be applied in this situation so that database connection requests that have the same credentials can be reused.

In the following code a singleton factory pattern is used to handle and distribute requests for database connections, using the dsn and username as an array key for a pool of safePDO instances. You can rest assured that the database connection is wrapped in a try/catch block. As an added bonus, as all safePDO construction should be made from the factory class, we can make a check for this using a debug backtrace and therefore prevent a safePDO object from being instantiated at random.

If PHP code isn’t your thing – and assuming you’ve not already stopped reading by now – then you may want to give the code after the jump a miss. If your curiosity is piqued, read on . . .

Continue reading ‘I am the one and only’

Catching at source

If your application does not catch the exception thrown from the PDO constructor, the default action taken by the zend engine is to terminate the script and display a back trace. This back trace will likely reveal the full database connection details, including the username and password.
- PDO Connections and Connection management

Ideally you shouldn’t be displaying any error messages to the outside world at all – especially on a production server. Even during development you should probably limit debugging output to approved IP addresses only.

You can take a very simple step to avoid displaying your username and password should the connection fail and you (or somebody else) forget to catch the error. By subclassing the PDO database abstraction layer you can make sure that you implicitly catch the exception message by temporarily changing the PHP exception handler.

You could generate your own backtrace here as well and sanitize the data to remove any passwords before display but I shall leave that as an exercise for the reader.

All you need to do now is remember to use the SafePDO class instead of instantiating a standard PDO object.

< ?php

	Class SafePDO extends PDO {

		public static function exception_handler($exception) {
			// Output the exception details
			die('Uncaught exception: ', $exception->getMessage());
		}

		public function __construct($dsn, $username='', $password='', $driver_options=array()) {

			// Temporarily change the PHP exception handler while we . . .
			set_exception_handler(array(__CLASS__, 'exception_handler'));

			// . . . create a PDO object
			parent::__construct($dsn, $username, $password, $driver_options);

			// Change the exception handler back to whatever it was before
			restore_exception_handler();
		}

	}

	try {

		// Connect to the database with defined constants
		$dbh = new SafePDO(PDO_DSN, PDO_USER, PDO_PASSWORD);

		// The rest of your code goes here . . .

		// Destroy the database connection
		$dbh = null;

	} catch (Exception $e) {
		SafePDO::exception_handler($e);
	}

?>

A better phpinfo

The phpinfo() command comes in very useful when you want to check details about your PHP install and server setup. However, there is a lot of output and you won’t need it all. Not everyone knows that you can pass parameters to the function to narrow the scope of the information displayed.

I came up with this simple method to view the results of using these parameters and make it easy to switch between them.

< ?php

	$options = array('CONFIGURATION', 'ENVIRONMENT', 'MODULES', 'VARIABLES', 'GENERAL', 'CREDITS', 'LICENSE', 'ALL');
	$display = (empty($_GET['display']) || !in_array(strtoupper($_GET['display']), $options)) ? 'ALL' : strtoupper($_GET['display']);

	$navigation = array();

	foreach($options as $key=>$value) {
		$navigation[] = ($value != $display) ? '<a href="' . $_SERVER['SCRIPT_NAME'] . '?display=' . $value . '">' . $value . '</a>' : '<strong>' . $value . '</strong>';
	}

	ob_start();

	switch($display) {
		case 'CONFIGURATION':
			phpinfo(INFO_CONFIGURATION);
			break;

		case 'ENVIRONMENT':
			phpinfo(INFO_ENVIRONMENT);
			break;

		case 'MODULES':
			phpinfo(INFO_MODULES);
			break;

		case 'VARIABLES':
			phpinfo(INFO_VARIABLES);
			break;

		case 'GENERAL':
			phpinfo(INFO_GENERAL);
			break;

		case 'CREDITS':
			phpinfo(INFO_CREDITS);
			break;

		case 'LICENSE':
			phpinfo(INFO_LICENSE);
			break;

		case 'ALL': default:
			phpinfo();
			break;
	}

	$content = ob_get_clean();

	if (('CREDITS' === $display) &amp; preg_match('/<h1><a href="([^"]+?)">PHP Credits< \/a>< \/h1>/', $content, $matches) & !empty($matches)) {
		$content = file_get_contents('http://' . $_SERVER['HTTP_HOST'] . $matches[1]);
	}

	echo str_replace('<body>', '</body><body><div class="center options"><p>' . implode(' | ', $navigation) . '</p></div>', $content);

?>

It’s also worth pointing out that the information exposed by this function can be useful to people who want to locate any weaknesses in your system so I would recommend restricting access to this file with a password, by an IP address range or only uploading the file to your webserver temporarily and removing it as soon as you’re finished with it.

Choices

After Google I/O a few weeks ago I got to playing with some of the HTML5 demos that were used during the keynote presentation. I was impressed by performance and browser support: the latest releases of Firefox, Chrome, Opera and Safari all embrace HTML5. True-to-form, IE is a long way behind. As Ian Hickson correctly identifies, browser vendors have the ultimate veto on a specification: if they don’t implement it then it might as well not exist. In this way a consensus between vendors can lead the development of a specification as opposed to the other way round. I wouldn’t say that it’s exactly a collusion to drive people away from IE but even if it was, few developers would mourn its passing.

I attended a talk given by Tristan Nitot at Internet World last year where he extolled the virtues of openness and the dangers of lock-in. The ownership of a standard implies control. Systems without control lead to cooperation, transparency, participation, equality and freedom. In a system with control, you get to decide who can see what and what to charge them. I’m not saying that this is the goal of Adobe. They may very well keep content available for everyone without charge but the danger that people could be pushed towards content from which Adobe receive a payment is palpable.

Microsoft’s Silverlight was actually a welcome competitor but it is still a proprietary technology and it’s safe to say that adoption rates have been less then stellar. Major League Baseball dropped Silverlight recently and even Bing – Microsoft’s newly branded search engine – favours Flash.

The majority of the time that I encounter Flash on the Internet it’s used simply to present video. The native <video> tag as used by YouTube and Dailymotion could put a serious dent in the importance of Flash despite the near ubiquitous install base.