我在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查找方法:
$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);
[UPDATE]
经过大量研究并使用两个答案。我发现有多种方法可以做到这一点,包括我原来的解决方案。您也可以使用虚拟字段然后使用afterFind方法并在那里展平结果。
答案 0 :(得分:1)
您不需要编写自己的循环来手动从数组输出JSON字符串。 PHP已经有一个函数将数组编码为JSON:
http://php.net/manual/en/function.json-encode.php
您只需要确保进入的数组具有正确的键,以便正确标记JSON。
同时阅读setting up your model associations properly,然后您可以在查找选项中使用containable
行为来获取标记,而无需手动指定联接,这通常是混乱和复杂的。
答案 1 :(得分:1)
您可以使用Containable Behavior来简化查询,使用JSON view来简化输出。