Thom Lawrence

Entries from April 2006

Grouping Array Elements In PHP

April 30, 2006 · 1 Comment

PHP’s had array_chunk for a while, which splits an array into groups of a certain size. The Ruby equivalent is each_slice from Enumerator, recently joined by some Rails goodies in the form of Enumerable#group_by and Array#in_groups_of.

in_groups_of is just a slightly enhanced wrapper around each_slice, which gives it array_chunk’s ability to pad out groups. But PHP doesn’t seem to have anything like group_by, which lets you split the elements on some criteria. And because group_by takes a block, you can create nested groups to put the elements in whatever hierarchy you like.

So I’ve chucked together a function to do something similar:

function array_group($array, $callback) {
	return array_reduce(array_map($callback, $array), 'array_merge_recursive');
}

array_group expects $callback to take the element and put it into an array thusly:

array($top_level => array($mid_level => array($bottom_level => $element)));

The callback builds a mini hierarchy-of-one for each element, and then it’s all merged together. For example:

function group(&$element) {
	if (is_int($element)) {
		$top = 'number';
	} else if ($element == strtolower($element)) {
		$top = 'lower';
	} else if ($element == strtoupper($element)) {
		$top = 'upper';
	}

	$bottom = strlen($element) > 6 ? 'long' : 'short';

	return array($top => array($bottom => $element));
}

$array = array("lower", "UPPER", 12345, "lower lower", "UPPER UPPER", 1234567890);
var_dump(array_group($array, 'group'));

Gives you:

array(3) {
  ["lower"]=>
  array(2) {
    ["short"]=>
    string(5) "lower"
    ["long"]=>
    string(11) "lower lower"
  }
  ["upper"]=>
  array(2) {
    ["short"]=>
    string(5) "UPPER"
    ["long"]=>
    string(11) "UPPER UPPER"
  }
  ["number"]=>
  array(2) {
    ["short"]=>
    int(12345)
    ["long"]=>
    int(1234567890)
  }
}

I’m pretty sure that this implementation will lose any references inside the array, and I don’t think you can avoid that with all the array_map/reduce/merge_recursive stuff. If this is an issue for you, you’ll probably have to write something uglier (which I’d still like to see).

It still feels a bit clunky, but all in all it’s about as elegant as PHP gets, and it’s a nice demo of functional programming in the language.

Categories: Uncategorized

TAPEFAILURE Updates

April 26, 2006 · Comments Off

There’s now a TAPEFAILURE API, an address for bug reports and a bunch of fixes, all described in the new blog. Time for another look, I think.

Categories: Uncategorized

Simple Test, Better Living In PHP 4

April 26, 2006 · Comments Off

It takes a lot of will-power to do the right thing in PHP 4. As far as I can tell, PHP 5 is a healthy, sensible language, spawning all sorts of happy, shiny frameworks with ten fingers and ten toes each. PHP 4, on the other hand, is a strange, mutated strip-tease of a language. It comes tantalisingly close to being useful, but at the last moment it draws back the veil to reveal the pus-ridden, horribly deformed truth. Simple operators don’t work predictably, objects are taboo, the universe starts in 1970… when PHP 4 takes its shoes off, it’s hard to want to stay in the room.

But it lives on, and some days it pays your wages. And now I have one less reason to complain: having spent one too many weeks with PHPUnit (the PEAR version for PHP 4), wishing I could convince create_function to let me make mock objects, I discovered Simple Test. They do the dirty work, so you don’t have to: big fat evals of your classes, giving you return values, expectations and most of what you’d expect. Even better, Simple Test’s test case assertions are slightly less patronising than PHPUnit’s, so you won’t get errors refusing to implement useful funcionality in PHP 4.

It’s no Test::Unit, MbUnit or Rhino Mocks, but this truly is PHP 4 flavour country.

Categories: Uncategorized

TAPEFAILURE

April 15, 2006 · Comments Off

TAPEFAILURE doesn’t work for me in Firefox, and lacks lots of features that I’d love, but but it’s a fascinating idea that I’m definitely going to check back on.

It lets you record a browser session from their site, save it with a unique ID, and the share the ID and play it back (againt, it says it does this, but I couldn’t get anything to work – lots of permission errors in Firefox).

This could be an amazing testing tool, if only it was redistributable and had an API. Install it on a local server, have testers give a site a workout inside the TAPEFAILURE session, and give them tools to report bugs and save the session so someone can repeat it later. Use the API to export Selenium tests (or whatever you’d like to use) and integrate it with your QA process. Even if they just added the ability to set up accounts, you could allow bugs to be submitted through a TAPEFAILURE account for a live site.

Anyway, right now it could be cool for demoing new features, and I’d love to see a site asking for bug reports as TAPEFAILURE sessions. But if they wanted to add a layer for developers, it could become a really essential functional testing tool.

Categories: Uncategorized

Epicenter or Sinkhole?

April 10, 2006 · Comments Off

Jason Fried:

You can have a calendar without color coding. You can have a calendar without alarms. You can have a calendar without dragging and dropping. You can have a calendar without displaying a mini calendar of the next three months. You can have a calendar without a lot of things. But you can’t have a calendar without being able to add events. That’s where you start.

You can’t have a calendar without a login button either, but I guess that’s not as glamorous.

Categories: Uncategorized