使用php

时间:2019-01-20 00:13:59

标签: php mysql sql

我有一个包含以下列的表:

contest_id, exhibition_id, username, files

files包含我放置在数据库中时已序列化的图片,因为它们是多个文件。 files列看起来像这样

"a:3:{i:0;s:9:"10210.PNG";i:1;s:9:"99073.PNG";i:2;s:9:"89321.PNG";}"

我使用PHP执行了此SQL语句

$a = mysqli_query($this->con, "SELECT username,  GROUP_CONCAT(files) files from my_exhibition_contests WHERE exhibition_id='$id'");

并继续用PHP编写

$s=$a->fetch_all(MYSQLI_ASSOC); 
foreach ($s as &$row) {
    $row['files'] = unserialize($row['files']); 
}
echo json_encode($s);

然后我使用angularjs在前端收集了它。 我使用了GROUP_CONCAT(files),以便按用户名对其进行分组,并将具有该用户名的所有文件放在一行中。 问题是使用foreach ($s as &$row)违反了GROUP_CONCAT(files)的目的,它只能带来一种结果,就像我使用GROUP BY一样,但是在删除foreach ($s as &$row)时,它可以我想要的方式(即,将具有特定用户名的文件中的所有行打包在别名为files的单列中),但是文件的每个索引中的值都以字符串格式序列化。 我如何反序列化files数组中的每个索引。 让我举这个例子,假设表的第一行是这样的

contest_id: 1 exhibition_id: 5 username: John files: "a:3:{i:0;s:9:"10210.PNG";i:1;s:9:"99073.PNG";i:2;s:9:"89321.PNG";}"

第二行就是这样

contest_id: 2 exhibition_id: 5 username John: files: "a:3:{i:0;s:9:"33937.PNG";i:1;s:9:"26831.PNG";i:2;s:8:"6316.PNG";}"

当我移除foreach后,我明白了

username: John files: "a:3:{i:0;s:9:"10210.PNG";i:1;s:9:"99073.PNG";i:2;s:9:"89321.PNG";},a:3:{i:0;s:9:"33937.PNG";i:1;s:9:"26831.PNG";i:2;s:8:"6316.PNG";}"

它将所有内容都放在一个单列文件中,这是我想要的,但问题是它是以字符串格式序列化的。

当我放置foreach行时,我明白了

username: John files : ["10210.PNG", "99073.PNG", "89321.PNG"]

这是一种数组格式,正是我想要的,但是它只带来了第一行,我如何才能做到这一点,使它成为数组格式,却带来所有行?

1 个答案:

答案 0 :(得分:0)

您的问题是,您需要先对GROUP_CONCAT的文件列表进行分解,然后再对它们进行反序列化,然后合并所有结果。这应该起作用:

$s=$a->fetch_all(MYSQLI_ASSOC);
foreach ($s as &$row) { 
    $files = array();
    foreach (preg_split('/}(,|$)/', $row['files'], -1, PREG_SPLIT_NO_EMPTY) as $filelist) {
        $files = array_merge($files, unserialize($filelist . '}')); 
    } 
    $row['files'] = $files;
}
echo json_encode($s);

Demo of splitting code on 3v4l.org

注意

我们必须使用preg_split来拆分数据,因为序列化数据中也有逗号。如果您更改查询以使用其他分隔符,则分隔符将不会出现在文件名之一中,例如

$a = mysqli_query($this->con, "SELECT username,  GROUP_CONCAT(files SEPARATOR '#') files from my_exhibition_contests WHERE exhibition_id='$id'");

然后您可以用

替换preg_split
explode('#', $row['files'])

这还将消除在反序列化之前将}拆分字符添加回$filelist的需要。