前言

承接上一篇 [Laravel筆記 01] Laravel8 入門及環境安裝

本篇將以頁面顯示、Route 設定為主

假設你自己擁有滿足了上一篇所有的安裝設定,同時我再重建一下我的習慣

平時習慣把php project都放在 ~/php ,即 使用者名稱/php,本次測試會建立名為 test01 的project都放在

2. 啟動Project

2.1用artisan開啟server
cd ~/php/test01
php artisan serve

有關artisan本文最後再簡介一下

2.2 用npm watch前端文件

打開第2個 Terminal,安裝npm 套件並同叫 run watch

cd ~/php/test01
npm i & npm run watch
2.3 有關這2個 Terminal

這2個 Terminal 需要長期開著,第1個以你的php server,而第2個就是利用nodejs來監察你的前端文件,每次你save後就會自動更新你的css、js等文件

同時打開瀏覽器 前往:http://127.0.0.1:8000/
第一個 Terminal 其實是有網址的,如果8000被佔了會自己派8001給你,如此類推

能成功顯示 Larave 預設的welcome 頁面就成功了初始化安裝

如果你十分執著想要取回8000port,可參考這篇文章:
MAC 檢查使用中的PORT 是什麼PID

3. 建立第一個 controller 、blade文件、設定Route

3.1 建立controller文件

用 vscode 打開 ~/php/test01
輸入

php artisan make:controller TestdbController

建立了 app/Http/Controllers/TestdbController.php

確定一系class name 是否你自己想要的,可自行修改
並嘗試加入第1個function,把文件改成

namespace App\Http\Controllers;

class TestdbController extends Controller {
    function index() {
        return view('testdb.index');
    }
}
3.2 設定 route

前往 routes/web.php

頂部輸入這行

use Illuminate\Http\Request;

文件尾部輸入這行

Route::resource('testdb', TestdbController::class);

這只是習慣,你喜歡兩行放在一起都可以

3.3 建立blade模板文件前往

resources/views/
建立folder testdb,並在里面建立一個 index.blade.php

修改 resources/views/testdb/index.blade.php,直接輸入

Hello, Test Blade

瀏覽 http://127.0.0.1:8000/testdb

成功見到

Hello, Test Blade

3.4 嘗試在頁面中加入變數

修改 TestdbController.php

  1. 引入 Request
  2. index function 中引入 Request
  3. Request 拿到的值經 view() 傳去頁面
input('user_name');
        return view('testdb.index', [
            'user' => $user_name,
        ]);
    }
}

前往修改 testdb/index.blade.php,改為

Hello, {{$user}}

瀏覽 http://127.0.0.1:8000/testdb?user_name=peter

頁面顯示

Hello, peter

3.5 在blade文件中嘗試用if
@if($user)

Hello, {{$user}}

@else

Hello, All

@endif @endif

當你有沒有輸入 $user_name 都能正常顯示

3.6 網址中有辦法不用 ?

不喜歡用 ?user_name=xxx,那麼你需要用到show function

function show($user_name) {
        return view('testdb.user', [
            'user' => $user_name,
        ]);
    }

建立並修改 resources/views/testdb/user.blade.php,這邊的檔案名是基於 controller 中 view() 的第一個值

{{$user}} Profile

這樣一來就可是直接用這樣的網址
http://127.0.0.1:8000/testdb/peter
http://127.0.0.1:8000/testdb/mary
甚至中文也是支援的
http://127.0.0.1:8000/testdb/陳大明

如果你想用 http://127.0.0.1:8000/user/peter ?

那應該考慮建另一個controller,一個網站中是有n個controller的,又或者可參考下面的 4.4 Route::get 設定

4.Route 其他的方式

補充,以面所有route暫時都是在 routes/web.php操作

4.1 Route::redirect 設定

平常的經想想到的301轉跳、301redirect就是這個

Route::redirect('/aaa', '/shop');

瀏覽http://127.0.0.1:8000/aaa
會自己redirect至 http://127.0.0.1:8000/shop

第3個數值

Route::redirect('/aaa', '/shop',301);
Route::redirect('/bbb', '/shop',302);

你用 /bbb/aaa 前往測試都會去到 /shop

但如果你細心查看瀏覽器中的DevTools-> Network,會看到status 兩者是不一樣的

301是永久轉跳,而302是臨時轉跳,有時你直接設定了301轉跳後發現不是自己要的效果,要再修改一次,可能需要換個瀏覽器或者重開瀏覽器才有效

個人建議不熟的話可先用302試一試是否自己要的效果,確定是這樣的話,再設定為301。

那麼明明302比301方便,為什麼要選301? 那就是SEO的話題了,另外,反正你真的想要這樣轉呎,永久轉跳又有什麼不好呢?

官方還提供了一個直接是301轉跳的function
以下的代碼是已經包含了301的,跟上面在第3個值輸入301 是一樣的效果

Route::permanentRedirect('/ccc', '/shop');
4.2 Route::view 設定

上面我在 routes/web.php 是使用 Route::resource來設定,其實是方便操作數據庫,因為下一篇就是跟數據庫有關的

Route::resource('testdb', TestdbController::class);

但除了Route::resource,還有其他更直接的方法,甚至可直接跳過Controller,下面我們做個簡單的測試

在不建立Controller的情況下,我們去 routes/web.php 直接添加以下這句

Route::view('/shop', 'shop');

再強調一次,在不建立Controller的情況下,我們前往resources/views/ 建立一個名為 shop.blade.php的模板文件,並進行修改

