WebService 串接、API 資料交換常需在多維陣列與物件間轉換。單層 (array)、(object) 強制轉型無法處理巢狀結構;json_encode/decode 雖能一鍵轉換,但遇非 UTF-8 編碼(如 GBK 中文)會失敗,且效能有額外開銷。本文提供純 PHP 遞迴實作,支援任意深度巢狀結構,無編碼限制。
function objectToArray($data) {
if (is_object($data)) {
// 取得物件屬性(含 protected/private 需在類別內呼叫或用 Reflection)
$data = get_object_vars($data);
}
if (is_array($data)) {
// 遞迴處理每個元素
return array_map(__FUNCTION__, $data);
}
return $data; // 標量值直接返回
}
function arrayToObject($data) {
if (is_array($data)) {
// 遞迴轉換值,最後轉為 stdClass 物件
return (object) array_map(__FUNCTION__, $data);
}
return $data;
}
<?php
// 建立多層巢狀物件
$init = new stdClass;
$init->foo = "Test data";
$init->bar = new stdClass;
$init->bar->baaz = "Testing";
$init->bar->fooz = new stdClass;
$init->bar->fooz->baz = "Testing again";
$init->foox = "Just test";
// 物件 → 陣列 → 物件 完整循環
$array = objectToArray($init);
$object = arrayToObject($array);
// 輸出驗證
print_r($init);
echo "\n---\n";
print_r($array);
echo "\n---\n";
print_r($object);
?>
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 本文遞迴函式 | 無編碼限制、效能較好、可控性強 | 需自行維護、無法處理 Resource 等特殊型別 | 非 UTF-8 專案、高頻轉換、需自訂邏輯 |
| json_encode/decode | 一行代碼、原生支援、處理循環引用 | 強制 UTF-8、大資料效能差、浮點精度可能損失 | UTF-8 專案、簡單場景、資料量小 |
| 序列化 serialize | 完整保留型別、物件方法 | 二進位不可讀、跨語言困難、安全風險 | PHP 內部儲存、快取、Session |
&$visited 陣列記錄 spl_object_id)。new $className 並注入屬性。DateTime、ArrayObject 等內建類別的特殊轉換邏輯。純 PHP 遞迴轉換是處理多維結構互轉的輕量、可控方案,特別適合歷史專案或特殊編碼環境。