Функция CakePHP для преобразования точечных массивов в многомерные - PullRequest
2 голосов
/ 17 ноября 2009

В CakePHP кажется, что многие функции могут принимать свои аргументы в виде вложенных, многомерных массивов или в виде пунктирных строк:

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

Следовательно, я полагаю, что где-то в ядре должна быть функция для переключения с точечной на вложенную ассоциативную, но я не могу найти ее на всю жизнь. Есть идеи?

Ответы [ 4 ]

8 голосов
/ 17 ноября 2009

Я на самом деле придумал, как добиться этого, используя встроенные функции Set.

Дано:

$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',
);

Этот код поместит это во вложенный ассоциативный массив.

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

Вот документы для Set::insert()

2 голосов
/ 17 ноября 2009

То, что вы ищете, это Set :: flatten (). Это не задокументировано в руководстве CakePHP, но посмотрите на определение API .

Это работает примерно так (результат может быть не точным, это из моей головы):

$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);

Ваша переменная $array теперь будет выглядеть так:

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 голосов
/ 27 июня 2012

Отличный вопрос, я просто искал то же самое. Судя по всему, это будет в Cake 2.2.

Новый класс Hash (новая, улучшенная версия класса Set) имеет функцию expand(), которая делает это. Вы можете просмотреть код на Github, если вам нужно использовать его в это время:

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

... Однако опубликованное nickf решение тоже прекрасно работает. : -)

0 голосов
/ 17 ноября 2009

Это всего лишь соглашение по всему Cake, но каждая часть выполняет собственный, настраиваемый анализ. Если вы посмотрите на функцию ContainableBehavior::containments() в cake/libs/model/behaviors/containable.php, вы увидите, что происходит много preg_matching и explode('.')ing. По крайней мере, в случае Containable, подробный синтаксис array('name' => array(...)) представляется каноническим синтаксисом, но его можно сокращать с помощью синтаксиса с точками, который будет только расширен. Я предполагаю, что само расширение слишком различно для разных частей, чтобы его можно было легко обобщить в центральной функции.

Это, или они просто еще не дошли до этого. :)

...