Interesting Things

Richard Bradshaw's idea of what is interesting

Dynamically drawing gradients with PHP

Just a little script to create a PNG image of a simple linear gradient using PHP. You could adapt this to make it better in many ways! Insipired (by which I mean 99% ripped of!) by http://www.cutcodedown.com/

No demo to avoid load on the server, but it just makes a simple gradient.

I use it as a fallback for CSS3 gradients.

<?php
/* Put on a server, make the gradients folder, then call like so:
 
gradient.php?sc=ff0000&ec=0000ff&h=100&w=200
 
sc = start colour, ec = end colour, h = height, w = width.
 
The file should be cached, though I normally use mod_rewrite to tidy it up a little.
*/
 
/* Change this to suit, you'll need to make the folder first */
$destfolder = $_SERVER[ 'DOCUMENT_ROOT' ]."/gradients/";
 
function caching_headers ($file, $timestamp) {
	$gmt_mtime = gmdate('r', $timestamp);
	header('ETag: "'.md5($timestamp.$file).'"');
 
	if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
		if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmt_mtime || str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == md5($timestamp.$file)) {
			header('HTTP/1.1 304 Not Modified');
			exit();
		}
	}
 
	header('Last-Modified: '.$gmt_mtime);
	header('Cache-Control: public');
}
 
function gradient($width,$height,$startColor,$endColor) {
	$final=imagecreatetruecolor($width,$height);
 
	$r=($startColor >> 16) & 0xFF;
	$g=($startColor >> 8) & 0xFF;
	$b=($startColor) & 0xFF;
 
	if ($height==0) {
		imagefill($final,0,0,imagecolorallocate($final,$r,$g,$b));
	} else {
 
		$endR=($endColor >> 16) & 0xFF;
		$endG=($endColor >> 8) & 0xFF;
		$endB=($endColor) & 0xFF;
 
		$incR=($endR-$r);
		$incG=($endG-$g);
		$incB=($endB-$b);
 
		$absDisR=abs($incR);
		$absDisG=abs($incG);
		$absDisB=abs($incB);
 
		if ($absDisR>$absDisG) {
			if ($absDisR>$absDisB) {
				$distance=$absDisR;
			} else {
				$distance=$absDisB;
			}
		} else if ($absDisG>$absDisB) {
			$distance=$absDisG;
		} else {
			$distance=$absDisB;
		}
 
		if ($distance==0) {
			imagefill($final,0,0,imagecolorallocate($final,$r,$g,$b));
		} else {
			if ($distance>$height) $distance=$height;
 
			$sliver=imagecreatetruecolor(1,$distance);
			$sliverMax=$distance-1;
 
			$incR/=$sliverMax;
			$incG/=$sliverMax;
			$incB/=$sliverMax;
 
			$style=array();
 
			for ($t=0; $t<$distance; $t++) {
				$style[$t]=imagecolorallocate($sliver,$r,$g,$b);
				$r+=$incR;
				$g+=$incG;
				$b+=$incB;
			}
 
			imagesetstyle($sliver,$style);
			imageline($sliver,0,0,0,$sliverMax,IMG_COLOR_STYLED);
			imagecopyresized(
				$final,$sliver,
				0,0,0,0,
				$width,$height,1,$distance
			);
			imagedestroy($sliver);
		}
	}
	return $final;
}
 
/* This bit isn't really very good, but you get the idea. */
$width=is_numeric(str_replace("px","",$_GET['w'])) ? $_GET['w'] : 96;
$height=is_numeric(str_replace("px","",$_GET['h'])) ? $_GET['h'] : 96;
$startColor=empty($_GET['sc']) ? 0 : hexdec($_GET['sc']);
$endColor=empty($_GET['ec']) ? 0xFFFFFF : hexdec($_GET['ec']);
 
$filename = $width."_".$height."_".$_GET['sc']."_".$_GET['ec'].".png";
 
if (!file_exists($destfolder.$filename)) {
	$image=gradient($width,$height,$startColor,$endColor);
	imagepng($image,$destfolder.$filename);
	imagedestroy($image);
}
 
caching_headers ($filename, filemtime($destfolder.$filename));
 
header('Parameters : '.$_GET['w']."x".$_GET['h']." ".$_GET['sc']." to ".$_GET['ec']);
header('Content-Type: image/png');
 
$image = imagecreatefrompng($destfolder.$filename);	
imagepng($image);
imagedestroy($image);
 
?>

CSS3 Transition, Transform and Animation Tutorial

I’ve just written a tutorial complete with demos showing how to use the CSS3 transition, transform and animation properties – find it here: CSS3 Transition, Transform and Animations Tutorial.

Hopefully it’s useful/interesting – any comments/improvements let me know!

It’s still a work in progress, so I’ll be adding to it over the next few weeks.

Fancy Forms: HTML5 + CSS3 – JS

Forms in HTML have typically been pretty boring – input boxes and buttons with all validation performed by javascript. With the new HTML5 Forms module things have become a little more useful. As of May 2010, only bleeding edge browsers support this, Webkit Nightlies, Chrome Dev Channel builds and Opera.

The HTML5 forms module started out as Web Forms 2.0 before moving into HTML5. The focus has been to increase the number of input types and to allow validation of input to happen in the browser, rather than in javascript.

HTML5 Form Demo

In this demo I’ve set up a simple form with a number of different fields, the code should be pretty self explanatory, but there are a couple of new features of interest.

  • New input types – email, url, number and range
  • New pseudo classes – :valid, :invalid:, :required
  • You can’t submit the form until all fields are counted as valid by the browser

I’ve also added a few CSS3 touches to make things a little nicer to look at:

  • CSS transitions and transformations
  • :not pseudo class

