【问题标题】:sorting serialized data in GROUP_CONCAT() using php使用 php 对 GROUP_CONCAT() 中的序列化数据进行排序
【发布时间】:2019-01-20 00:13:58
【问题描述】:

我有一个包含这些列的表格:

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"]

这是一个数组格式,正是我想要的,但它只带来了第一行,我怎样才能让它成为数组格式,但带来所有的行?

【问题讨论】:

    标签: php mysql sql


    【解决方案1】:

    您的问题是您需要分解GROUP_CONCAT'ed 文件列表反序列化它们,然后合并所有结果。这应该有效:

    $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 的需要。

    【讨论】:

    • 哇,这太棒了,正是我想要的。您还花时间解释并放弃了替代方案,我非常感谢您。
    • @atomty 很高兴能帮上忙。
    猜你喜欢
    • 2015-05-11
    • 2010-11-02
    • 2016-06-17
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    相关资源
    最近更新 更多