signalkraft

Real-World Examples of PHP5.3

With­out fur­ther ado, here’s some cool stuff that only works in the lat­est big release of PHP:

Adding Data to an Array
<?php
	
	$blogPosts = getBlogPosts();
	$postsWithPictures = array();
	
	// The old way...
	foreach($blogPosts AS $key => $post)
	{
		$postsWithPictures[$key] = $post;
		$postsWithPictures[$key]['pictures'] = getPostPictures($post['id']);
	}
	
	// ...the anonymous function...
	$postsWithPictures = array_map(
		function($post) {
			$post['pictures'] = getPostPictures($post['id']);
			return $post;
		},
		$blogPosts
	);
	
	// ...and the lambda:
	
	$addPictures = function($post) { 
		$post['pictures'] = getPostPictures($post['id']); return $post; 
	};
	
	$postsWithPictures = array_map($addPictures, $blogPosts);

The final ver­dict on per­for­mance is still out — in the­ory the pro­ce­dural style of foreach loops is slightly quicker than array_map, as the lat­ter adds a func­tion call to every iter­a­tion. We’re talk­ing mil­lisec­onds here, and in this exam­ple getPostPictures() would prob­a­bly slow down all three exam­ples to an equally slow pace.

Clo­sures as Func­tion Arguments

Imag­ine you have a HTML helper func­tion that gen­er­ates anchors from a route…

<?php echo anchor('Blog/archive', 'Archive'); ?>

…using your framework’s Router library the result might look like this:

<a href="http://blog.com/myblog/archive.html">Archive</a>

In one par­tic­u­lar case you need to alter the gen­er­ated link slightly. You could hard­code that spe­cific case into the func­tion itself and add another para­me­ter, or you could add a much more future-proof method of chang­ing the HTML lay­out with a third, optional Clo­sure argument:

<?php
	$wrapper = function($route, $name) {
		return "<span target=\"$route\">$name</span>";
	}
	echo anchor('blog/archive', 'Archive', $wrapper);
?>

The anchor func­tion def­i­n­i­tion could look like this:

<?php
function anchor($route, $name, \Closure $wrapper = null) {
	if (is_null($wrapper)) {
		$wrapper = function($route, $name) {
			$href = MyFramework::getRouter()->resolve($route);
			return "<a href=\"\">$name</span>";
		}
	}
	return $wrapper($route, $name);
}
?>

This means you now cov­ered all pos­si­ble usage sce­nar­ios involv­ing the lay­out of the gen­er­ated HTML.

The type­hint in the 2nd line (\Closure) “hints” at another fan­tas­tic new fea­ture in PHP 5.3 — namespaces.

You should check out the lat­est devel­op­ment in Doc­trine 2.0 for some real-world usage of namespaces.