php会话数据默认经序列化后存储,序列化格式由session.serialize_handler决定,常见值为php(默认,含|分隔符易受注入)、php_serialize(更安全)和php_binary(二进制友好);存储位置由session.save_handler控制,如files、redis或user自定义;php不校验序列化数据完整性,篡改可能触发危险魔术方法;resource及部分对象不可序列化,应只存id等可重建数据;json不能替代php原生序列化机制。

PHP会话数据默认就是序列化后存储的,关键在于你用的是哪种序列化处理器,以及是否理解它对数据结构、安全性与兼容性的影响。
session.serialize_handler 决定序列化格式
PHP 会话数据不是直接存数组,而是先按 session.serialize_handler 指定的方式序列化,再写入存储介质(如文件、Redis)。这个配置有三个常见值:
-
php(默认):键名 +|+serialize()后的值,例如tt|s:4:"Lxxx";。注意键名里不能含|或!,否则会出错甚至截断数据。 -
php_serialize:整个$_SESSION数组被统一用serialize()处理,结果是纯序列化字符串,如a:1:{s:2:"tt";s:4:"Lxxx";}。更干净,也更安全——避免了|注入类攻击。 -
php_binary:键名长度的 ASCII 字符 + 键名 + 序列化值,二进制友好但调试困难,极少手动使用。
修改方式:ini_set('session.serialize_handler', 'php_serialize'); 必须在 session_start() 前调用,否则无效。
session.save_handler 影响存储位置与反序列化时机
序列化后的数据最终存在哪,由 session.save_handler 控制。不同 handler 对序列化数据的处理逻辑不同:
-
files(默认):把序列化字符串写进/tmp/sess_*文件,读取时自动反序列化填充$_SESSION。 -
redis:PHP 将序列化字符串原样塞进 Redis 的 value 中(如SET session:abc123 "a:1:{s:2:\"tt\";s:4:\"Lxxx\";}"),不解析内容;反序列化仍由 PHP 在读取时完成。 -
user:自定义 handler,你得自己实现write和read回调,read返回的必须是合法的序列化字符串,否则unserialize()会失败并静默清空$_SESSION。
重要提醒:无论哪种 handler,PHP 都不会校验序列化字符串是否被篡改。如果攻击者能控制 session 存储内容(如通过文件写入、Redis 注入或共享存储漏洞),就可能触发危险的 __wakeup() 或 __destruct() 方法。
为什么不能存 resource 和部分对象?
serialize() 明确不支持 resource 类型,比如数据库连接、文件句柄、cURL 句柄等。尝试序列化会直接报错或产生不可预测行为。
- session 中写入
$_SESSION['db'] = $pdo;→ 启动会话时抛出Fatal error: Uncaught Exception: Serialization of 'PDO' is not allowed。 - 某些内置对象(如
SimpleXML)也不支持,除非它们实现了Serializable接口或__sleep()/__wakeup()。 - 对象中包含闭包、私有属性未正确处理、类定义缺失,都会导致反序列化失败或数据丢失。
解决办法:只存 ID、标识符或可重建的数据,而不是资源本身。例如存 $_SESSION['user_id'] = 123;,需要时再查库重建对象。
JSON 不是 session 的替代方案
有人想用 json_encode() 替代默认序列化,这是行不通的——PHP 的 session 机制硬编码依赖 serialize() 格式,你无法让 session_start() 自动识别 JSON 字符串。
- 强行把 JSON 字符串赋给
$_SESSION某个键(如$_SESSION['data'] = json_encode($arr);),读取时还得手动json_decode(),失去 session 的透明性。 - JSON 无法表示
null以外的NULL、布尔、资源、对象方法、引用关系,且对多字节字符、特殊控制字符更敏感。 - 如果你真需要跨语言会话共享,应改用外部服务(如 Redis)+ 自定义协议,而非改造 PHP session 底层。
真正要注意的其实是:session 数据一旦离开 PHP 环境(比如被前端 JS 读取、被日志系统记录、被缓存穿透暴露),它的序列化格式就成了安全隐患入口。别让它出去。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











