核心轉換函數:遞迴深度轉換
<?php
/** 陣列遞迴轉物件 (支援多維、資源型別保護) */
function arrayToObject(mixed $data): object {
if (!is_array($data)) return $data;
$obj = new stdClass();
foreach ($data as $key => $value) {
$obj->$key = is_array($value) || is_object($value)
? arrayToObject($value)
: $value;
}
return $obj;
}
/** 物件遞迴轉陣列 (支援 private/protected 屬性、資源型別跳過) */
function objectToArray(mixed $obj): array {
if (is_object($obj)) {
$obj = (array) $obj; // 將物件屬性轉為陣列 (含可見性標記)
}
if (!is_array($obj)) return [];
$result = [];
foreach ($obj as $key => $value) {
// 處理 private/protected 屬性鍵名 (含 \0* \0 前綴)
$cleanKey = ltrim($key, "\0*\0");
if (is_resource($value)) continue; // 資源無法序列化,略過
$result[$cleanKey] = is_array($value) || is_object($value)
? objectToArray($value)
: $value;
}
return $result;
}
?>
簡易強制轉型 (單層、無遞迴)
<?php
$arr = ['a' => 1, 'b' => 2, 'c' => 3];
// 陣列 → 物件
$obj = (object) $arr; // stdClass { a:1, b:2, c:3 }
$obj->a; // 1
// 物件 → 陣列
$arr2 = (array) $obj; // ['a'=>1, 'b'=>2, 'c'=>3]
// 匿名類別建構 (PHP 7+)
$obj = new class($arr) {
public function __construct(public array $data) {}
};
?>
StdClass 與匿名類別
<?php
// 傳統 StdClass
$andy = new StdClass();
$andy->a = 1; $andy->b = 2; $andy->c = 3;
// 匿名類別 (PHP 7+) - 可定義方法、介面、型別提示
$andy = new class {
public int $a = 1;
public string $b = 'test';
public function sum(): int { return $this->a + 10; }
};
$andy->sum(); // 11
// 唯讀屬性 (PHP 8.1+)
$config = new class {
public readonly string $appName = 'MyApp';
public readonly int $version = 1;
};
?>
ArrayObject:陣列物件化、可迭代、可計數、ArrayAccess
<?php
$array = ['1' => 'one', '2' => 'two', '3' => 'three'];
$ao = new ArrayObject($array, ArrayObject::ARRAY_AS_PROPS);
// 像陣列一樣操作
echo $ao['1']; // one
$ao['4'] = 'four'; // 新增
echo count($ao); // 4
foreach ($ao as $k => $v) { echo "$k=$v\n"; }
// 取得原生陣列
$native = $ao->getArrayCopy();
// 進階:繼承 ArrayObject 自訂行為
class MyCollection extends ArrayObject {
public function offsetSet($key, $value): void {
if (!is_int($value)) throw new InvalidArgumentException('只允許整數');
parent::offsetSet($key, $value);
}
}
?>
資源消耗與效能對比
| 特性 | 陣列 | 物件 |
| 記憶體 | 複製時完整複製 (Copy-on-Write 優化) | 參考傳遞,極省記憶體 |
| 存取速度 | 極快 (HashTable 直接索引) | 略慢 (屬性查找、可見性檢查) |
| 序列化 | 原生支援 | 需實作 Serializable/JsonSerializable |
| 型別安全 | 無 (PHP 8.0+ 僅型別提示) | 可定義嚴格型別、readonly、介面 |
| 適用場景 | 資料集合、暫時資料、高頻讀寫 | 領域模型、服務物件、狀態封裝 |
現代最佳實務建議
- DTO/Value Object: 使用
readonly class (PHP 8.1+) 定義不可變資料傳輸物件。
- 集合類別: 繼承
ArrayObject 或實作 IteratorAggregate + Countable 封裝陣列操作邏輯。
- 避免手動轉換: 使用序列化器 (Symfony Serializer、Laravel Resources) 自動處理物件↔陣列/JSON。
- 資源型別處理: PDOStatement、Stream、GD Image 等資源不可直接序列化,轉換時需特別處理或略過。
- JSON API: 直接
json_encode($object) (實作 JsonSerializable) 或 json_encode($array),無需中間轉換。