OneWheeledBicycle

Random mutterings of Alastair James

Automatically validate you XHTML output from PHP

leave a comment »

Today I was playing around, thinking of ways I can make validation easier when writing web applications. I thought it would be nice if I could (during development) configure PHP to automatically validate each webpage it generates against whatever XHTML Doctype I have chosen and return a (possibily big) list of errors at the bottom.

After digging around I decided to try the PHP tidy functions, however I soon discovered these are only for HTML. For XML based structures, the tool to use is xmllint that is included in your linux (or Mas OS X) install. Heres the code:


function dump_xhtml_validation_errors($xmltext){
$pipespec = array(
0 => array("pipe", "r"),
1 => array("file", "/dev/null", "w"),
2 => array("pipe", "w")
);
$pipes = array();
$cmd = "xmllint -noout -valid -nowrap -htmlout -";
$process = proc_open($cmd, $pipespec, $pipes, null, null);
if (is_resource($process)) {
fwrite($pipes[0], $xmltext);
fclose($pipes[0]);
echo stream_get_contents($pipes[2]);
fclose($pipes[2]);
proc_close($process);
}
}

The code basically opens pipes to a xmllint process, pipes in the XHTML and pipes out the errors to the browser. Its not pretty but works! I am hoping it will help me pick up XHTML errors as they arrive. Of course, this will only be possible if you are using a templating engine and are able to get all out output as one string. If you are using echos (urgh!) you will have to use output buffering to do this!

Update

The above method is very slow as xmllint will fetch the DTD from the w3c’s website for each validation. Its much quicker to store these on your own webserver for development (only). Simply down load the following files to a directory on your server (i.e. http://localhost/dtds):

  • http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd
  • http://www.w3.org/TR/xhtml1/DTD/xhtml1-lat1.dtd
  • http://www.w3.org/TR/xhtml1/DTD/xhtml1-symbols.dtd
  • http://www.w3.org/TR/xhtml1/DTD/xhtml1-special

Then add the following line as the very first line in the above function:


$xmltext = str_replace(
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd",
"http://localhost/dtds/xhtml1-strict.dtd ",
$xmltext
);

So that re-writes the DTD location in the xml before validation. Remember to change back before going live!

Advertisement

Written by aljames

March 5, 2007 at 1:02 am

Posted in Coding, PHP, Tech

Leave a Reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

Please log in to WordPress.com to post a comment to your blog.

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.