如何在 PHP 建立一個 Object

JavaScript 的 Object

在 JavaScript 定義一個 Object 相當的容易:

const name = {
first: 'Peng',
last: 'Jie',
};
console.log(name.first);
console.log(name.last);

PHP 的 Object

有段時間沒寫 PHP 了,最近因為工作關係所以又重返 PHP 了哈哈,那天想要嘗試寫一下 Object 突然卡住,第一個印象中的寫法是:

$name = [
'first' => 'Peng',
'last' => 'Jie',
];
var_dump($name);
// array(2) {
// ["first"]=>
// string(4) "Peng"
// ["last"]=>
// string(3) "Jie"
// }

看起來好像是這麼回事吧,但是 var_dump 結果出來感覺又哪裡怪怪的,所以用了 json_encode 確認一下:

{
"first":"Peng",
"last":"Jie"
}

結果跟我們在 JavaScript 定義一個 object 長得一樣呢!

Laravel 中的 Collection

在 Laravel 開發上使用 Eloquent ORM 透過 get() 或是 all() 拿回來的資料是 Collection,通常我們會透過一個 foreach 去把每筆資料給 dump 出來,我們可能會這麼使用:

use App\NameList;
$nameList = App\NameList::all();
foreach ($nameList as $name) {
echo $name->first . "\n" . $name->last;
}

注意不是寫成:

foreach ($nameList as $name) {
echo $name['first'] . "\n" . $name['last'];
}

官方文件有提到:Eloquent Model 都會被作為 query builder,所以在 queries 文件可以找到這個訊息:

The get method returns an Illuminate\Support\Collection containing the results where each result is an instance of the PHP StdClass object. You may access each column's value by accessing the column as a property of the object ...

在 PHP 使用不同方式定義 Object 的差異

$name = [
'first' => 'Peng',
'last' => 'Jie',
];
echo json_encode($name); // {"first":"Peng","last":"Jie"}
echo $name['first']; // Peng
$name = (object) [
'first' => 'Peng',
'last' => 'Jie',
];
echo json_encode($name); // {"first":"Peng","last":"Jie"}
echo $name['first']; // Fatal error: Cannot use object of type stdClass as array...

這裡可以看到錯誤的訊息:不能使用類型 stdClass 的 object 作為物件

知識點:你必須確認 Object 是透過哪種方式定義的,而決定你必須用哪一種方法,或者是透過一些 method 去做轉換。

關於 stdClass 有興趣可以去查詢一下,上面的 $name 也可以用 stdClass 寫成:

$name = new stdClass();
$name->first = 'Peng';
$name->last = 'Jie';
var_dump($name);
// object(stdClass)#1 (2) {
// ["first"]=>
// string(4) "Peng"
// ["last"]=>
// string(3) "Jie"
// }

stdClass 的定義大概就是如下面的意思,節錄自 Notes on stdClass

stdClass is the default PHP object. stdClass has no properties, methods or parent. It does not support magic methods, and implements no interfaces.

When you cast a scalar or array as Object, you get an instance of stdClass. You can use stdClass whenever you need a generic object instance.