在 PHP 開發中,json_decode()、SOAP 回傳、資料庫 ORM 查詢常產生 stdClass 物件。若需陣列操作(如 array_map、array_filter、鍵名存取),需先轉為陣列。本文整理三種主流轉換方法,並針對大資料量進行效能分析。
<?php
/**
* 遞迴將物件轉為陣列
* @param mixed $data
* @return array
*/
function object_to_array($data) {
if (is_object($data)) {
$data = (array) $data;
}
if (is_array($data)) {
foreach ($data as $key => $value) {
$data[$key] = object_to_array($value);
}
}
return $data;
}
// 使用範例
$obj = json_decode('{"id":1,"name":"John","tags":["a","b"],"meta":{"age":25}}');
$arr = object_to_array($obj);
var_dump($arr);
優點:純 PHP 實作,無擴充套件依賴,相容所有 PHP 版本。
缺點:遞迴呼叫開銷大,10 萬筆資料耗時約 1 秒,結構越複雜越慢(可達 3 秒以上)。
<?php
/**
* 透過 JSON 序列化/反序列化快速轉換
* @param mixed $data
* @return array
*/
function object_to_array_fast($data) {
return json_decode(json_encode($data), true);
}
// 使用範例
$obj = json_decode('{"id":1,"name":"John","tags":["a","b"],"meta":{"age":25}}');
$arr = object_to_array_fast($obj);
var_dump($arr);
優點:C 底層實作,速度極快(10 萬筆約 0.05 秒),程式碼極簡潔。
缺點:
mb_convert_encoding()。<?php
/**
* 以傳址方式遞迴轉換,減少記憶體複製
* @param mixed &$data
* @return array
*/
function object_to_array_ref(&$data) {
if (is_object($data)) {
$data = (array) $data;
}
if (is_array($data)) {
foreach ($data as $key => &$value) {
object_to_array_ref($value);
}
unset($value); // 解除參考
}
return $data;
}
傳址方式可減少大陣列複製的記憶體峰值,但速度仍不如 JSON 法。
| 方法 | 耗時 (秒) | 記憶體峰值 | 適用場景 |
|---|---|---|---|
| 遞迴型 (方法一) | ~2.8 | 高 | 舊版 PHP、非 UTF-8、含資源型別 |
| JSON 繞道 (方法二) | ~0.06 | 中 | 現代專案、UTF-8、純資料結構 |
| 傳址遞迴 (方法三) | ~1.9 | 低 | 記憶體受限、需保留物件參考關係 |
若掌管物件類別,可實作 JsonSerializable 介面精確控制輸出:
<?php
class User implements JsonSerializable {
private $password;
public $id, $name, $email;
public function jsonSerialize() {
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
// 敏感欄位不輸出
];
}
}
$user = new User();
$user->id = 1; $user->name = 'John'; $user->email = 'john@example.com'; $user->password = 'secret';
$arr = json_decode(json_encode($user), true);
// 結果不含 password