As I use more and more mock objects when testing I often have to fake the results of some findAll calls. That means I have to create array structures as shown in the following example:
$expectedPosts = array(array('Post' => array('id' => 3, 'title' => 'a title', 'content' => 'some content')),
array('Post' => array('id' => 4, 'title' => 'another title', 'content' => 'some other content')));
The core class Set provides an alternative way to create arrays using a dot notation. The example from above can be rewritten as:
$expectedPosts = array(); $expectedPosts = Set::insert($expectedPosts, '0.Post.id', 3); $expectedPosts = Set::insert($expectedPosts, '0.Post.title', 'a title'); $expectedPosts = Set::insert($expectedPosts, '0.Post.content', 'some content'); $expectedPosts = Set::insert($expectedPosts, '1.Post.id', 4); $expectedPosts = Set::insert($expectedPosts, '1.Post.title', 'another title'); $expectedPosts = Set::insert($expectedPosts, '1.Post.content', 'some other content');
You can also mix those two approaches:
$expectedPosts = array();
$expectedPosts = Set::insert($expectedPosts, '0.Post', array('id' => 3, 'title' => 'a title', 'content' => 'some content'));
$expectedPosts = Set::insert($expectedPosts, '1.Post', array('id' => 4, 'title' => 'another title', 'content' => 'some other content'));
It is quite handy, especially if you have to create more complex array structures.

Brilliant & simple, but I’d never have noticed it without this post. Will beautify several horrible array constructions (findAll pivots and transformations not able to be done in the SQL) in a couple of my controller actions.
Enjoy reading your blog thru google reader, keep them coming
The mixed approach is great!
Great way of improving code readability!
I like all these insights very much.
Thanks!
@Howard, Matt: Thanks for your comments!
For more readability I’d rather use a bit different array notation:
$expectedPosts = array( array( 'Post' => array( 'id' => 3, 'title' => 'a title', 'content' => 'some content' ) ), array( 'Post' => array( 'id' => 4, 'title' => 'another title', 'content' => 'some other content' ) ), );or using less space (worse case):
$expectedPosts = array( array('Post' => array( 'id' => 3, 'title' => 'a title', 'content' => 'some content' )), array('Post' => array( 'id' => 4, 'title' => 'another title', 'content' => 'some other content' )), );And don’t forget to avoid Set::insert in production because of performance ;)
Doh, html pre tag was stripped, so indentation is missing.. Please view the source to see what I’ve ment in my previous comment :)
Great post! If I’m not mistaken, Set class can also be instantiated:
$expectedPosts = new Set();
$expectedPosts->insert(’0.Post.id’, 3);
$expectedPosts->insert(’0.Post.title’, ‘a title’);
$expectedPosts->insert(’0.Post.content’, ‘some content’);
$expectedPosts->insert(’1.Post.id’, 4);
$expectedPosts->insert(’1.Post.title’, ‘another title’);
$expectedPosts->insert(’1.Post.content’, ‘some other content’);
$data = $expectedPosts->get();
@Lech, Brandon: Thanks for your comments!
@Lech: I fixed your comment by adding pre tags.
Yes, that’s a possible way to structure arrays. I think it is a matter of preference whether you like it that way or not. Personally, I don’t like it. I prefer to create private methods to create the sub arrays.
I think in most applications the impact of the described approach on the performance can be ignored ;-)
@Brandon: Yes, that works. I wasn’t aware you could use it in this way, too.
Ah, what a shortcut… real cool !!