修改 resources/views/testdb/user.blade.php

Welcome to Shop

瀏覽http://127.0.0.1:8000/shop

會見到

Welcome to Shop

4.3 在Route::view嘗試加些數值?

routes/web.php 內修改為

Route::view('/shop', 'shop',['shop_name' => 'IT Shop']);

修改 resources/views/testdb/user.blade.php

Welcome to {{$shop_name}}

瀏覽http://127.0.0.1:8000/shop

會見到

Welcome to IT Shop

個人用處:
Route::view可用在小型網站,為Aboust Us 等頁面做Route設定頗為方便的,因為這類頁面未必有什麼運算,基本上都是直接讀取模板內容,甚至未必需要寫在數據庫

但,在 routes/web.php設定直接輸入設個人不太清楚有什麼用?
因為routes/web.php給我的感覺是入口文件,應該盡量用最少的內容令網站運作更快。

4.4 Route::get 設定

上面提供Route::view不明加數值有什麼,其實就是因為有Route::get 的存在!

routes/web.php 內修改為

Route::get('/product/{id}', function ($id) {
    return 'Product ID:  '.$id;
});

瀏覽 http://127.0.0.1:8000/product/food123

得到

Product ID: food123

你還可以做一些預設值

Route::get('/product/{id}', function ($id = '100') {
    return 'Product ID:  '.$id;
});

如果你這頁面是經其他route callback 進來的,應該把Request加入,同時要把對應文件引入

use Illuminate\Http\Request;
Route::get('/product/{id}', function (Request $request, $id) {
    return 'Product ID:  '.$id;
});

你可以用「Regular 正則表達式」做一些驗證限制

Route::get('/product/{name}', function ($name) {
    //show some thing
})->where('name', '[A-Za-z]+');

Route::get('/product/{id}', function ($id) {
    //show some thing
})->where('id', '[0-9]+');

Route::get('/product/{id}/{name}', function ($id, $name) {
    //show some thing
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

還有一些常用的驗證限制

Route::get('/user/{id}/{name}', function ($id, $name) {
    //
})->whereNumber('id')->whereAlpha('name');

Route::get('/user/{name}', function ($name) {
    //
})->whereAlphaNumeric('name');

Route::get('/user/{id}', function ($id) {
    //
})->whereUuid('id');

還有其他的function,比如Route::match Route::any

Routing 還有很多東西,詳細可參閱官方的: Laravel Routing

4.5 Route::resources 補充

上面第3部分已把Route::resources 用了,我需要在第4部分把route都介紹了一下,最後再補充Route::resources

Verb URI Action Route Name
GET /photos index photos.index
GET /photos/create create photos.create
POST /photos/ store photos.store
GET /photos/{photo} show photos.show
GET /photos/{photo}/edit edit photos.edit
PUT/PATCH /photos/{photo} update photos.update
DELETE /photos/{photo} destroy photos.destroy

以上這些是官方預設的Action,相信你應該明白/photos 是個例子名稱

參考官方:Actions Handled By Resource Controller

4.6 Route::resources 配合 Route::get 一起使用

上一段 4.5 我們說到官方對於Route::resources 是有預設action預設route name

那麼如果在Controller 自定義一個function要怎麼做Route?

我們拿第3部分的TestdbController做例子

去route文件,在原有的Route::resources 「上面」 加一行 Route::get

即修改為

Route::get('testdb/custom', [TestdbController::class, 'custom']);
Route::resource('testdb', TestdbController::class);

建立blade模版文件 resources/views/testdb/custom.blade.php

Custom Function Route

{{$content}}

修改app/Http/Controllers/TestdbController.php,新增一個function

function custom() {
    $str = 'Hello, ';
    $user_name = "Peter";
    $content = $str . $user_name;
    return view('testdb.custom', [
    '   content' => $content,
    ]);
}

瀏覽:http://127.0.0.1:8000/testdb/custom
得到

Custom Function Route
Hello, Peter

只要你能自己建立一個Controller + 自定義Route,其實你已經做到整個完整網站出來了,上面的例子已經證明了,只要你在自己的function 做了任何整合及運算,最終把內容輸入到 view() 就可以把內容傳送到blade 顯示出來

後記

很重要再強調一次,我是喜歡深入淺出的學習模式,先跟我說最終會是什麼樣,或者大約工作模式及流程是什麼樣的,然後再把基礎的東西學習一次
這篇一口氣把ControllerBladeRoute 同時介紹,的確很難把他們分開,因為分開了看其實根本就沒有學習價值,你們也不可以單獨使用一項而完成一個網站。

可能這篇中把 Route 示範得較多,因為我認為 Controller 其實就是我們平時用的PHP,只是把不同的內容經view()傳送給模板。
Blade 就只是一套模板而已,我沒有什麼好演示的,反而大家看文檔及親手測試才是模板系統最能理解到的方法,如果後面有需要,我會再詳細分享一下

Controller – MVC 中的C(Controller),管理系統的流程、邏輯
https://laravel.com/docs/8.x/controllers

Blade – MVC中的V,view ,模板系統
https://laravel.com/docs/8.x/views

Route – 配合blade模板系統、Controller,管理整個網站的網址及入口
https://laravel.com/docs/8.x/routing

上面提到的MVC中的M 是Model,在後台會詳細分享的,比較進階,可能會後面再出現,甚至在小型的project我未必會用上

下一篇將會跟數據庫做連接