PHP array_unique返回重复

时间:2016-10-20 17:49:53

标签: php mysql

这是我的表tracks

+---+--------------------+
| id|                 tag|
+---+--------------------+
| 1 |              dance,|
| 2 |        dance,tecno,|
| 3 |        dance,hihop,|
| 4 |                rap,|
| 5 |            country,|
| . |                 ...|
+---+--------------------+

我试过这个($value是我的查询):

$tags = $this->db->query(sprintf("SELECT `tag`, `id` FROM `tracks` WHERE `tag` LIKE '%s' GROUP BY `tag` DESC LIMIT %s, %s", '%'.$this->db->real_escape_string($value).'%', $this->db->real_escape_string($start), $per_page));

while($row = $tags->fetch_assoc()) {
    $rows[] = $row;
}

$tags = explode(',', $row['tag']);
$rows = array_unique(array_map('strtolower', $tags));

foreach($rows as $row) {
    if(stripos($row, $value) !== false) {
        $tag_output .= '<div class="hashtag-inner">
                            '.$row.'
                        </div>';
    }
}

从这个例子。预期的输出为dance, tecno, hiphop, rap, country,其中包含所有唯一标记,而我的标记dance有多个输出。 我的输出有什么问题?

2 个答案:

答案 0 :(得分:1)

您需要在处理每一行的循环中调用explode()。你的代码只是爆炸了最后一行。

$rows = array();
while ($row = $tags->fetch_assoc()) {
    $tags = explode(',', $row['tag']);
    $rows = array_merge($rows, $tags);
}
$rows = array_unique(array_map('strtolower', array_filter($rows)));

array_filter()用于删除来自标记列表末尾的,的空字符串。

但是,最好的长期解决方案是规范化数据库架构,这样就不会在表中存储以逗号分隔的列表。你应该有一个表格,每个标签都在一个单独的行中。

答案 1 :(得分:0)

我认为你需要这样的东西

$tags = $this->db->query(sprintf("SELECT `tag`, `id` FROM `tracks` WHERE `tag` LIKE '%s' GROUP BY `tag` DESC LIMIT %s, %s", '%'.$this->db->real_escape_string($value).'%', $this->db->real_escape_string($start), $per_page));

$str = '';
while($row = $tags->fetch_assoc()) {
    // combine all tags from "tag" column
    $str .= $row['tag'];
}

$tags = explode(',', $str);
$rows = array_unique(array_map('strtolower', $tags));

foreach($rows as $row) {
    if(stripos($row, $value) !== false) {
        $tag_output .= '<div class="hashtag-inner">
                            '.$row.'
                        </div>';
    }
}