2009-11-17 3 views
2

En CakePHP, il semble que beaucoup de fonctions peuvent prendre leurs arguments imbriqués, des tableaux multidimensionnels, ou sous forme de chaînes en pointillés:CakePHP fonction pour convertir des tableaux en pointillés à multidimensionnelle

$this->MyModel->contain(array(
    'Something', 'Something.Else', 'Something.Else.Entirely' 
)); 
$this->MyModel->contain(array(
    'Something' => array(
     'Else' => 'Entirely' 
    ) 
)); 

Par conséquent, je figure il doit y avoir une fonction quelque part dans le noyau pour passer de l'associatif pointé à l'associatif imbriqué, mais je ne peux pas le trouver pour la vie de moi. Des idées?

Répondre

8

J'ai En fait, j'ai pensé à ma propre façon de faire fonctionner ce travail en utilisant les fonctions Set intégrées.

Étant donné:

$input = array (
    'Post.id' => 1, 
    'Post.title' => 'Some post title.', 
    'Post.Tag.0.id' => 4, 
    'Post.Tag.0.name' => 'cakephp', 
    'Post.Tag.1.id' => 7, 
    'Post.Tag.1.name' => 'mysql', 
); 

Ce code va mettre cela dans un tableau associatif imbriqué.

$output = array(); 
foreach ($input as $key => $value) { 
    $output = Set::insert($output, $key, $value); 
} 

est ici les docs pour Set::insert()

0

C'est juste une convention dans Cake, mais chaque partie fait son propre analyse personnalisée. Si vous regardez la fonction ContainableBehavior::containments() dans cake/libs/model/behaviors/containable.php, vous verrez beaucoup de preg_matching et explode('.')ing en cours. Au moins dans le cas de Containable, la syntaxe verbale array('name' => array(...)) semble être la syntaxe canonique, mais elle peut être abrégée avec la syntaxe de point, qui sera simplement développée. Je suppose que l'expansion elle-même est trop variée entre les différentes parties pour être facilement résumée dans une fonction centrale.

Cela, ou ils ne l'ont pas encore compris. :)

+0

deceze, je me retrouve à lire les messages de CakePHP sur SO juste pour que je puisse trouver quelque chose de nouveau. Ça arrive chaque fois que vous postez. Merci pour l'info addt'l, continuez votre bon travail! –

+0

En fait, j'apprends beaucoup des questions, c'est une relation mutuellement bénéfique. : -3 – deceze

2

Ce que vous cherchez est Set :: flatten(). Ce n'est pas documenté dans le manuel CakePHP, mais jetez un oeil à la API definition.

Il fonctionne quelque chose comme ça (le résultat pourrait ne pas être exacte, cela est de ma tête):

$array = array(
    'Post' => array(
     'id' => 1, 
     'title' => 'Some post title.', 
     'Tag' => array(
      0 => array(
       'id' => 4, 
       'name' => 'cakephp', 
      ), 
      1 => array(
       'id' => 7, 
       'name' => 'mysql', 
      ), 
     ), 
    ); 
); 

$array = Set::flatten($array); 
var_dump($array); 

votre variable $array ressemblera à ceci:

Array (
    'Post.id' => 1, 
    'Post.title' => 'Some post title.', 
    'Post.Tag.0.id' => 4, 
    'Post.Tag.0.name' => 'cakephp', 
    'Post.Tag.1.id' => 7, 
    'Post.Tag.1.name' => 'mysql', 
) 
+0

Merci Matt, malheureusement, j'ai vraiment besoin de l'exact opposé de cela. – nickf

+0

Ahh, désolé. J'ai mal lu la question. –

+1

Je suis content que vous avez mal posé la question ;-) C'était une fonctionnalité intéressante que je cherchais! – the0ther

0

Grande question, je recherche juste la même chose. Apparemment, ça vient dans le gâteau 2.2.

La nouvelle classe Hash (une nouvelle version améliorée de la classe Set) a une fonction expand() qui le fait. Vous pouvez afficher le code sur GitHub si vous devez l'utiliser dans l'intervalle:

https://github.com/cakephp/cakephp/blob/2.2/lib/Cake/Utility/Hash.php

... Cependant la solution nickf affichée fonctionne très bien, aussi. :-)