實務開發中常遇到 JSON 字串嵌套在陣列、物件或混合結構中,需遞歸遍歷完整轉換。本文提供一個可處理「字串 JSON、stdClass 物件、多維陣列」三種情境的通用轉換類。
<?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));
?>
toArray() 判斷型別分派,所有子函數最終回呼 toArray(),確保任意深度巢狀結構皆被處理public 屬性,protected/private 需搭配 ReflectionClass 或實作 __debugInfo()try-catch 決定降級策略JsonSerializable 介面物件mb_check_encoding() 確保 UTF-8 有效性此類適合 API 回應正規化、配置檔解析、第三方資料清洗等場景,一行程式碼處理複雜混合結構。