Things to try

  • Submit the form without completing it
  • Notice that the browser checks whether the input is valid
  • The iPhone offers different keyboards depending on the input type
  • Check what it looks like in older browsers (fine, but no validation)

The code is commented where interesting, so take a look at the source.

HTML5 Form Demo

Video of ChromeOS Early Build


Just a quick video made of the ChromeOS build found on the chromium.org server. It’s run on Ubuntu in a virtual machine running on Snow Leopard. Used Quicktime X to record it, which turned out pretty well I think!

Not much in there yet, but good to see that parts of it are on the way!

Interesting links for week ending October 14th

Here are some links that I’ve found interesting:

The State of Solid State Hard Drives

Fugitive gives the game away with Facebook updates

Tesco boss raps school standards

Help us nail spammers

Building a jQuery/PHP Powered Chat Room

Time-travelling Higgs sabotages the LHC. No, really

Tim Berners-Lee’s One Regret Regarding the Web

New in Labs: Got the wrong Bob?

Lightly Edit Images Easily With Acorn [Mac only]

Introducing Google Building Maker

Some interesting links for October 13th

Here are some links that I’ve found interesting:

Interesting Links

Here are some links that I’ve found interesting:

Improve the typography on your Mac in 5 seconds.

As you are surely aware, Microsoft ripped off Helvetica to create the Arial font. It’s not as nice, and doesn’t look nice on screen at all. The image below shows some of the differences.

As you can see, the ends of each letter aren’t lined up properly, they are all at weird angles.

Though Helvetica is the superior font, many sites specify that they should use Arial preferentially to Helvetica. This seems to be a throwback from Dreamweaver, which defines it’s default font stack as Arial, Helvetica, sans-serif. As Arial comes with Macs, no one will get the Helvetica in this situation.

Luckily, on your Mac there is an easy fix to rid websites of Arial – just open Fontbook, disable Arial and restart your web browser. Arial no more, Helvetica is back!

How to know that your PHP is borked before your clients kill you

Maybe it’s just me, but every now and then I make a quick change to a PHP script, don’t bother checking it, then a few hours/days/months later either realise that I missed a vital semicolon, or mismatched a bracket. This started to get on my nerves, as now this has happened a couple of times I’d like to prevent it from happening again.

After thinking about this a little, and asking the wonderful stackoverflow.com, a person known as okoman suggested using the cli version of PHP to test parse the code using the -l flag.

I quickly wrapped it into a parcel of (ugly) code, set up a cron job to run it as frequently as I estimate I make errors and can now sleep peacefully knowing that all semicolons are in place, and all if’s have the right number of brackets.

So, here’s the delicious file which I’ve placed on my server. You can edit it not to produce output if you’d like and just to send emails/tweets.

<?
function list_dir($dir) {
 
	if (is_dir($dir)) {
		if ($dh = opendir($dir)) {
			while (($file = readdir($dh)) !== false) {
				if (substr("$file", 0, 1) != ".") {
					$files[] = $file;
				}
			}
			closedir($dh);
		}
	}
	sort($files);
	return $files;
}
 
$dir = "/path/to/code//";
$files = list_dir($dir);
$num_files = count($files);
 
for($i=0;$i<$num_files;$i++) {
	if (strpos($files[$i],".php") !== false) {
		$path = $dir.$files[$i];
		$result = `php -l $path`;
 
		if (strpos($result, "Errors parsing") !== false) {
			//tweet_error("Syntax",$files[$i]); //Function in my last post
			mail("emailaddress@example.com","Syntax Error",$files[$i]);
			echo "Syntax error in $files[$i]\n";
		}
	}
}
 
?>

And that’s all there is to it.

To check that it’s working OK, try making a file such as:

<?
if () {
?>

and run the error checking file.

This could be extended by parsing out line numbers and error types, but this minimum setup works for me.

How to use Twitter as an error log

Sure this has been done before, but I had a brainwave today – why not use Twitter as an error log for web apps?

I already have error handling on my functions, so surely this shouldn’t be a difficult addition… turns out it’s not.

First, you’ll need a twitter account. I’d recommend setting one up, then protecting the updates. Keep the username and password, you’ll need them in a minute. I’d then follow the new account you set up, as well as anyone else on your team.

Then, define a function as follows in PHP, preferably in a global include or some such thing.

function tweet_error ($error, $description) {
	$username = 'yourusername';
	$password = 'yourpassword';
	$status = "#$error - $description";
 
	$update_url = 'http://www.twitter.com/statuses/update.xml'; // http://identi.ca/api/statuses/update.xml will use identi.ca instead.
 
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, "$update_url");
	curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 2);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($curl, CURLOPT_POST, 1);
	curl_setopt($curl, CURLOPT_POSTFIELDS, "status=$status");
	curl_setopt($curl, CURLOPT_USERPWD, "$username:$password");
 
	$result = curl_exec($curl);
	$resultArray = curl_getinfo($curl);
 
	curl_close($curl);
 
	return ($resultArray['http_code'] == 200);
}

My function here takes two parameters, the error code as well as a description. You could generalise this and rejig it a bit, as well as perhaps changing the $status variable to look different.

For instance,

$status = "d username #$error - $description";

or

$status = "@username #$error - $description";

to send it to you. You could even define different usernames for different types of errors, if you are in a team.

In your code, then call it like this:

tweet_error ("404", $_SERVER[SCRIPT_URL]);

to log a 404, as well as the page it came from, or:

tweet_error ("DB-Connect", "Failed");

In your database connection script, or even:

tweet_error ("Possible spam", "From user XXXX");

in your comment/email form handling.

Hope this comes in useful!