首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 陣列與字串互轉:serialize/unserialize vs var_export 實戰對比

     編輯:PHP 綜合知識

原始代碼分析(存在風險)

<?php
function string2array($data) {
    if ($data == '') return [];
    @eval("\$array = $data;"); // ⚠️ 極高風險:eval 注入
    return $array;
}

function array2string($data, $isformdata = 1) {
    if ($data == '') return '';
    if ($isformdata) $data = new_stripslashes($data); // 依賴未定義函數
    return addslashes(var_export($data, true));
}

致命缺陷:eval() 執行任意代碼,若 $data 來自用戶輸入/資料庫,直接導致 RCE(遠端代碼執行)漏洞。

現代標準方案:serialize / unserialize

<?php
$array = ['id' => 1, 'name' => '張三', 'tags' => ['php', 'laravel']];

// 陣列 → 字串(二進制安全、保留型別)
$serialized = serialize($array);
// a:3:{s:2:"id";i:1;s:4:"name";s:6:"張三";s:4:"tags";a:2:{i:0;s:3:"php";i:1;s:7:"laravel";}}

// 字串 → 陣列
$restored = unserialize($serialized);
// 完全還原原陣列結構、型別、巢狀關係

替代方案:JSON(跨語言、可讀、前端友善)

<?php
$json = json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// {"id":1,"name":"張三","tags":["php","laravel"]}

$restored = json_decode($json, true); // true 返回關聯陣列
// 注意:JSON 無法區分 indexed array vs associative array,且不支援 resource/object

方案對比表

特性serializejson_encodevar_export
PHP 型別保真度✅ 完整(含 object、resource*)⚠️ 僅陣列/標量/物件公開屬性✅ 完整(輸出合法 PHP 代碼)
跨語言通用性❌ PHP 專用✅ 標準格式❌ PHP 專用
人類可讀性❌ 難讀✅ 清楚✅ 可讀 PHP 代碼
效能(大數據)⚡ 快⚡ 快🐢 慢(解析 PHP 代碼)
安全性⚠️ 不可反序列化不可信數據✅ 安全❌ 極危險(需 eval)

安全警示:反序列化漏洞防範

<?php
// ❌ 絕對禁止:unserialize($userInput)

// ✅ 如果必須反序列化外部數據,使用 allowed_classes 限制(PHP 7.0+)
$data = unserialize($serialized, ['allowed_classes' => ['MyApp\\DTO\\UserDTO']]);

// ✅ 更佳:改用 JSON + 結構驗證
$dto = json_decode($json, true);
if (!isset($dto['id'], $dto['name'])) {
    throw new InvalidArgumentException('Invalid data structure');
}

最佳實踐建議

  1. 緩存/Session/隊列傳遞:serialize() / unserialize()(配合 allowed_classes)
  2. API 回應/前端互動/配置檔:json_encode() + JSON_UNESCAPED_UNICODE
  3. 除錯輸出/代碼生成:var_export($arr, true)(僅開發環境)
  4. 永遠不要:eval() 處理資料、unserialize() 不可信輸入

總結

拋棄 eval() 時代遺毒。序列化首選 serialize(),交互首選 json_encode()。若專案仍在使用類似 string2array 的舊代碼,請立即重構為安全方案,並審計所有 unserialize() 調用點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved