Nouveau dans la version 2.2.
La gestion du tableau, si elle est bien faite, peut être un outil très puissant et utile pour construire du code plus intelligent et plus optimisé. CakePHP offre un ensemble d’utilitaires statiques très utile dans la classe Hash qui vous permet de faire justement cela.
La classe Hash de CakePHP peut être appelée à partir de n’importe quel
model ou controller de la même façon que pour un appel à Inflector
Exemple: Hash::combine()
.
La syntaxe de chemin décrite ci-dessous est utilisée par toutes les méthodes
dans Hash
. Les parties de la syntaxe du chemin ne sont pas toutes
disponibles dans toutes les méthodes. Une expression en chemin est faite
depuis n’importe quel nombre de tokens. Les Tokens sont composés de deux
groupes. Les Expressions sont utilisées pour parcourir le tableau de données,
alors que les matchers sont utilisés pour qualifier les éléments. Vous
appliquez les matchers aux éléments de l’expression.
Expression |
Définition |
---|---|
|
Représente une clé numérique. Va matcher toute chaîne ou clé numérique. |
|
Représente une chaîne. Va matcher toute valeur de chaîne y compris les valeurs de chaîne numérique. |
|
Représente n’importe quelle valeur, quel que soit le type. |
|
Matche les clés avec exactement la même valeur keys with the exact same value. |
Tous les éléments d’expression supportent toutes les méthodes. En plus des
éléments d’expression, vous pouvez utiliser les attributs qui matchent avec
certaines méthodes. Il y a extract()
, combine()
, format()
,
check()
, map()
, reduce()
, apply()
, sort()
, insert()
,
remove()
et nest()
.
Matcher |
Definition |
---|---|
|
Match les éléments avec une clé de tableau donnée. |
|
Match les éléments avec un id égal à 2. |
|
Match les éléments avec un id non égal à 2. |
|
Match les éléments avec un id supérieur à 2. |
|
Match les éléments avec un id supérieur ou égal à 2. |
|
Match les éléments avec un id inférieur à 2. |
|
Match les éléments avec un id inférieur ou égal à 2. |
|
Match les éléments qui ont des valeurs
matchant avec l’expression régulière
à l’intérieur de |
Modifié dans la version 2.5: Le support des matcher a été ajouté dans insert()
et remove()
.
mixed
get()
est une version simplifiée de extract()
, elle ne supporte
que les expressions de chemin direct. Les chemins avec {n}
, {s}
ou les matchers ne sont pas supportés. Utilisez get()
quand vous
voulez exactement une valeur sortie d’un tableau. Le troisième paramètre
sera retourné si le chemin demandé n’a pas été trouvé dans le tableau.
Modifié dans la version 2.5: Le troisième argument $default = null
optionel a été ajouté.
array
Hash::extract()
supporte toutes les expressions, les components
matcher de la Syntaxe de chemin Hash. Vous pouvez utiliser l’extract pour
récupérer les données à partir des tableaux, le long des chemins
arbitraires rapidement sans avoir à parcourir les structures de données.
A la place, vous utilisez les expressions de chemin pour qualifier
les éléments que vous souhaitez retourner:
// Utilisation habituelle:
$users = $this->User->find("all");
$results = Hash::extract($users, '{n}.User.id');
// $results égal à:
// array(1,2,3,4,5,...);
array
Insère $data dans un tableau tel que défini dans $path
:
$a = array(
'pages' => array('name' => 'page')
);
$result = Hash::insert($a, 'files', array('name' => 'files'));
// $result ressemble maintenant à:
Array
(
[pages] => Array
(
[name] => page
)
[files] => Array
(
[name] => files
)
)
Vous pouvez utiliser les chemins en utilisant {n}
et {s}
pour
insérer des données dans des points multiples:
$users = $this->User->find('all');
$users = Set::insert($users, '{n}.User.new', 'value');
Modifié dans la version 2.5: Depuis 2.5.0, les expressions matchant l’attribut fonctionnent avec insert().
array
Retire tous les éléments d’un tableau qui matche avec $path.
$a = array(
'pages' => array('name' => 'page'),
'files' => array('name' => 'files')
);
$result = Hash::remove($a, 'files');
/* $result ressemble maintenant à:
Array
(
[pages] => Array
(
[name] => page
)
)
*/
L’utilisation de {n}
et {s}
vous autorisera à retirer les valeurs
multiples en une fois.
Modifié dans la version 2.5: Depuis 2.5.0, les expressions matchant l’attribut fonctionnent avec remove()
array
Crée un tableau associatif en utilisant $keyPath en clé pour le chemin à construire, et optionnellement $valuePath comme chemin pour récupérer les valeurs. Si $valuePath n’est pas spécifiée, ou ne matche rien, les valeurs seront initialisées à null. Vous pouvez grouper en option les valeurs par ce qui est obtenu en suivant le chemin spécifié dans $groupPath.
$a = array(
array(
'User' => array(
'id' => 2,
'group_id' => 1,
'Data' => array(
'user' => 'mariano.iglesias',
'name' => 'Mariano Iglesias'
)
)
),
array(
'User' => array(
'id' => 14,
'group_id' => 2,
'Data' => array(
'user' => 'phpnut',
'name' => 'Larry E. Masters'
)
)
),
);
$result = Hash::combine($a, '{n}.User.id');
/* $result ressemble maintenant à:
Array
(
[2] =>
[14] =>
)
*/
$result = Hash::combine($a, '{n}.User.id', '{n}.User.Data');
/* $result ressemble maintenant à:
Array
(
[2] => Array
(
[user] => mariano.iglesias
[name] => Mariano Iglesias
)
[14] => Array
(
[user] => phpnut
[name] => Larry E. Masters
)
)
*/
$result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.name');
/* $result ressemble maintenant à:
Array
(
[2] => Mariano Iglesias
[14] => Larry E. Masters
)
*/
$result = Hash::combine($a, '{n}.User.id', '{n}.User.Data', '{n}.User.group_id');
/* $result ressemble maintenant à:
Array
(
[1] => Array
(
[2] => Array
(
[user] => mariano.iglesias
[name] => Mariano Iglesias
)
)
[2] => Array
(
[14] => Array
(
[user] => phpnut
[name] => Larry E. Masters
)
)
)
*/
$result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.name', '{n}.User.group_id');
/* $result ressemble maintenant à:
Array
(
[1] => Array
(
[2] => Mariano Iglesias
)
[2] => Array
(
[14] => Larry E. Masters
)
)
*/
Vous pouvez fournir des tableaux pour les deux $keyPath et $valuePath. Si vous le faîte, la première valeur sera utilisée comme un format de chaîne de caractères, pour les valeurs extraites par les autres chemins:
$result = Hash::combine(
$a,
'{n}.User.id',
array('%s: %s', '{n}.User.Data.user', '{n}.User.Data.name'),
'{n}.User.group_id'
);
/* $result ressemble maintenant à:
Array
(
[1] => Array
(
[2] => mariano.iglesias: Mariano Iglesias
)
[2] => Array
(
[14] => phpnut: Larry E. Masters
)
)
*/
$result = Hash::combine(
$a,
array('%s: %s', '{n}.User.Data.user', '{n}.User.Data.name'),
'{n}.User.id'
);
/* $result ressemble maintenant à:
Array
(
[mariano.iglesias: Mariano Iglesias] => 2
[phpnut: Larry E. Masters] => 14
)
*/
array
Retourne une série de valeurs extraites d’un tableau, formaté avec un format de chaîne de caractères:
$data = array(
array(
'Person' => array(
'first_name' => 'Nate',
'last_name' => 'Abele',
'city' => 'Boston',
'state' => 'MA',
'something' => '42'
)
),
array(
'Person' => array(
'first_name' => 'Larry',
'last_name' => 'Masters',
'city' => 'Boondock',
'state' => 'TN',
'something' => '{0}'
)
),
array(
'Person' => array(
'first_name' => 'Garrett',
'last_name' => 'Woodworth',
'city' => 'Venice Beach',
'state' => 'CA',
'something' => '{1}'
)
)
);
$res = Hash::format($data, array('{n}.Person.first_name', '{n}.Person.something'), '%2$d, %1$s');
/*
Array
(
[0] => 42, Nate
[1] => 0, Larry
[2] => 0, Garrett
)
*/
$res = Hash::format($data, array('{n}.Person.first_name', '{n}.Person.something'), '%1$s, %2$d');
/*
Array
(
[0] => Nate, 42
[1] => Larry, 0
[2] => Garrett, 0
)
*/
boolean
Détermine si un Hash ou un tableau contient les clés et valeurs exactes d’un autre:
$a = array(
0 => array('name' => 'main'),
1 => array('name' => 'about')
);
$b = array(
0 => array('name' => 'main'),
1 => array('name' => 'about'),
2 => array('name' => 'contact'),
'a' => 'b'
);
$result = Hash::contains($a, $a);
// true
$result = Hash::contains($a, $b);
// false
$result = Hash::contains($b, $a);
// true
- rtype
boolean
Vérifie si un chemin particulier est défini dans un tableau:
$set = array(
'My Index 1' => array('First' => 'The first item')
);
$result = Hash::check($set, 'My Index 1.First');
// $result == True
$result = Hash::check($set, 'My Index 1');
// $result == True
$set = array(
'My Index 1' => array('First' =>
array('Second' =>
array('Third' =>
array('Fourth' => 'Heavy. Nesting.'))))
);
$result = Hash::check($set, 'My Index 1.First.Second');
// $result == True
$result = Hash::check($set, 'My Index 1.First.Second.Third');
// $result == True
$result = Hash::check($set, 'My Index 1.First.Second.Third.Fourth');
// $result == True
$result = Hash::check($set, 'My Index 1.First.Seconds.Third.Fourth');
// $result == False
array
Filtre les éléments vides en dehors du tableau, en excluant “0”. Vous
pouvez aussi fournir un $callback personnalisé pour filtrer les éléments
de tableau. Votre callback devrait retourner false
pour retirer
les éléments du tableau résultant:
$data = array(
'0',
false,
true,
0,
array('one thing', 'I can tell you', 'is you got to be', false)
);
$res = Hash::filter($data);
/* $data ressemble maintenant à:
Array (
[0] => 0
[2] => true
[3] => 0
[4] => Array
(
[0] => one thing
[1] => I can tell you
[2] => is you got to be
)
)
*/
array
Réduit un tableau multi-dimensionnel en un tableau à une seule dimension:
$arr = array(
array(
'Post' => array('id' => '1', 'title' => 'First Post'),
'Author' => array('id' => '1', 'user' => 'Kyle'),
),
array(
'Post' => array('id' => '2', 'title' => 'Second Post'),
'Author' => array('id' => '3', 'user' => 'Crystal'),
),
);
$res = Hash::flatten($arr);
/* $res ressemble maintenant à:
Array (
[0.Post.id] => 1
[0.Post.title] => First Post
[0.Author.id] => 1
[0.Author.user] => Kyle
[1.Post.id] => 2
[1.Post.title] => Second Post
[1.Author.id] => 3
[1.Author.user] => Crystal
)
*/
array
Développe un tableau qui a déjà été aplatie avec
Hash::flatten()
:
$data = array(
'0.Post.id' => 1,
'0.Post.title' => First Post,
'0.Author.id' => 1,
'0.Author.user' => Kyle,
'1.Post.id' => 2,
'1.Post.title' => Second Post,
'1.Author.id' => 3,
'1.Author.user' => Crystal,
);
$res = Hash::expand($data);
/* $res ressemble maintenant à:
array(
array(
'Post' => array('id' => '1', 'title' => 'First Post'),
'Author' => array('id' => '1', 'user' => 'Kyle'),
),
array(
'Post' => array('id' => '2', 'title' => 'Second Post'),
'Author' => array('id' => '3', 'user' => 'Crystal'),
),
);
*/
array
Cette fonction peut être vue comme un hybride entre le array_merge
et
le array_merge_recursive
de PHP. La différence entre les deux est que
si une clé du tableau contient un autre tableau, alors la fonction se
comporte de façon récursive (pas comme array_merge
) mais ne le fait
pas pour les clés contenant les chaînes de caractères (pas comme
array_merge_recursive
).
Note
Cette fonction va fonctionner avec un montant illimité d’arguments et convertit les paramètres de non-tableau en tableaux.
$array = array(
array(
'id' => '48c2570e-dfa8-4c32-a35e-0d71cbdd56cb',
'name' => 'mysql raleigh-workshop-08 < 2008-09-05.sql ',
'description' => 'Importing an sql dump'
),
array(
'id' => '48c257a8-cf7c-4af2-ac2f-114ecbdd56cb',
'name' => 'pbpaste | grep -i Unpaid | pbcopy',
'description' => 'Remove all lines that say "Unpaid".',
)
);
$arrayB = 4;
$arrayC = array(0 => "test array", "cats" => "dogs", "people" => 1267);
$arrayD = array("cats" => "felines", "dog" => "angry");
$res = Hash::merge($array, $arrayB, $arrayC, $arrayD);
/* $res ressemble maintenant à:
Array
(
[0] => Array
(
[id] => 48c2570e-dfa8-4c32-a35e-0d71cbdd56cb
[name] => mysql raleigh-workshop-08 < 2008-09-05.sql
[description] => Importing an sql dump
)
[1] => Array
(
[id] => 48c257a8-cf7c-4af2-ac2f-114ecbdd56cb
[name] => pbpaste | grep -i Unpaid | pbcopy
[description] => Remove all lines that say "Unpaid".
)
[2] => 4
[3] => test array
[cats] => felines
[people] => 1267
[dog] => angry
)
*/
boolean
Vérifie pour voir si toutes les valeurs dans le tableau sont numériques:
$data = array('one');
$res = Hash::numeric(array_keys($data));
// $res est à true
$data = array(1 => 'one');
$res = Hash::numeric($data);
// $res est à false
integer
Compte les dimensions d’un tableau. Cette méthode va seulement considérer la dimension du premier élément dans le tableau:
$data = array('one', '2', 'three');
$result = Hash::dimensions($data);
// $result == 1
$data = array('1' => '1.1', '2', '3');
$result = Hash::dimensions($data);
// $result == 1
$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => '3.1.1'));
$result = Hash::dimensions($data);
// $result == 2
$data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
$result = Hash::dimensions($data);
// $result == 1
$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
$result = Hash::dimensions($data);
// $result == 2
Similaire à dimensions()
, cependant cette méthode
retourne le nombre le plus profond de dimensions de tout élément dans
le tableau:
$data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
$result = Hash::maxDimensions($data, true);
// $result == 2
$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
$result = Hash::maxDimensions($data, true);
// $result == 3
Crée un nouveau tableau, en extrayant $path, et mappe $function à travers les résultats. Vous pouvez utiliser les deux, expression et le matching d’éléments avec cette méthode:
//appel de la fonction noop $this->noop() sur chaque element de $data
$result = Hash::map($data, "{n}", array($this, 'noop'));
function noop($array) {
//fait des trucs au tableau et retourne les résultats
return $array;
}
Crée une valeur unique, en extrayant $path, et en réduisant les résultats extraits avec $function. Vous pouvez utiliser les deux, expression et le matching d’éléments avec cette méthode.
Appliquer un callback à un ensemble de valeurs extraites en utilisant $function. La fonction va récupérer les valeurs extraites en premier argument.
array
Trie un tableau selon n’importe quelle valeur, déterminé par une Syntaxe de chemin Hash. Seuls les éléments de type expression sont supportés par cette méthode:
$a = array(
0 => array('Person' => array('name' => 'Jeff')),
1 => array('Shirt' => array('color' => 'black'))
);
$result = Hash::sort($a, '{n}.Person.name', 'asc');
/* $result ressemble maintenant à:
Array
(
[0] => Array
(
[Shirt] => Array
(
[color] => black
)
)
[1] => Array
(
[Person] => Array
(
[name] => Jeff
)
)
)
*/
$dir
peut être soit asc
, soit desc`. Le ``$type
peut être une des valeurs suivantes:
regular
pour le trier régulier.
numeric
pour le tri des valeurs avec leurs valeurs numériques
équivalentes.
string
pour le tri des valeurs avec leur valeur de chaîne.
natural
pour trier les valeurs d’une façon humaine. Va trier
foo10
en-dessous de foo2
par exemple. Le tri naturel
a besoin de PHP 5.4 ou supérieur.
Nouveau dans la version 2.8: L’option $type
accepte maintenant un tableau et l’option ignoreCase
active le tri sans sensibilité à la casse.
array
Calcule la différence entre deux tableaux:
$a = array(
0 => array('name' => 'main'),
1 => array('name' => 'about')
);
$b = array(
0 => array('name' => 'main'),
1 => array('name' => 'about'),
2 => array('name' => 'contact')
);
$result = Hash::diff($a, $b);
/* $result ressemble maintenant à:
Array
(
[2] => Array
(
[name] => contact
)
)
*/
array
Cette fonction fusionne les deux tableaux et pousse les différences dans les données à la fin du tableau résultant.
Exemple 1
$array1 = array('ModelOne' => array('id' => 1001, 'field_one' => 'a1.m1.f1', 'field_two' => 'a1.m1.f2'));
$array2 = array('ModelOne' => array('id' => 1003, 'field_one' => 'a3.m1.f1', 'field_two' => 'a3.m1.f2', 'field_three' => 'a3.m1.f3'));
$res = Hash::mergeDiff($array1, $array2);
/* $res ressemble maintenant à:
Array
(
[ModelOne] => Array
(
[id] => 1001
[field_one] => a1.m1.f1
[field_two] => a1.m1.f2
[field_three] => a3.m1.f3
)
)
*/
Exemple 2
$array1 = array("a" => "b", 1 => 20938, "c" => "string");
$array2 = array("b" => "b", 3 => 238, "c" => "string", array("extra_field"));
$res = Hash::mergeDiff($array1, $array2);
/* $res ressemble maintenant à:
Array
(
[a] => b
[1] => 20938
[c] => string
[b] => b
[3] => 238
[4] => Array
(
[0] => extra_field
)
)
*/
array
Normalise un tableau. Si $assoc
est à true, le tableau résultant
sera normalisé en un tableau associatif. Les clés numériques avec les
valeurs, seront convertis en clés de type chaîne avec des valeurs null.
Normaliser un tableau, facilite l’utilisation des résultats avec
Hash::merge()
:
$a = array('Tree', 'CounterCache',
'Upload' => array(
'folder' => 'products',
'fields' => array('image_1_id', 'image_2_id')
)
);
$result = Hash::normalize($a);
/* $result ressemble maintenant à:
Array
(
[Tree] => null
[CounterCache] => null
[Upload] => Array
(
[folder] => products
[fields] => Array
(
[0] => image_1_id
[1] => image_2_id
)
)
)
*/
$b = array(
'Cacheable' => array('enabled' => false),
'Limit',
'Bindable',
'Validator',
'Transactional'
);
$result = Hash::normalize($b);
/* $result ressemble maintenant à:
Array
(
[Cacheable] => Array
(
[enabled] => false
)
[Limit] => null
[Bindable] => null
[Validator] => null
[Transactional] => null
)
*/
Prend un ensemble de tableau aplati, et crée une structure de données
imbriquée ou chaînée. Utilisé par des méthodes comme
Model::find('threaded')
.
Options:
children
Le nom de la clé à utiliser dans l’ensemble de résultat
pour les enfants. Par défaut à “children”.
idPath
Le chemin vers une clé qui identifie chaque entrée. Doit être
compatible avec Hash::extract()
. Par défaut à
{n}.$alias.id
parentPath
Le chemin vers une clé qui identifie le parent de chaque
entrée. Doit être compatible avec Hash::extract()
. Par défaut
à {n}.$alias.parent_id
.
root
L’id du résultat le plus désiré.
Exemple:
$data = array(
array('ModelName' => array('id' => 1, 'parent_id' => null)),
array('ModelName' => array('id' => 2, 'parent_id' => 1)),
array('ModelName' => array('id' => 3, 'parent_id' => 1)),
array('ModelName' => array('id' => 4, 'parent_id' => 1)),
array('ModelName' => array('id' => 5, 'parent_id' => 1)),
array('ModelName' => array('id' => 6, 'parent_id' => null)),
array('ModelName' => array('id' => 7, 'parent_id' => 6)),
array('ModelName' => array('id' => 8, 'parent_id' => 6)),
array('ModelName' => array('id' => 9, 'parent_id' => 6)),
array('ModelName' => array('id' => 10, 'parent_id' => 6))
);
$result = Hash::nest($data, array('root' => 6));
/* $result ressemble maintenant à:
array(
(int) 0 => array(
'ModelName' => array(
'id' => (int) 6,
'parent_id' => null
),
'children' => array(
(int) 0 => array(
'ModelName' => array(
'id' => (int) 7,
'parent_id' => (int) 6
),
'children' => array()
),
(int) 1 => array(
'ModelName' => array(
'id' => (int) 8,
'parent_id' => (int) 6
),
'children' => array()
),
(int) 2 => array(
'ModelName' => array(
'id' => (int) 9,
'parent_id' => (int) 6
),
'children' => array()
),
(int) 3 => array(
'ModelName' => array(
'id' => (int) 10,
'parent_id' => (int) 6
),
'children' => array()
)
)
)
)
*/