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

PHP JSON 編解碼純實現:eval 技巧與性能優化深度解析

     編輯:PHP 相關知識

背景

PHP 5.2 前無原生 json_encode/decode,且許多虛擬主機仍運行舊版本。本文展示純 PHP 實現的 JSON 編解碼器,解碼器利用 eval() 技巧將 JSON 轉為 PHP 代碼執行,性能遠超同類純 PHP 庫。

JSON Encode 實現

<?php
function json_stringify($data) {
    if (is_null($data)) return 'null';
    if (is_scalar($data)) return json_stringify_scalar($data);
    if (empty($data)) return '[]';
    
    if (is_object($data)) {
        $data = get_object_vars($data);
        if (empty($data)) return '{}';
    }
    
    $keys = array_keys($data);
    // 連續數字鍵視為數組
    if ($keys === array_keys($keys)) {
        return '[' . implode(',', array_map(__FUNCTION__, $data)) . ']';
    }
    // 關聯數組視為對象
    $pairs = [];
    foreach ($data as $k => $v) {
        $pairs[] = json_stringify_scalar((string)$k) . ':' . json_stringify($v);
    }
    return '{' . implode(',', $pairs) . '}';
}

function json_stringify_scalar($v) {
    if (is_bool($v)) return $v ? 'true' : 'false';
    if (is_string($v)) {
        $v = addcslashes($v, "\t\n\r\"\/\\");
        // 非 ASCII 字符轉 Unicode 轉義
        $v = '"' . preg_replace_callback('|[^\x00-\x7F]+|', '_unicode_escape', $v) . '"';
    }
    return (string)$v;
}

function _unicode_escape($matches) {
    $s = iconv('UTF-8', 'UCS-2BE', $matches[0]);
    $s = str_split($s, 2);
    foreach ($s as $i => $c) {
        $s[$i] = sprintf('\u%02x%02x', ord($c[0]), ord($c[1]));
    }
    return implode('', $s);
}

JSON Decode:eval 技巧核心

原理:JSON 是 JavaScript 子集,JS 用 eval() 直接解析。PHP 也有 eval(),若將 JSON 轉為等價 PHP 代碼即可直接執行。

轉換規則:

  • { → (object)array(
  • } → )
  • [ → array(
  • ] → )
  • : → =>
  • null → NULL
  • 字符串鍵值加雙引號
<?php
function json_parse($json, $assoc = false) {
    static $strings = [], $count = 0;
    
    if (is_string($json)) {
        $json = trim($json);
        $strings = [];
        // 1. 提取並佔位所有字符串(處理轉義引號)
        $json = preg_replace_callback('/"([\s\S]*?(?','NULL'],
            $json
        );
        
        // 4. 還原字符串佔位符
        $json = preg_replace_callback('/#\d+#/', function($m) use ($strings) {
            $idx = (int)substr($m[0], 1, -1);
            return $strings[$idx];
        }, $json);
        
        // 5. 執行並返回
        @$result = eval("return $json;");
        $strings = $count = 0; // GC
        return $result;
    }
    // 內部回調處理...
}

function _unicode_unescape($data) {
    if (is_string($data)) {
        return preg_replace_callback(
            '/(?

性能對比

操作本實現Services_JSONPHP 內置 (C)
Encode基準 (1x)~3-4x 慢~100x 快
Decode基準 (1x)~10-15x 慢~100x 快

優化關鍵點

  • Encode:iconv('UTF-8','UCS-2BE') 批量轉 Unicode,避免逐字符處理
  • Decode:利用 PHP 內置字符串函數 + eval(),雖掃描多次但均為 C 級操作
  • 安全:字符串提取佔位、清理檢查、@eval 抑制錯誤

使用範例

<?php
$data = [
    'name' => '測試',
    'age' => 25,
    'tags' => ['PHP', 'JSON', '性能'],
    'active' => true,
    'meta' => (object)['version' => '1.0']
];

$json = json_stringify($data);
echo $json . PHP_EOL;
// {"name":"\u6d4b\u8bd5","age":25,"tags":["PHP","JSON","\u6027\u80fd"],"active":true,"meta":{"version":"1.0"}}

$parsed = json_parse($json);
var_dump($parsed);
// object(stdClass)#1 (5) { ["name"]=> string(6) "測試" ... }

適用場景與限制

  • ✅ PHP 5.2 環境無法升級
  • ✅ 禁用 eval() 的環境不可用(需修改 php.ini)
  • ✅ 大數據量、高頻調用場景建議升級 PHP 或安裝 pecl/json
  • ✅ 不支援 JSONP、BSON 等變體
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved