0

我正在用 CakePHP(最新版本)编写一个标记系统,但与 CakePHP 的其余部分的简单程度相比,我所做的解决方案似乎过于复杂。希望有人可以为我指明正确的方向或帮助我改进当前的解决方案。

我需要以这种格式(JSON)传递给我的视图数据:

[{label:'actionscript', count: 14}, {label:'php', count: 2} ... ]

现在我知道以下 SQL 查询为我提供了所需的数据:

SELECT tags.name, count(*)
FROM tags
RIGHT JOIN tags_users
ON tags.id=tags_users.tag_id
GROUP BY name";

所以使用我制作的 CakePHP find 方法:

$options = array();
$options['contain'] = '';   
$options['recursive'] =  -1;            
$options['joins'][0]['table'] = 'tags_users';
$options['joins'][0]['type'] = 'RIGHT';
$options['joins'][0]['conditions'] = 'Tag.id = tags_users.tag_id';
$options['fields'] =  array('name', 'COUNT(*) as tag_counter');
$options['group']  =  'Tag.name';
$options['order']  =  'tag_counter DESC';       
$availableTagsArray = $this->User->TagsUser->Tag->find('all', $options);

这给了我一个数组:

Array
(
[0] => Array
    (
        [Tag] => Array
            (
                [name] => actionscript
            )

        [0] => Array
            (
                [tag_counter] => 14
            )

    )

[1] => Array
    (
        [Tag] => Array
            (
                [name] => php
            )

        [0] => Array
            (
                [tag_counter] => 2
            )

    )
)

然后我通过以下方式将此数组转换为 JSON:

$availableTags = "[";

foreach ($availableTagsArray as $tag) {
        $availableTags .= "{label:'{$tag['Tag']['name']}', count:{$tag[0]['tag_counter']}},";   
    }

$availableTags = substr($availableTags, 0, -1);
$availableTags .= "]";  
$this->set("availableTags", $availableTags);

[更新]

经过大量研究并使用这两个答案。我发现有多种方法可以做到这一点,其中包括我原来的解决方案。您还可以使用虚拟字段,然后使用 afterFind 方法并在那里展平结果。

4

2 回答 2

1

您无需编写自己的循环即可从数组中手动​​输出 JSON 字符串。PHP 已经有一个将数组编码为 JSON 的函数:

http://php.net/manual/en/function.json-encode.php

您只需要确保进入的数组具有正确的键,以便正确标记 JSON。


另请阅读正确设置模型关联,然后您可以使用containable查找选项中的行为来获取标签,而无需手动指定连接,这通常是混乱和复杂的。

于 2012-10-17T16:03:23.873 回答
1

您可以使用Containable Behavior来简化查询,并使用JSON 视图来简化输出。

于 2012-10-17T16:04:50.520 回答