March 4, 2008 – 12:56 am
Test data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| $data = array(
1 => array('Post' => array(
'id' => 1, 'post_comment_count' => 2,
'name' => 'My first title', 'body' => 'My first body'
),
'PostComment' => array(
array(
'id' => 1, 'post_id' => 1, 'is_active' => 1,
'name' => 'My first comment', 'body' => 'My first comment'),
array(
'id' => 2, 'post_id' => 2, 'is_active' => 1,
'name' => 'My second comment', 'body' => 'My second comment'),
array(
'id' => 3, 'post_id' => 2, 'is_active' => 1,
'name' => 'My third comment', 'body' => 'My third comment')
)
),
2 => array('Post' => array(
'id' => 2, 'post_comment_count' => 1,
'name' => 'My second title', 'body' => 'My second title'
),
'PostComment' => array(
array(
'id' => 4, 'post_id' => 2, 'is_active' =>
1, 'name' => 'My fourth comment', 'body' => 'My fourth comment'
)
)
),
3 => array('Post' => array(
'id' => 3, 'post_comment_count' => 0,
'name' => 'My third title', 'body' => 'My third title'
),
'PostComment' => array(
)
)
);
$dataExtra = array(
4 => array('Post' => array(
'id' => 4, 'post_comment_count' => 1,
'name' => 'My fourth title', 'body' => 'My fourth title'
),
'PostComment' => array(
array(
'id' => 5, 'post_id' => 4, 'is_active' => 1,
'name' => 'My fifth comment', 'bdoy' => 'My fifth comment'
)
)
)
); |
Set::merge
PHP doc blcok
This function can be thought of as a hybrid between PHP's array_merge and
array_merge_recursive. The difference to the two is that if an array key
contains another array then the function behaves recursive (unlike array_merge)
but does not do if for keys containing strings (unlike array_merge_recursive).
See the unit test for more information.
Note: This function will work with an unlimited amount of arguments and
typecasts non-array parameters into arrays.
A bit like array_merge_recursive. Merge joins two arrays on their keys.
If we want to add the $extraData array into the $dat most people would probably think, hey, lets merge them using Set::merge… but.. no, dont, unless you know what your doing.
1
| pr(Set::merge($data, $dataExtra)); |
The above cod will only produce the ‘expected’(?) result because I have added the numeric key 4 in the $extraData array (Line 40). If I had, as I did the first time around, just let php auto-increment the keys for me, both $datad and $extraData would contain the numeric index key 0, and since Set::merge works on keys, $extraData’s Fourth post would overwrite $data’s First post where they had anything in common (id, name, post_comment_count, body and everything in the first PostComment (My first comment)).
In case I had let php handle the index keys, I would have to use Set::insert to append the fourth comment to the list.
A better use of Set::merge is in CAKE/libs/model/model.php where is automagic merges ‘actsAs’ from your current model (PostComment) and your AppModel, so you automagic inherit the global behaviors from AppModel:
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
| // model.php
if (is_subclass_of($this, 'AppModel')) {
$appVars = get_class_vars('AppModel');
$merge = array();
if ($this->actsAs !== null || $this->actsAs !== false) {
$merge[] = 'actsAs';
}
foreach ($merge as $var) {
if (isset($appVars[$var]) && !empty($appVars[$var]) && is_array($this->{$var})) {
$this->{$var} = Set::merge($appVars[$var], $this->{$var});
}
}
} |
A funny thing is that Set::merge is still rarely used in the core code yet. Probably because array_merge (or am()) is faster for simple operations like just merging two simple 1 level arrays like a config array.
Set::filter
PHP doc blcok
Filters empty elements out of a route array, excluding '0'.
This method is not recursive. So doing
1
2
| < ?php
pr(Set::filter($data, true)); |
wont change anything in the array sinc no elements in first level is empty.
1
2
3
4
5
6
7
8
9
| pr(Set::filter($data[3], true));
array('Post' => array(
'id' => 3,
'post_comment_count' => 0,
'name' => 'My third title',
'body' => 'My third title'
)
); |
We will notice that the PostComment array is gone, since its empty
Set::pushDiff
PHP doc blcok
Pushes the differences in $array2 onto the end of $array
That sounds simple enough, and it really is.
1
| pr(Set::pushDiff($data, $dataExtra)); |
just pushes the $dataExtra on the end of $data, since they have nothing in common. Again, this method operates on the array keys when comparing arrays.
Set::map
PHP doc block
Maps the contents of the Set object to an object hierarchy.
Maintains numeric keys as arrays of objects
That sounds very fancy, and it is! A lot of people migrating to CakePHP from Symfony (PHPDoctrine, Propel) will probably be confused at first that all model data in CakePHP is arrays, and not objects like other frameworks. This method attemps to ‘fix’ this issue by converting a model data array to a set of objects (StdClass). StdClass is a build-in dummy class in PHP, and it doesnt really do anything but contain data, no methods or fancy magic there.
1
2
3
4
5
6
7
8
9
| < ?php
// Convert to objects
$map = Set::map($data);
// id of first post (Object style)
echo $map[0]->id;
// name of first comment to first post (Object style)
echo $map[0]->PostComment[0]->name;
// name of first comment to first post (array style)
echo $map[0]['PostComment'][0]['name']; // WONT WORK, Cannot access StdClass as an array |
As you can see above, its important to decide what method you want to use, Object or Array style, since they cannot be mixed.
Also, the return from Set::map is a mix of arrays and StdClass, thats why I can access $map[0] as array, but not access $map[0]['name'].
Set::numeric
PHP doc blcok
Checks to see if all the values in the array are numeric
Not much to say on this one, because it doesnt do more or less than the name implies.
1
2
3
4
5
6
7
8
| // false
var_dump(Set::numeric($data));
// false
var_dump(Set::numeric($data[1]));
// false
var_dump(Set::numeric($data[1]['PostComment']));
// true
var_dump(Set::numeric(array(1,2,3))); |
——-
Thats it for now, next time I will look at:
Set::enum, Set::format, Set::extract, Set::insert, Set::remove, Set::check, Set::diff, Set::isEqual, Set::contains, Set::countDim, Set::normalize, Set::combine and Set::reverse.
Look forward to it
Tags: Cakephp, english, set
Posted in Cakephp | 4 Comments »