在 API 開發、日誌記錄、緩存序列化等場景,常需將對象(含巢狀對象/數組)完整轉為關聯數組。本文提供健壯的遞歸實現。
/**
* 對象/數組遞歸轉關聯數組
* @param object|array $data
* @return array
*/
function objectToArray($data) {
if (is_object($data)) {
$data = get_object_vars($data);
}
if (!is_array($data)) {
return $data; // 標量直接返回
}
$result = [];
foreach ($data as $key => $value) {
$result[$key] = objectToArray($value);
}
return $result;
}
class User {
public $id = 1;
public $name = '張三';
public $profile; // 巢狀對象
public $tags = []; // 數組
}
$user = new User();
$user->profile = (object)['age' => 25, 'city' => '北京'];
$user->tags = ['php', 'laravel', (object)['level' => 'high']];
$arr = objectToArray($user);
print_r($arr);
/*
Array
(
[id] => 1
[name] => 張三
[profile] => Array
(
[age] => 25
[city] => 北京
)
[tags] => Array
(
[0] => php
[1] => laravel
[2] => Array
(
[level] => high
)
)
)
*/
function objectToArrayAdvanced($data) {
if (is_object($data)) {
if ($data instanceof \Traversable) {
$data = iterator_to_array($data);
} else {
$data = get_object_vars($data);
}
}
if (!is_array($data)) return $data;
return array_map('objectToArrayAdvanced', $data);
}
get_object_vars() 僅返回可見屬性。若需包含私有屬性,需在類內部調用或使用反射 ReflectionClass。$visited = [] 檢測 spl_object_id()。resource 無法轉數組,需特殊處理(如流獲取內容)。json_decode(json_encode($obj), true):簡潔但性能較差、會丟失私有屬性、資源類型變 null。