鋼琴留言版
https://laihao.vaserver.com/gbook
可以實際測試
也歡迎大家一起來學習喔
https://www.pressplay.cc/project/9D489B43D08BD198FDEB03ECDEFAC161/about
資料表-這裡只有單一一個
MVC架構-
MODEL
前端
後端
--
MODEL程式碼
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Gbook extends Model
{
protected $connection = 'mysql_gbook';
protected $table = 'gbook';
protected $primaryKey = 'gid';
public $timestamps = false;
protected $fillable = [
'gbook_poser',
'gbook_kind',
'gbook_title',
'gbook_msg',
'gbook_date',
];
}
這是一個 Laravel 的 Eloquent Model,名稱是 Gbook,用來代表資料庫中的 gbook 資料表。透過它,你可以使用 PHP 物件方式新增、查詢、修改及刪除留言資料。
namespace App\Models;
表示這個 Model 位於:
app/Models/Gbook.php
Laravel 會使用命名空間來管理類別,避免不同類別名稱互相衝突。
例如 Controller 中通常可以這樣引用:
use App\Models\Gbook;
use Illuminate\Database\Eloquent\Model;
這行引入 Laravel 的基礎 Eloquent Model。
class Gbook extends Model
表示 Gbook 繼承 Laravel 的 Model 類別,因此可以使用:
Gbook::all();
Gbook::find(1);
Gbook::create([...]);
Gbook::where(...)->get();
Eloquent 原本預設會按照 Model 名稱推測資料表與主鍵;這裡因為資料表和主鍵名稱不是 Laravel 的預設格式,所以需要自行設定。
protected $connection = 'mysql_gbook';
表示這個 Model 不使用 Laravel 的預設資料庫連線,而是使用名為 mysql_gbook 的連線設定。
這個名稱通常必須存在於:
config/database.php
例如:
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
],
'mysql_gbook' => [
'driver' => 'mysql',
'host' => env('GBOOK_DB_HOST', '127.0.0.1'),
'port' => env('GBOOK_DB_PORT', '3306'),
'database' => env('GBOOK_DB_DATABASE'),
'username' => env('GBOOK_DB_USERNAME'),
'password' => env('GBOOK_DB_PASSWORD'),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => false,
],
],
.env 可以搭配:
GBOOK_DB_HOST=127.0.0.1
GBOOK_DB_PORT=3306
GBOOK_DB_DATABASE=laihao_my_gbook
GBOOK_DB_USERNAME=資料庫帳號
GBOOK_DB_PASSWORD=資料庫密碼
因此,這個 Model 很適合用來連接「獨立的留言資料庫」或「不同資料庫伺服器」。
Laravel 的 Eloquent 支援在 Model 上指定不同的資料庫連線名稱。 laravel
protected $table = 'gbook';
指定這個 Model 對應的資料表是:
gbook
如果沒有這一行,Laravel 會根據 Gbook 自動推測資料表名稱。通常會推測成:
gbooks
但實際資料表是單數的 gbook,所以必須明確指定。
例如:
Gbook::all();
大致會產生類似 SQL:
SELECT * FROM `gbook`;
protected $primaryKey = 'gid';
指定資料表的主鍵欄位是:
gid
Laravel Eloquent 預設假設主鍵名稱是:
id
但你的資料表使用:
gid
因此要加上這一行。
有了這個設定,以下查詢才會正確使用 gid:
$gbook = Gbook::find(2);
它會尋找:
SELECT *
FROM `gbook`
WHERE `gid` = 2
LIMIT 1;
如果沒有設定 $primaryKey = 'gid',Laravel 可能會錯誤地查詢:
WHERE `id` = 2
public $timestamps = false;
Laravel Eloquent 預設會尋找兩個欄位:
created_at
updated_at
新增或修改資料時,Laravel 也會嘗試自動更新它們。
但你的 gbook 資料表沒有這兩個欄位,只有:
gbook_date
因此設定:
public $timestamps = false;
告訴 Laravel:
不要自動處理
created_at和updated_at。
否則新增資料時可能出現類似錯誤:
Unknown column 'updated_at' in 'field list'
Laravel 官方文件也說明,如果資料表沒有標準的 created_at 與 updated_at 欄位,就可以將 $timestamps 設定為 false。 laravel
要注意的是,這只會關閉 Laravel 的自動時間管理,不會讓 gbook_date 自動失效。
你的 MySQL 資料表仍然有:
gbook_date TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP
所以:
gbook_date。gbook_date。$fillable 欄位白名單protected $fillable = [
'gbook_poser',
'gbook_kind',
'gbook_title',
'gbook_msg',
'gbook_date',
];
$fillable 是 Eloquent 的「可大量填入欄位白名單」。
它會限制哪些欄位可以透過以下方式批次寫入:
Gbook::create($data);
或:
gbook->update(data);
目前允許寫入的欄位包括:
| 欄位 | 用途 |
|---|---|
gbook_poser |
發表人 |
gbook_kind |
發表類型或程度 |
gbook_title |
標題或分類 |
gbook_msg |
留言內容 |
gbook_date |
發表日期 |
gid 沒有放入 $fillable,因此一般不會讓使用者透過批次提交資料時自行指定主鍵,這是比較安全的做法。
Laravel 使用 $fillable 是為了防止 Mass Assignment,也就是避免使用者透過表單額外提交不應該修改的欄位。 laravel
Gbook::create([
'gbook_poser' => '學生',
'gbook_kind' => '初級',
'gbook_title' => '許願',
'gbook_msg' => '卡農',
]);
這會新增一筆資料。
由於沒有指定 gbook_date,資料庫的:
DEFAULT CURRENT_TIMESTAMP
會自動產生日期。
大致相當於:
INSERT INTO gbook
(
gbook_poser,
gbook_kind,
gbook_title,
gbook_msg
)
VALUES
(
'學生',
'初級',
'許願',
'卡農'
);
gid 也會由 MySQL 的 AUTO_INCREMENT 自動產生。
查詢全部留言:
$messages = Gbook::all();
查詢單筆留言:
$message = Gbook::find(1);
查詢「許願」:
$messages = Gbook::where('gbook_title', '許願')
->orderByDesc('gbook_date')
->get();
查詢內容包含「兒歌」的資料:
$messages = Gbook::where('gbook_msg', 'like', '%兒歌%')
->get();
分頁查詢:
$messages = Gbook::orderByDesc('gbook_date')
->paginate(10);
$message = Gbook::findOrFail(2);
$message->update([
'gbook_msg' => '德布西:月光',
]);
這裡的 2 是 gid。
修改後:
created_at 或 updated_at。gbook_date。$message = Gbook::findOrFail(2);
$message->delete();
大致相當於:
DELETE FROM gbook
WHERE gid = 2;
如果只是希望查詢而不真正刪除,則需要另外設計軟刪除欄位,例如 deleted_at;目前這份資料表並沒有這個欄位。
Gbook Model
↓
mysql_gbook 資料庫連線
↓
gbook 資料表
↓
gid 主鍵
↓
gbook_poser、gbook_kind、gbook_title、
gbook_msg、gbook_date 欄位
設定完成後,Laravel 就能正確對應你前面 SQL 中的資料表。
$casts可以加入:
protected $casts = [
'gbook_date' => 'datetime',
];
完整範例:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Gbook extends Model
{
protected $connection = 'mysql_gbook';
protected $table = 'gbook';
protected $primaryKey = 'gid';
public $timestamps = false;
protected $fillable = [
'gbook_poser',
'gbook_kind',
'gbook_title',
'gbook_msg',
'gbook_date',
];
protected $casts = [
'gbook_date' => 'datetime',
];
}
這樣讀取時:
$message->gbook_date
會被 Laravel 轉成日期物件,方便格式化:
$message->gbook_date->format('Y-m-d H:i');
如果新增時一律讓 MySQL 自動產生 gbook_date,也可以不把它放進 $fillable:
protected $fillable = [
'gbook_poser',
'gbook_kind',
'gbook_title',
'gbook_msg',
];
這樣使用者不能透過表單自行偽造留言日期,安全性較高。
這個 Gbook Model 的主要功能是把 Laravel 和你的 gbook 資料表接起來:
protected $connection = 'mysql_gbook';
使用指定的資料庫連線。
protected $table = 'gbook';
對應 gbook 資料表。
protected $primaryKey = 'gid';
指定 gid 為主鍵。
public $timestamps = false;
停用 Laravel 預設的 created_at 與 updated_at 管理。
protected $fillable = [...]
指定哪些欄位可以使用 create() 或 update() 批次寫入。
因此,這份程式可以安全地支援留言的新增、查詢、修改和刪除。
明天就來解釋後端程式碼~