最直接方式是用explode()拆字符串,它按分隔符切分返回索引数组,但不处理空格、去重或嵌套;分隔符需精确匹配,空输入返回[""],不支持正则;json应使用json_decode(),表单多值须用name="xxx[]",禁用eval/unserialize()。

用 explode() 拆字符串是最直接的方式
PHP 里所谓“从变量中提取列表”,绝大多数情况是指:一个字符串变量(比如 $str = "apple,banana,cherry")要变成数组。这时候别想太复杂,explode() 就是为此生的。
它把字符串按分隔符切开,返回索引数组。注意它不处理空格、不自动去重、也不管嵌套结构。
- 分隔符必须精确匹配,
explode(", ", $str)和explode(",", $str)结果不同——后者可能让元素带前导空格 - 如果分隔符不存在,返回单元素数组:
explode(",", "apple")→["apple"] - 空字符串输入会返回
[0 => ""],不是空数组,容易在foreach里意外触发一次循环 - 不支持正则,想按“一个或多个逗号/分号”拆,得换
preg_split()
遇到 JSON 字符串就用 json_decode()
如果变量内容其实是 JSON 格式(比如 $json = '["a","b","c"]' 或 $json = '{"list":["x","y"]}'),硬用 explode() 会崩。这时必须先确认数据来源是否可信,再调用 json_decode()。
json_decode($json, true) 的第二个参数设为 true 才返回关联数组;不加就是对象,后续访问得用 -> 而不是 []。
立即学习“PHP免费学习笔记(深入)”;
- JSON 格式错误时返回
null,且json_last_error()不会自动抛异常,得手动检查 - 中文字符没转义、末尾多逗号、单引号代替双引号——这些都导致解码失败
- 如果原始变量是 HTML 表单提交的 JSON 字符串,可能被自动 URL 解码过一遍,需留意双重编码问题
从 $_POST 或 $_GET 里取多值要用数组语法命名
表单里多个同名 checkbox 或 select multiple 提交后,PHP 默认不会合并成一个字符串,而是直接生成数组。前提是 HTML name 属性带 [],比如 <input name="tag[]">。
否则,比如写成 name="tag",PHP 只保留最后一个值,前面的全丢。
- 没加
[]是常见疏漏,尤其在动态生成表单时容易漏掉 - 即使只勾了一个 checkbox,
$_POST["tag"]也是数组(含一个元素),不是字符串,别直接explode() - 如果后端还做了
filter_input(INPUT_POST, "tag", FILTER_SANITIZE_STRING),会把整个数组转成字符串"Array",彻底丢失数据
别用 eval() 或 unserialize() 解“伪列表”
有些老代码会把数组存成类似 "a|b|c" 或 PHP 数组语法字符串 "array('a','b','c')",然后试图用 eval() 或 unserialize() 还原。这非常危险,尤其是变量来自用户输入时。
unserialize() 在 PHP 7.4+ 默认禁用对象反序列化,且存在已知 POP 链风险;eval() 更是执行任意代码的入口。
- 哪怕加了
is_string()和白名单校验,也挡不住精心构造的绕过 - 真正需要序列化传输,请改用
json_encode()+json_decode() - 如果必须兼容旧格式,至少用
str_getcsv()替代explode()处理带引号/逗号的 CSV 风格字符串
最麻烦的情况其实是“列表”根本没定义清楚:是用户粘贴的一段换行文本?是数据库里用逗号拼的字段?还是 API 返回的混合结构?这时候光看函数没用,得先盯住数据源头长什么样。











