# Laravel 相關知識整理
上課的時候來不及整理的筆記會用 // 先將重點寫下來,會再找時間慢慢補完,但希望有人跟我一起把這份筆記當共筆寫完它
所以如果有錯誤之類的話也希望大家一起留言討論要怎麼修改並糾正我寫錯的觀念,謝謝<3(尤其是巧婷!!謝謝妳的留言QQQ)
Ref: [https://laravel.tw/docs/5.0](https://laravel.tw/docs/5.0)
* * *
## 遷移結構 Migration
Ref: [https://laravel.tw/docs/5.0/migrations](https://laravel.tw/docs/5.0/migrations)
> 有中文把 Migration 翻成遷移,我覺得不太好理解XD
> 遷移結構是 Laravel 提供定義資料表格式的方式,透過此方式建立的結構可以保持在不同電腦(或資料庫)上資料表的一致性與快速建立資料表的功能
> 白話:遷移結構就像資料表的藍圖,將藍圖產生後放在 Laravel 專案中就可以在更換資料庫時快速地透過藍圖產生結構一致的資料表
### ⭐ 建議的遷移結構命名方式
***註:根據以下的命名方式產生遷移結構時,框架會自動引入有關於資料庫的語法***
| 操作 | 建議命名規則 |
| ---------- | --------------------------------------- |
| 新增資料表 | create_\<table\>\_table |
| 新增欄位 | add\_<field\>\_to\_\<table\>_table |
| 移除欄位 | remove\_<field\>\_from\_\<table\>\_table |
### 基本用法
#### 建立遷移結構
`php artisan make:migration <fileName>`
*註:新建的遷移結構會位於 /database/migrations 底下*
#### 執行遷移
`php artisan migrate`
*註:此指令會執行遷移結構中的 up() 函式*
#### 反向執行遷移
`php artisan migrate:rollback`
*註:此指令會執行遷移結構中的 down() 函式;`down()` 函式應該撰寫與 up() 函式中相反的邏輯*
#### 透過遷移結構重新產生資料表(注意 ❗ 此指令會清空所有資料表的資料!)
`php artisan:refresh`
### 相關函式
```php=
// 新增資料表
Schema::create('news', function (Blueprint $table) {
$table->id();
});
// 移除資料表
Schema::dropIfExists('news');
// 新增欄位
Schema::table('news', function ($table) {
$table->integer('tag');
});
// 移除欄位
$table->dropColumn('tag'); // 單數
$table->dropColumn(['tag', 'title']); // 複數
// 修改欄位
Schema::table('news', function ($table) {
$table->string('tag')->change();
});
// 重新命名欄位
Schema::table('users', function ($table) {
$table->renameColumn('tag', 'tttag');
});
```
### 遷移指令對照表
動作 | 指令 | 反向指令
----|------|-------
新增資料表 | `Schema::create(<table_name>)` | `Schema::dropIfExists(<table_name>)`
移除資料表 |
修改資料型態|`$table->integer('type_id')->change();` 改成integer|`$table->string('type_id')->change();`
### 欄位修飾
除了上述的欄位類型列表,還有一些其它的欄位「修飾」,你可以將它增加至欄位。例如,若要讓欄位「nullable」,那麼你可以使用 nullable 方法:
```
Schema::table('users', function ($table) {
$table->string('email')->nullable();
});
```
修飾 |描述
----|-------------
->first() | 將此欄位放置在資料表的「第一個」(僅限 MySQL)
->after('column') | 將此欄位放置在其他欄位「之後」(僅限 MySQL)
->nullable() | 此欄位允許寫入 NULL 值
->default($value) | 為此欄位指定「預設」值
->unsigned() | 設置 integer 欄位為 UNSIGNED
-[資料來源](https://laravel.tw/docs/5.2/migrations#creating-columns)
### 小知識
- 在執行遷移時會在資料庫中加入一筆 batch 資料紀錄目前的(遷移)堆疊,並且此堆疊會在下次反向執行遷移時被優先移除,舉例來說:
1. 第一次輸入 `migrate` 時使用了 create_A_table 中的 `up()` 函式創建了 A 資料表,此次動作會在資料庫中被記錄為 batch = 1
2. 第二次輸入 `migrate` 時使用了 create_B_table 中的 `up()` 函式創建了 B 資料表,此次動作會在資料庫中被記錄為 batch = 2
3. 輸入 `migrate:rollback`,會由高至低地從 batch 值執行 `down()` 函式,此處的 rollback 會導致 B 資料表被移除,並且在資料庫中抹去執行過 create_B_table 的遷移紀錄,而 A 仍然存在
4. 再次輸入 `migrate:rollback`,執行 create_A_table 中的 `down()` 函式,移除 A 資料表,並且在資料庫中抹去執行過 create_A_table 的遷移紀錄
上述的行為可以簡化成:每次 `migrate` 會使該次執行過的遷移結構 batch +=1,而 `migrate:rollback` 時會從最高的 batch 值開始執行 down() 函式
### 雷
> 執行 `php artisan migrate` 時報錯 Class 'Doctrine\DBAL\Driver\PDOMySql\Driver' not found
解:`composer require doctrine/dbal:2.10`
* * *
## 資料庫模型 Model
Ref: [https://laravel.tw/docs/5.0/eloquent#introduction](https://laravel.tw/docs/5.0/eloquent#introduction)
### 建立資料庫模型
`php artisan make:model <modelName>`
註:新建的模型會位於 /app 底下
###
// insert -> create 但 insert 可繞過 fillable
//
// fillable 代表可被更動,但如果將陣列以外的欄位傳入資料庫則不會報錯,會以資料庫的預設值取代
// guarded 則代表不可寫入
// 透過 Model 新增或修改資料時預設會需要傳入 created_at 與 updated_at 資料庫需要有此兩個欄位
// fillable 不需要將 create_at 與 updated_at 設為白名單
// Model 繼承的方法
* * *
## 路由 Route
> 如果把網站比喻為一座城市,而這城市中包含了許多大大小小的道路,那路由的功能就像是告訴這座城市「如果有人用了OO方式,那就允許他通過這條名為XX的道路」
>
> 在路由中,OO方法指的是來自使用者的請求方式`<method>`(GET, POST, PUT, PATCH, DELETE),XX道路則是指網址`<url>`
### 基本語法
```php=
Route::<method>(<url>, <controller>)
```
### 群組 Group
> 群組可以管理擁有相同路徑的路由
```php=
<?php
// 尚未群組化的路由
Route::get('/news', 'NewsController@index');
Route::get('/news/delete/{id}/', 'NewsController@delete');
Route::get('/news/create', 'NewsController@createForm');
Route::get('/news/update/{id}', 'NewsController@updateForm');
Route::get('/news/{id}', 'NewsController@content');
Route::post('/news/create', 'NewsController@create');
Route::post('/news/update/{id}', 'NewsController@update');
?>
```
```php=
<?php
// 群組化過的路由
Route::prefix('news')->group(function () {
Route::get('/', 'NewsController@index');
Route::get('/delete/{id}/', 'NewsController@delete');
Route::get('/create', 'NewsController@createForm');
Route::get('/update/{id}', 'NewsController@updateForm');
Route::get('/{id}', 'NewsController@content');
Route::post('/create', 'NewsController@create');
Route::post('/update/{id}', 'NewsController@update');
});
// 也可以這樣寫
Route::group(['prefix' => 'news'],function () {
Route::get('/', 'NewsController@index');
Route::get('/delete/{id}/', 'NewsController@delete');
Route::get('/create', 'NewsController@createForm');
Route::get('/update/{id}', 'NewsController@updateForm');
Route::get('/{id}', 'NewsController@content');
Route::post('/create', 'NewsController@create');
Route::post('/update/{id}', 'NewsController@update');
});
?>
```
### 與路由有關聯的知識
#### 瀏覽網頁是 GET
> 使用者的網址列每一次改變時,都會透過瀏覽器自動地向伺服器使用 `GET` 方法請求該網址,這也是為什麼在上述的寫法中只需要使用 `Route::get` 就可以向使用者呈現畫面的原因
#### 路由的設計
##### 課堂上設計方式
- CRUD
- 讀取:`GET` -> /news/{id}
- 建立:`POST` -> /news/create
- 更新:`POST` /news/{id}/update
- 刪除:`POST` /news/{id}/delete
##### RESTful
> RESTful 是一種路由的設計模式,其主要設計方式是將動詞從網址上抽離,並將這些動詞作為發送請求時的方法
>
> Laravel 也提供了一個快速建立路由的方法:
> `Route::resource('<uri>', '<controller>');`
> 透過 resource 方法開啟的路由也充分地使用了 Restful 的設計模式
- 透過 `resource` 方法開啟的路由會以下方式表現
- 讀取:`GET` -> /news/{id}
- 建立頁面:`GET` -> /news/create
- 建立:`POST` -> /news
- 更新頁面:`GET` -> /news/{id}/edit
- 更新:`PUT/PATCH` /news/{id}
- 刪除:`DELETE` /news/{id}
#### 關於 \<form\> 表單
\<form\> 表單是網頁裡其中一種與後端溝通的方式,表單在送出時只能夠選擇使用 `GET` 與 `POST` 兩種方法(`action` 屬性的值就是請求方法),並根據用途粗略地分為:
- 「如果只讀取或傳遞簡單資料用 `GET`」
- 「如果要傳遞大量或機密資料則用 `POST`」
`GET` 與 `POST` 在傳遞資料上的實作也有點不同,但為了專注在路由上所以只先討論其用途而非功能上的差異
另外 Laravel 也提供我們一種改變 `<form>` 表單請求動作的方式,在標籤內加入 `@method(<method>)` 就可以讓表單也能使用 `PUT` 與 `DELETE` 等方式,但千萬要記得表單原生的屬性 `method="POST"` 不可省略。
```htmlembedded=
<form method="POST">
@method('PUT');
</form>
```
// resource
// route:list
###### tags: `Laravel` `Dahis`