在處理 API 回傳、JSON 解碼或 ORM 查詢結果時,常需將 stdClass 物件轉為陣列以便操作。本文提供一個支援多層巢狀結構的遞迴轉換函式,並說明使用情境與注意事項。
<?php
/**
* 將 stdClass 物件遞迴轉換為關聯陣列
* @param object|array $stdclassobject 物件或陣列
* @return array 轉換後的純陣列
*/
function std_class_object_to_array($stdclassobject) {
// 若為物件取得屬性陣列,否則直接使用
$_array = is_object($stdclassobject)
? get_object_vars($stdclassobject)
: $stdclassobject;
foreach ($_array as $key => $value) {
// 遞迴處理巢狀物件或陣列
$value = (is_array($value) || is_object($value))
? std_class_object_to_array($value)
: $value;
$array[$key] = $value;
}
return $array;
}
?>
<?php
// 模擬 API 回傳的巢狀物件結構
$response = json_decode('{
"user": {
"id": 123,
"profile": {
"name": "張三",
"tags": ["VIP", "活躍"]
}
},
"metadata": {
"timestamp": 1699999999,
"version": "1.0"
}
}');
// 轉換為陣列
$data = std_class_object_to_array($response);
// 現在可以用陣列語法存取
echo $data['user']['profile']['name']; // 輸出:張三
print_r($data['user']['profile']['tags']); // 正常輸出陣列
function object_to_array_advanced($obj, $includePrivate = false) {
if (is_array($obj)) {
return array_map(function($v) use ($includePrivate) {
return object_to_array_advanced($v, $includePrivate);
}, $obj);
}
if (!is_object($obj)) return $obj;
$reflection = new ReflectionClass($obj);
$props = $reflection->getProperties(
$includePrivate ? ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE
: ReflectionProperty::IS_PUBLIC
);
$arr = [];
foreach ($props as $prop) {
$prop->setAccessible(true);
$arr[$prop->getName()] = object_to_array_advanced($prop->getValue($obj), $includePrivate);
}
return $arr;
}
json_decode($json, false) 回傳物件需轉陣列處理大量資料轉換時,遞迴函式會有函式呼叫開銷。若確定結構扁平,可直接用 (array)$obj 強制轉型(但無法處理巢狀、private 屬性)。生產環境大數據建議使用 json_decode($json, true) 直接產出陣列,避免物件中轉。