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

PHP JSON 轉陣列通用類:遞歸處理巢狀結構

     編輯:PHP 綜合知識

實務開發中常遇到 JSON 字串嵌套在陣列、物件或混合結構中,需遞歸遍歷完整轉換。本文提供一個可處理「字串 JSON、stdClass 物件、多維陣列」三種情境的通用轉換類。

核心實作:antiTranJson 類

<?php
class antiTranJson {
    /** 公開入口:統一轉換介面 */
    public static function toArray($params) {
        $tmp = [];
        if (is_string($params) && !is_null(json_decode($params))) {
            $tmp = self::jsonToArray($params);
        } elseif (is_array($params)) {
            $tmp = self::arrayRToArray($params);
        } elseif (is_object($params)) {
            // 僅可讀取 public 屬性或動態屬性
            $tmp = self::stdClassToArray($params);
        } else {
            $tmp = $params; // 標量直接回傳
        }
        return $tmp;
    }

    /** JSON 字串 → 陣列 */
    protected static function jsonToArray($json) {
        if (!is_string($json) || is_null(json_decode($json, true))) {
            throw new Exception('param is not a json string');
        }
        $deJson = json_decode($json, true); // true 關鍵:關聯陣列
        return self::toArray($deJson); // 遞歸處理巢狀結構
    }

    /** stdClass 物件 → 陣列 */
    protected static function stdClassToArray($stds) {
        if (!is_object($stds)) {
            throw new Exception('params not object');
        }
        $params = get_object_vars($stds); // 取得可見屬性
        return self::toArray($params);
    }

    /** 多維陣列遞歸轉換 */
    protected static function arrayRToArray($params) {
        if (!is_array($params)) {
            throw new Exception('params not array');
        }
        $tmp = [];
        foreach ($params as $k => $v) {
            $tmp[$k] = self::toArray($v); // 遞歸處理每個元素
        }
        return $tmp;
    }
}
?>

使用範例

<?php
// 1. 純 JSON 字串
$json = '{"user":{"name":"John","tags":["php","json"]},"status":true}';
print_r(antiTranJson::toArray($json));

// 2. 陣列包含 JSON 字串元素
$mixed = [
    'config' => '{"debug":true,"version":"1.0"}',
    'items' => ['a', 'b', '{"nested":123}']
];
print_r(antiTranJson::toArray($mixed));

// 3. stdClass 物件(如資料庫查詢結果)
$obj = new stdClass();
$obj->data = '{"id":1,"val":"test"}';
$obj->meta = (object)['time' => time()];
print_r(antiTranJson::toArray($obj));

// 4. 混合深層結構
$deep = [
    'level1' => (object)[
        'jsonStr' => '{"level2":["a","b"]}',
        'plain' => 'text'
    ]
];
print_r(antiTranJson::toArray($deep));
?>

關鍵設計細節

  1. 遞歸統一入口:toArray() 判斷型別分派,所有子函數最終回呼 toArray(),確保任意深度巢狀結構皆被處理
  2. json_decode 第二參數 true:強制回傳關聯陣列而非 stdClass,避免後續再轉換
  3. get_object_vars() 限制:僅能取得 public 屬性,protected/private 需搭配 ReflectionClass 或實作 __debugInfo()
  4. 標量透傳:非陣列/物件/JSON字串直接回傳,保留原始資料型別
  5. 例外處理:格式錯誤拋出 Exception,呼叫端可 try-catch 決定降級策略

擴充建議

  • 支援 JsonSerializable 介面物件
  • 新增深度限制防止無限遞歸
  • 加入快取機制(針對重複 JSON 字串)
  • 整合 mb_check_encoding() 確保 UTF-8 有效性

此類適合 API 回應正規化、配置檔解析、第三方資料清洗等場景,一行程式碼處理複雜混合結構。

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