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

PHP URL 陣列傳遞技巧:序列化與編碼完整指南

     編輯:PHP 相關知識

在 Web 開發中,經常需要在頁面間透過 URL 傳遞陣列資料。由於 URL 僅支援字串,需將陣列序列化並編碼。本文詳細介紹 PHP 中使用 serialize()、base64_encode() 實現陣列 URL 傳遞的完整方案與安全考量。

核心原理

陣列傳遞三步驟:

  1. 序列化:serialize($array) 將陣列轉為字串表示
  2. 編碼:base64_encode() 確保 URL 安全字元
  3. 解碼還原:接收端按逆序操作 unserialize(base64_decode())

完整實作範例

發送端:建立帶陣列參數的連結

<?php
$information = [
    'name' => '張三',
    'age' => 28,
    'city' => '台北',
    'tags' => ['PHP', 'Laravel', 'MySQL']
];

// 正確順序:serialize → base64_encode
$encoded = base64_encode(serialize($information));

echo "<a href='2.php?info={$encoded}'>查看資訊</a>";
?>

接收端:解碼還原陣列

<?php
// 正確順序:base64_decode → unserialize
$info = unserialize(base64_decode($_GET['info']));

// 使用資料
echo "姓名: {$info['name']}<br>";
echo "年齡: {$info['age']}<br>";
echo "城市: {$info['city']}<br>";
echo "標籤: " . implode(', ', $info['tags']);
?>

關鍵技術細節

為什麼需要 base64_encode?

serialize() 產生的字串包含特殊字元(如分號、冒號、大括號),直接放入 URL 會導致解析錯誤。Base64 編碼將其轉為 URL 安全字元集(A-Z, a-z, 0-9, +, /, =)。

順序絕對不能顛倒

// 正確
$encoded = base64_encode(serialize($data));
$decoded = unserialize(base64_decode($encoded));

// 錯誤 - 會導致資料損壞
$encoded = serialize(base64_encode($data)); // 序列化了 Base64 字串而非原始資料

安全性強化方案

1. 完整性驗證(防篡改)

<?php
// 發送端:加入 HMAC 簽名
function signData($data, $secretKey) {
    $serialized = serialize($data);
    $encoded = base64_encode($serialized);
    $signature = hash_hmac('sha256', $encoded, $secretKey);
    return $encoded . '.' . $signature;
}

// 接收端:驗證簽名
function verifyAndDecode($signedData, $secretKey) {
    list($encoded, $signature) = explode('.', $signedData, 2);
    $expected = hash_hmac('sha256', $encoded, $secretKey);
    
    if (!hash_equals($expected, $signature)) {
        throw new Exception('資料簽名驗證失敗,可能被篡改');
    }
    
    return unserialize(base64_decode($encoded));
}
?>

2. 加密傳輸(敏感資料)

<?php
function encryptData($data, $key) {
    $serialized = serialize($data);
    $iv = random_bytes(openssl_cipher_iv_length('aes-256-cbc'));
    $encrypted = openssl_encrypt($serialized, 'aes-256-cbc', $key, 0, $iv);
    return base64_encode($iv . $encrypted);
}

function decryptData($encryptedData, $key) {
    $data = base64_decode($encryptedData);
    $ivLen = openssl_cipher_iv_length('aes-256-cbc');
    $iv = substr($data, 0, $ivLen);
    $encrypted = substr($data, $ivLen);
    $decrypted = openssl_decrypt($encrypted, 'aes-256-cbc', $key, 0, $iv);
    return unserialize($decrypted);
}
?>

替代方案比較

方法優點缺點適用場景
serialize + base64支援複雜陣列/物件、PHP 原生長度較長、需防篡改內部系統、非敏感資料
json_encode + base64跨語言相容、可讀性佳不支援資源/物件型別API 介面、前後端分離
http_build_query標準查詢字串、無需解碼僅支援一維陣列、URL 較長簡單表單資料傳遞
Session/資料庫安全、無長度限制需伺服器端儲存、增加複雜度敏感資料、大量資料

最佳實踐總結

  1. 嚴格遵循順序:序列化 → 編碼發送;解碼 → 反序列化接收
  2. 必須驗證輸入:isset($_GET['info']) 檢查參數存在性
  3. 錯誤處理:包裝 unserialize() 於 try-catch,防惡意資料導致錯誤
  4. 長度限制:URL 長度建議不超過 2000 字元,大量資料改用 POST 或 Session
  5. 安全優先:敏感資料加密簽名,防止資料洩露與篡改

總結

PHP URL 陣列傳遞透過 serialize() + base64_encode() 組合實現簡單有效,但必須注意操作順序、安全驗證與長度限制。現代應用中,對於複雜或敏感資料傳遞,建議採用 Session、JWT 或資料庫暫存等更安全方案。理解這項技術本質,有助於在適當場景做出正確技術選型。

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