Hash

    • class Hash
    • Array management, if done right, can be a very powerful and usefultool for building smarter, more optimized code. CakePHP offers avery useful set of static utilities in the Hash class that allow youto do just that.

    The path syntax described below is used by all the methods in Hash. Not allparts of the path syntax are available in all methods. A path expression ismade of any number of tokens. Tokens are composed of two groups. Expressions,are used to traverse the array data, while matchers are used to qualifyelements. You apply matchers to expression elements.

    All expression elements are supported by all methods. In addition to expressionelements, you can use attribute matching with certain methods. They are extract(),combine(), format(), check(), map(), reduce(),apply(), sort(), insert(), remove() and nest().

    Attribute Matching Types

    MatcherDefinition
    [id]Match elements with a given array key.
    [id=2]Match elements with id equal to 2.
    [id!=2]Match elements with id not equal to 2.
    [id>2]Match elements with id greater than 2.
    [id>=2]Match elements with id greater thanor equal to 2.
    [id<2]Match elements with id less than 2
    [id<=2]Match elements with id less thanor equal to 2.
    [text=/…/]Match elements that have values matchingthe regular expression inside .
    • static Cake\Utility\Hash::get(array|ArrayAccess $data, $path, $default = null)
    • get() is a simplified version of extract(), it only supports directpath expressions. Paths with {n}, {s}, {*} or matchers are notsupported. Use get() when you want exactly one value out of an array. Ifa matching path is not found the default value will be returned.

    • static Cake\Utility\Hash::extract(array|ArrayAccess $data, $path)

    • Hash::extract() supports all expression, and matcher components ofHash Path Syntax. You can use extract to retrieve data from arraysor object implementing ArrayAccess interface, along arbitrary pathsquickly without having to loop through the data structures. Instead youuse path expressions to qualify which elements you want returned
    • static Cake\Utility\Hash::insert(array $data, $path, $values = null)
    • Inserts $values into an array as defined by $path:
    1. $a = [
    2. 'pages' => ['name' => 'page']
    3. ];
    4. $result = Hash::insert($a, 'files', ['name' => 'files']);
    5. // $result now looks like:
    6. [
    7. [pages] => [
    8. [name] => page
    9. ]
    10. [files] => [
    11. [name] => files
    12. ]
    13. ]
    1. $users = Hash::insert($users, '{n}.new', 'value');

    Attribute matchers work with insert() as well:

    1. $data = [
    2. 0 => ['up' => true, 'Item' => ['id' => 1, 'title' => 'first']],
    3. 1 => ['Item' => ['id' => 2, 'title' => 'second']],
    4. 2 => ['Item' => ['id' => 3, 'title' => 'third']],
    5. 3 => ['up' => true, 'Item' => ['id' => 4, 'title' => 'fourth']],
    6. 4 => ['Item' => ['id' => 5, 'title' => 'fifth']],
    7. ];
    8. $result = Hash::insert($data, '{n}[up].Item[id=4].new', 9);
    9. /* $result now looks like:
    10. [
    11. ['up' => true, 'Item' => ['id' => 1, 'title' => 'first']],
    12. ['Item' => ['id' => 2, 'title' => 'second']],
    13. ['Item' => ['id' => 3, 'title' => 'third']],
    14. ['up' => true, 'Item' => ['id' => 4, 'title' => 'fourth', 'new' => 9]],
    15. ['Item' => ['id' => 5, 'title' => 'fifth']],
    16. ]
    17. */
    • static Cake\Utility\Hash::remove(array $data, $path)
    • Removes all elements from an array that match $path.
    1. $a = [
    2. 'pages' => ['name' => 'page'],
    3. 'files' => ['name' => 'files']
    4. ];
    5. $result = Hash::remove($a, 'files');
    6. /* $result now looks like:
    7. [
    8. [pages] => [
    9. [name] => page
    10. ]
    11.  
    12. ]
    13. */

    Using {n}, {s} and {*} will allow you to remove multiple values at once.You can also use attribute matchers with remove():

    1. $data = [
    2. 0 => ['clear' => true, 'Item' => ['id' => 1, 'title' => 'first']],
    3. 1 => ['Item' => ['id' => 2, 'title' => 'second']],
    4. 2 => ['Item' => ['id' => 3, 'title' => 'third']],
    5. 3 => ['clear' => true, 'Item' => ['id' => 4, 'title' => 'fourth']],
    6. 4 => ['Item' => ['id' => 5, 'title' => 'fifth']],
    7. ];
    8. $result = Hash::remove($data, '{n}[clear].Item[id=4]');
    9. /* $result now looks like:
    10. [
    11. ['clear' => true, 'Item' => ['id' => 1, 'title' => 'first']],
    12. ['Item' => ['id' => 2, 'title' => 'second']],
    13. ['Item' => ['id' => 3, 'title' => 'third']],
    14. ['clear' => true],
    15. ['Item' => ['id' => 5, 'title' => 'fifth']],
    16. ]
    17. */
    • static Cake\Utility\Hash::combine(array $data, $keyPath, $valuePath = null, $groupPath = null)
    • Creates an associative array using a $keyPath as the path to build its keys,and optionally $valuePath as path to get the values. If $valuePath is notspecified, or doesn’t match anything, values will be initialized to null.You can optionally group the values by what is obtained when following thepath specified in $groupPath.
    1. $a = [
    2. [
    3. 'User' => [
    4. 'id' => 2,
    5. 'group_id' => 1,
    6. 'Data' => [
    7. 'user' => 'mariano.iglesias',
    8. 'name' => 'Mariano Iglesias'
    9. ]
    10. ]
    11. ],
    12. [
    13. 'User' => [
    14. 'id' => 14,
    15. 'group_id' => 2,
    16. 'Data' => [
    17. 'user' => 'phpnut',
    18. 'name' => 'Larry E. Masters'
    19. ]
    20. ]
    21. ],
    22. ];
    23.  
    24. $result = Hash::combine($a, '{n}.User.id');
    25. /* $result now looks like:
    26. [
    27. [2] =>
    28. [14] =>
    29. ]
    30. */
    31.  
    32. $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.user');
    33. /* $result now looks like:
    34. [
    35. [2] => 'mariano.iglesias'
    36. [14] => 'phpnut'
    37. ]
    38. */
    39.  
    40. $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data');
    41. /* $result now looks like:
    42. [
    43. [2] => [
    44. [user] => mariano.iglesias
    45. [name] => Mariano Iglesias
    46. ]
    47. [14] => [
    48. [user] => phpnut
    49. [name] => Larry E. Masters
    50. ]
    51. ]
    52. */
    53.  
    54. $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.name');
    55. /* $result now looks like:
    56. [
    57. [2] => Mariano Iglesias
    58. [14] => Larry E. Masters
    59. ]
    60. */
    61.  
    62. $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data', '{n}.User.group_id');
    63. /* $result now looks like:
    64. [
    65. [1] => [
    66. [2] => [
    67. [user] => mariano.iglesias
    68. [name] => Mariano Iglesias
    69. ]
    70. ]
    71. [2] => [
    72. [14] => [
    73. [user] => phpnut
    74. [name] => Larry E. Masters
    75. ]
    76. ]
    77. ]
    78. */
    79.  
    80. $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.name', '{n}.User.group_id');
    81. /* $result now looks like:
    82. [
    83. [1] => [
    84. [2] => Mariano Iglesias
    85. ]
    86. [2] => [
    87. [14] => Larry E. Masters
    88. ]
    89. ]
    90. */

    You can provide arrays for both $keyPath and $valuePath. If you do this,the first value will be used as a format string, for values extracted by theother paths:

    1. $result = Hash::combine(
    2. $a,
    3. '{n}.User.id',
    4. ['%s: %s', '{n}.User.Data.user', '{n}.User.Data.name'],
    5. '{n}.User.group_id'
    6. );
    7. /* $result now looks like:
    8. [
    9. [1] => [
    10. [2] => mariano.iglesias: Mariano Iglesias
    11. ]
    12. [2] => [
    13. [14] => phpnut: Larry E. Masters
    14. ]
    15. */
    16.  
    17. $result = Hash::combine(
    18. $a,
    19. ['%s: %s', '{n}.User.Data.user', '{n}.User.Data.name'],
    20. '{n}.User.id'
    21. );
    22. /* $result now looks like:
    23. [
    24. [mariano.iglesias: Mariano Iglesias] => 2
    25. [phpnut: Larry E. Masters] => 14
    26. ]
    27. */
    • static Cake\Utility\Hash::format(array $data, array $paths, $format)
    • Returns a series of values extracted from an array, formatted with aformat string:
    • static Cake\Utility\Hash::contains(array $data, array $needle)
    • Determines if one Hash or array contains the exact keys and valuesof another:
    1. $a = [
    2. 0 => ['name' => 'main'],
    3. 1 => ['name' => 'about']
    4. ];
    5. $b = [
    6. 0 => ['name' => 'main'],
    7. 1 => ['name' => 'about'],
    8. 2 => ['name' => 'contact'],
    9. 'a' => 'b'
    10. ];
    11.  
    12. $result = Hash::contains($a, $a);
    13. // true
    14. $result = Hash::contains($a, $b);
    15. // false
    16. $result = Hash::contains($b, $a);
    17. // true
    • static Cake\Utility\Hash::check(array $data, string $path = null)
    • Checks if a particular path is set in an array:
    1. $set = [
    2. 'My Index 1' => ['First' => 'The first item']
    3. ];
    4. $result = Hash::check($set, 'My Index 1.First');
    5. // $result == true
    6.  
    7. $result = Hash::check($set, 'My Index 1');
    8. // $result == true
    9.  
    10. $set = [
    11. 'My Index 1' => [
    12. 'First' => [
    13. 'Second' => [
    14. 'Third' => [
    15. 'Fourth' => 'Heavy. Nesting.'
    16. ]
    17. ]
    18. ]
    19. ]
    20. ];
    21. $result = Hash::check($set, 'My Index 1.First.Second');
    22. // $result == true
    23.  
    24. $result = Hash::check($set, 'My Index 1.First.Second.Third');
    25. // $result == true
    26.  
    27. $result = Hash::check($set, 'My Index 1.First.Second.Third.Fourth');
    28. // $result == true
    29.  
    30. $result = Hash::check($set, 'My Index 1.First.Seconds.Third.Fourth');
    31. // $result == false
    • static Cake\Utility\Hash::filter(array $data, $callback = ['Hash', 'filter'])
    • Filters empty elements out of array, excluding ‘0’. You can also supply acustom $callback to filter the array elements. You callback shouldreturn false to remove elements from the resulting array:
    1. $data = [
    2. '0',
    3. false,
    4. true,
    5. 0,
    6. ['one thing', 'I can tell you', 'is you got to be', false]
    7. ];
    8. $res = Hash::filter($data);
    9.  
    10. /* $res now looks like:
    11. [
    12. [0] => 0
    13. [2] => true
    14. [3] => 0
    15. [4] => [
    16. [0] => one thing
    17. [1] => I can tell you
    18. [2] => is you got to be
    19. ]
    20. ]
    21. */
    • static Cake\Utility\Hash::flatten(array $data, string $separator = '.')
    • Collapses a multi-dimensional array into a single dimension:
    1. $arr = [
    2. [
    3. 'Post' => ['id' => '1', 'title' => 'First Post'],
    4. 'Author' => ['id' => '1', 'user' => 'Kyle'],
    5. ],
    6. [
    7. 'Post' => ['id' => '2', 'title' => 'Second Post'],
    8. 'Author' => ['id' => '3', 'user' => 'Crystal'],
    9. ],
    10. ];
    11. $res = Hash::flatten($arr);
    12. /* $res now looks like:
    13. [
    14. [0.Post.id] => 1
    15. [0.Post.title] => First Post
    16. [0.Author.id] => 1
    17. [0.Author.user] => Kyle
    18. [1.Post.id] => 2
    19. [1.Post.title] => Second Post
    20. [1.Author.id] => 3
    21. [1.Author.user] => Crystal
    22. ]
    23. */
    • static Cake\Utility\Hash::expand(array $data, string $separator = '.')
    • Expands an array that was previously flattened withHash::flatten():
    1. $data = [
    2. '0.Post.id' => 1,
    3. '0.Post.title' => First Post,
    4. '0.Author.id' => 1,
    5. '0.Author.user' => Kyle,
    6. '1.Post.id' => 2,
    7. '1.Post.title' => Second Post,
    8. '1.Author.id' => 3,
    9. '1.Author.user' => Crystal,
    10. ];
    11. $res = Hash::expand($data);
    12. /* $res now looks like:
    13. [
    14. [
    15. 'Post' => ['id' => '1', 'title' => 'First Post'],
    16. 'Author' => ['id' => '1', 'user' => 'Kyle'],
    17. ],
    18. [
    19. 'Post' => ['id' => '2', 'title' => 'Second Post'],
    20. 'Author' => ['id' => '3', 'user' => 'Crystal'],
    21. ],
    22. ];
    23. */
    • static Cake\Utility\Hash::merge(array $data, array $merge[, array $n])
    • This function can be thought of as a hybrid between PHP’sarray_merge and array_merge_recursive. The difference to the twois that if an array key contains another array then the functionbehaves recursive (unlike array_merge) but does not do if for keyscontaining strings (unlike array_merge_recursive).

    Note

    1. $array = [
    2. [
    3. 'id' => '48c2570e-dfa8-4c32-a35e-0d71cbdd56cb',
    4. 'name' => 'mysql raleigh-workshop-08 < 2008-09-05.sql ',
    5. 'description' => 'Importing an sql dump'
    6. ],
    7. [
    8. 'id' => '48c257a8-cf7c-4af2-ac2f-114ecbdd56cb',
    9. 'name' => 'pbpaste | grep -i Unpaid | pbcopy',
    10. 'description' => 'Remove all lines that say "Unpaid".',
    11. ]
    12. ];
    13. $arrayB = 4;
    14. $arrayC = [0 => "test array", "cats" => "dogs", "people" => 1267];
    15. $arrayD = ["cats" => "felines", "dog" => "angry"];
    16. $res = Hash::merge($array, $arrayB, $arrayC, $arrayD);
    17.  
    18. /* $res now looks like:
    19. [
    20. [0] => [
    21. [id] => 48c2570e-dfa8-4c32-a35e-0d71cbdd56cb
    22. [name] => mysql raleigh-workshop-08 < 2008-09-05.sql
    23. [description] => Importing an sql dump
    24. ]
    25. [1] => [
    26. [id] => 48c257a8-cf7c-4af2-ac2f-114ecbdd56cb
    27. [name] => pbpaste | grep -i Unpaid | pbcopy
    28. [description] => Remove all lines that say "Unpaid".
    29. ]
    30. [2] => 4
    31. [3] => test array
    32. [cats] => felines
    33. [people] => 1267
    34. [dog] => angry
    35. ]
    36. */
    • static Cake\Utility\Hash::numeric(array $data)
    • Checks to see if all the values in the array are numeric:
    1. $res = Hash::numeric(array_keys($data));
    2. // $res is true
    3.  
    4. $data = [1 => 'one'];
    5. $res = Hash::numeric($data);
    6. // $res is false
    • static Cake\Utility\Hash::dimensions(array $data)
    • Counts the dimensions of an array. This method will onlyconsider the dimension of the first element in the array:
    • static maxDimensions(array $data)
    • Similar to , however this method returns,the deepest number of dimensions of any element in the array:
    1. $data = ['1' => '1.1', '2', '3' => ['3.1' => '3.1.1']];
    2. $result = Hash::maxDimensions($data);
    3. // $result == 2
    4.  
    5. $data = ['1' => ['1.1' => '1.1.1'], '2', '3' => ['3.1' => ['3.1.1' => '3.1.1.1']]];
    6. $result = Hash::maxDimensions($data);
    7. // $result == 3
    • static Cake\Utility\Hash::map(array $data, $path, $function)
    • Creates a new array, by extracting $path, and mapping $functionacross the results. You can use both expression and matching elements withthis method:
    1. // Call the noop function $this->noop() on every element of $data
    2. $result = Hash::map($data, "{n}", [$this, 'noop']);
    3.  
    4. public function noop(array $array)
    5. {
    6. // Do stuff to array and return the result
    7. return $array;
    8. }
    • static Cake\Utility\Hash::reduce(array $data, $path, $function)
    • Creates a single value, by extracting $path, and reducing the extractedresults with $function. You can use both expression and matching elementswith this method.

    • static Cake\Utility\Hash::apply(array $data, $path, $function)

    • Apply a callback to a set of extracted values using $function. The functionwill get the extracted values as the first argument:
    1. $data = [
    2. ['date' => '01-01-2016', 'booked' => true],
    3. ['date' => '01-01-2016', 'booked' => false],
    4. ['date' => '02-01-2016', 'booked' => true]
    5. ];
    6. $result = Hash::apply($data, '{n}[booked=true].date', 'array_count_values');
    7. /* $result now looks like:
    8. [
    9. '01-01-2016' => 1,
    10. '02-01-2016' => 1,
    11. ]
    12. */
    • static Cake\Utility\Hash::sort(array $data, $path, $dir, $type = 'regular')
    • Sorts an array by any value, determined by a Hash Path SyntaxOnly expression elements are supported by this method:
    1. $a = [
    2. 0 => ['Person' => ['name' => 'Jeff']],
    3. 1 => ['Shirt' => ['color' => 'black']]
    4. ];
    5. $result = Hash::sort($a, '{n}.Person.name', 'asc');
    6. /* $result now looks like:
    7. [
    8. [0] => [
    9. [Shirt] => [
    10. [color] => black
    11. ]
    12. ]
    13. [1] => [
    14. [Person] => [
    15. [name] => Jeff
    16. ]
    17. ]
    18. ]
    19. */

    $dir can be either asc or desc. $typecan be one of the following values:

    • regular for regular sorting.
    • numeric for sorting values as their numeric equivalents.
    • string for sorting values as their string value.
    • natural for sorting values in a human friendly way. Willsort foo10 below foo2 as an example.
      • static Cake\Utility\Hash::diff(array $data, array $compare)
      • Computes the difference between two arrays:
    1. $a = [
    2. 0 => ['name' => 'main'],
    3. 1 => ['name' => 'about']
    4. ];
    5. $b = [
    6. 0 => ['name' => 'main'],
    7. 1 => ['name' => 'about'],
    8. 2 => ['name' => 'contact']
    9. ];
    10.  
    11. $result = Hash::diff($a, $b);
    12. /* $result now looks like:
    13. [
    14. [2] => [
    15. [name] => contact
    16. ]
    17. ]
    18. */
    • static Cake\Utility\Hash::mergeDiff(array $data, array $compare)
    • This function merges two arrays and pushes the differences indata to the bottom of the resultant array.

    Example 1

    1. $array1 = ['ModelOne' => ['id' => 1001, 'field_one' => 'a1.m1.f1', 'field_two' => 'a1.m1.f2']];
    2. $array2 = ['ModelOne' => ['id' => 1003, 'field_one' => 'a3.m1.f1', 'field_two' => 'a3.m1.f2', 'field_three' => 'a3.m1.f3']];
    3. $res = Hash::mergeDiff($array1, $array2);
    4.  
    5. /* $res now looks like:
    6. [
    7. [ModelOne] => [
    8. [id] => 1001
    9. [field_one] => a1.m1.f1
    10. [field_two] => a1.m1.f2
    11. [field_three] => a3.m1.f3
    12. ]
    13. ]
    14. */
    1. $array1 = ["a" => "b", 1 => 20938, "c" => "string"];
    2. $array2 = ["b" => "b", 3 => 238, "c" => "string", ["extra_field"]];
    3. $res = Hash::mergeDiff($array1, $array2);
    4. /* $res now looks like:
    5. [
    6. [a] => b
    7. [1] => 20938
    8. [c] => string
    9. [b] => b
    10. [3] => 238
    11. [4] => [
    12. [0] => extra_field
    13. ]
    14. ]
    15. */
    • static Cake\Utility\Hash::normalize(array $data, $assoc = true)
    • Normalizes an array. If $assoc is true, the resulting array will benormalized to be an associative array. Numeric keys with values, will beconverted to string keys with null values. Normalizing an array, makes usingthe results with Hash::merge() easier:
    • static Cake\Utility\Hash::nest(array $data, array $options = [])
    • Takes a flat array set, and creates a nested, or threaded data structure.

    Options:

    • children The key name to use in the result set for children. Defaultsto ‘children’.
    • idPath The path to a key that identifies each entry. Should becompatible with Hash::extract(). Defaults to {n}.$alias.id
    • parentPath The path to a key that identifies the parent of each entry.Should be compatible with . Defaults to {n}.$alias.parent_id
    • The id of the desired top-most result.
      For example, if you had the following array of data:
    1. $data = [
    2. ['ThreadPost' => ['id' => 1, 'parent_id' => null]],
    3. ['ThreadPost' => ['id' => 2, 'parent_id' => 1]],
    4. ['ThreadPost' => ['id' => 3, 'parent_id' => 1]],
    5. ['ThreadPost' => ['id' => 4, 'parent_id' => 1]],
    6. ['ThreadPost' => ['id' => 5, 'parent_id' => 1]],
    7. ['ThreadPost' => ['id' => 6, 'parent_id' => null]],
    8. ['ThreadPost' => ['id' => 7, 'parent_id' => 6]],
    9. ['ThreadPost' => ['id' => 8, 'parent_id' => 6]],
    10. ['ThreadPost' => ['id' => 9, 'parent_id' => 6]],
    11. ['ThreadPost' => ['id' => 10, 'parent_id' => 6]]
    12. ];
    13.  
    14. $result = Hash::nest($data, ['root' => 6]);
    15. /* $result now looks like:
    16. [
    17. (int) 0 => [
    18. 'ThreadPost' => [
    19. 'id' => (int) 6,
    20. 'parent_id' => null
    21. ],
    22. 'children' => [
    23. (int) 0 => [
    24. 'ThreadPost' => [
    25. 'id' => (int) 7,
    26. 'parent_id' => (int) 6
    27. ],
    28. 'children' => []
    29. ],
    30. (int) 1 => [
    31. 'ThreadPost' => [
    32. 'id' => (int) 8,
    33. 'parent_id' => (int) 6
    34. ],
    35. 'children' => []
    36. ],
    37. (int) 2 => [
    38. 'ThreadPost' => [
    39. 'id' => (int) 9,
    40. 'parent_id' => (int) 6
    41. ],
    42. 'children' => []
    43. ],
    44. (int) 3 => [
    45. 'ThreadPost' => [
    46. 'id' => (int) 10,
    47. 'parent_id' => (int) 6
    48. ],
    49. 'children' => []
    50. ]
    51. ]
    52. ]
    53. ]