1. 程式人生 > >Laravel 系列入門教程(三)【最適合中國人的 Laravel 教程】

Laravel 系列入門教程(三)【最適合中國人的 Laravel 教程】

在本篇文章中,我們將嘗試構建一個帶後臺的簡單部落格系統。我們將會使用到 路由、MVC、Eloquent ORM 和 blade 檢視系統。

簡單部落格系統規劃

我們在教程一中已經新建了一個繼承自 Eloquent Model 類的 Article 類,使用 migration 建立了資料表並使用 seeder 填入了測試資料。我們的部落格系統暫時將只管理這一種資源:後臺需要使用賬號密碼登入,進入後臺之後,可以新增、修改、刪除文章;前臺顯示文章列表,並在點選標題之後顯示出文章全文。

下面我們正式開始。

搭建前臺

前臺的搭建是最簡單的,我先帶大家找找感覺。

修改路由

刪掉

Route::get('/', function
() { return date("Y-m-d H:i:s"); });

Route::get('/home', '[email protected]')->name('home'); 改為 Route::get('/', '[email protected]')->name('home');,現在我們系統的首頁就落到了 App\Http\Controllers\HomeController 類的 index 方法上了。

檢視 HomeController 的 index 函式

將 learnlaravel5/app/Http/Controllers/HomeController.php

 的 index 函式我們之前加的 Exception 那行程式碼刪除,就只剩一行程式碼了:return view('home');,這個很好理解,返回名叫 home 的檢視給使用者。這個檢視檔案在哪裡呢?在 learnlaravel5/resources/views/home.blade.php,blade 是 Laravel 檢視引擎的名字,會對檢視檔案進行加工。

blade 淺析

blade 引擎會對檢視檔案進行預處理,幫我們簡化一些重複性很高的 echo、foreach 等 PHP 程式碼。blade 還提供了一個靈活強大的檢視組織系統。開啟 home.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Dashboard</div>

                <div class="panel-body">
                    @if (session('status'))
                        <div class="alert alert-success">
                            {{ session('status') }}
                        </div>
                    @endif

                    You are logged in!
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

@extends('layouts.app')

這表示此檢視的基檢視是 learnlaravel5/resources/views/layouts/app.blade.php 。這個函式還隱含了一個小知識:在使用名稱查詢檢視的時候,可以使用 . 來代替 / 或 \。

@Section('content') ... @endsection

這兩個識別符號之間的程式碼,會被放到基檢視的 @yield('content') 中進行輸出。

訪問首頁

首先刪除 learnlaravel5/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php 中 dispatch 函式裡我們加的的 var_dump 程式碼,否則會出現奇怪的頁面。
訪問 http://fuck.io:1024 ,不出意外的話,你會看到這個頁面:

為什麼需要登入呢?怎麼去掉這個強制登入呢?刪掉 HomeController 中的建構函式即可:

public function __construct()
{
    $this->middleware('auth');
}

這個函式會在控制器類生成物件後第一時間自動載入一個名為 auth 的中介軟體,正是這一步導致了首頁需要登入。刪除建構函式之後,重新訪問 http://fuck.io:1024 ,頁面應該就會直接出來了。這裡要注意兩點:① 一定要重新訪問,不要重新整理,因為此時頁面的 url 其實是 http://fuck.io:1024/login ② 這個頁面跟之前的歡迎頁雖然看起來一毛一樣,但其實文字是不同的,注意仔細觀察哦。

向檢視檔案輸出資料

既然 Controller - View 的架構已經執行,下一步就是引入 Model 了。Laravel 中向檢視傳資料非常簡單:

public function index()
{    
  return view('home',$assign);
 }

public function index()
{
    return view('home')->withArticles(\App\Article::all());
 }

 

2016 版教程裡很多人看到這段程式碼都十分不解,這裡解釋一下:

  1. \App\Article::all() 是採用絕對名稱空間方式對 Article 類的呼叫。
  2. withArticles 是我定義的方法,Laravel 並不提供,這也是 Laravel 優雅的一個表現:Laravel View 採用 __call 來 handle 對未定義 function 的呼叫,其作用很簡單:給檢視系統注入一個名為 $articles 的變數,這段程式碼等價於 ->with('articles', \App\Article::all())
  3. 展開講一下,->withFooBar(100) 等價於 ->with('foo_bar', 100),即駝峰變數會被完全轉換為蛇形變數。

修改檢視檔案

修改檢視檔案 learnlaravel5/resources/views/home.blade.php 的程式碼為:

@extends('layouts.app')

@section('content')
    <div id="title" style="text-align: center;">
        <h1>Learn Laravel 5</h1>
        <div style="padding: 5px; font-size: 16px;">Learn Laravel 5</div>
    </div>
    <hr>
    <div id="content">
        <ul>
            @foreach ($articles as $article)
            <li style="margin: 50px 0;">
                <div class="title">
                    <a href="{{ url('article/'.$article->id) }}">
                        <h4>{{ $article->title }}</h4>
                    </a>
                </div>
                <div class="body">
                    <p>{{ $article->body }}</p>
                </div>
            </li>
            @endforeach
        </ul>
    </div>
@endsection

 

重新整理,得到:

如果看到以上頁面,恭喜你,Laravel 初體驗成功!

調整檢視

前臺頁面是不應該有頂部的選單欄的,特別是還有註冊、登入之類的按鈕。接下來我們修改檢視內容為:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Learn Laravel 5</title>

    <link href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="//cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
    <script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>

    <div id="title" style="text-align: center;">
        <h1>Learn Laravel 5</h1>
        <div style="padding: 5px; font-size: 16px;">Learn Laravel 5</div>
    </div>
    <hr>
    <div id="content">
        <ul>
            @foreach ($articles as $article)
            <li style="margin: 50px 0;">
                <div class="title">
                    <a href="{{ url('article/'.$article->id) }}">
                        <h4>{{ $article->title }}</h4>
                    </a>
                </div>
                <div class="body">
                    <p>{{ $article->body }}</p>
                </div>
            </li>
            @endforeach
        </ul>
    </div>

</body>
</html>

此檢視檔案變成了一個獨立檢視,不再有基檢視,並且將 jQuery 和 BootStrap 替換為了國內的 CDN,更快更穩定了。

同理我們修改 learnlaravel5/resources/views/layouts/app.blade.php

① 刪除 <script src="{{ asset('js/app.js') }}"></script>
② 替換 <link href="{{ asset('css/app.css') }}" rel="stylesheet"> 為

<link href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

接下來我們來著手搭建後臺。

搭建後臺

生成控制器

我們使用 Artisan 工具來生成控制器檔案及程式碼:

php artisan make:controller Admin/HomeController

成功之後,我們就可以看到 artisan 幫我們建立的資料夾及控制器檔案了:

增加路由

我們要使用路由組來將後臺頁面置於“需要登入才能訪問”的中介軟體下,以保證安全。在 web.php 裡增加下面三行:

Route::group(['middleware' => 'auth', 'namespace' => 'Admin', 'prefix' => 'admin'], function() {
    Route::get('/', '[email protected]');
});

上一篇文章中我們已經接觸到了路由組,這是 Laravel 的另一個偉大創造。路由組可以給組內路由一次性增加 名稱空間、uri 字首、域名限定、中介軟體 等屬性,並且可以多級巢狀,異常強大。路由組中文文件在此:https://d.laravel-china.org/docs/5.5/routing#route-groups

上面的三行程式碼的功能簡單概括就是:訪問這個頁面必須先登入,若已經登入,則將 http://fuck.io:1024/admin 指向 App\Http\Controllers\Admin\HomeController 的 index 方法。其中需要登入由 middleware 定義,/admin 由 prefix 定義,Admin 由 namespace 定義,HomeController 是實際的類名。

構建後臺首頁

新建 index 方法

在新生成的 learnlaravel5/app/Http/Controllers/Admin/HomeController.php 檔案中增加一個 function:

public function index()
{
    return view('admin/home');
}

新建後臺首頁檢視檔案

在 learnlaravel5/resources/views/ 目錄下新建一個名為 admin 的資料夾,在 admin 內新建一個名為 home.blade.php 的檔案,填入程式碼:

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <div class="panel panel-default">
                <div class="panel-heading">Learn Laravel 5 後臺</div>

                <div class="panel-body">

                    <a href="{{ url('admin/article') }}" class="btn btn-lg btn-success col-xs-12">管理文章</a>

                </div>
            </div>
        </div>
    </div>
</div>
@endsection

修改 Auth 系統登陸成功之後的跳轉路徑

修改 learnlaravel5/app/Http/Controllers/Auth/LoginController.php 中相應的程式碼為:

protected $redirectTo = '/admin';

嘗試登入

訪問 http://fuck.io:1024/admin ,它會跳轉到登陸介面,輸入郵箱和密碼之後,你應該會看到如下頁面:

恭喜你,後臺首頁搭建完成!下面我們開始構建 Article 的後臺管理功能。

構建 Article 後臺管理功能

讓我們先嚐試點一下 “管理文章”按鈕,不出意外你將得到一個報錯:

這是 Laravel 5.5 剛剛引入的新策略:404 錯誤不再報告詳細資訊,而是展示一個友好的 404 頁面。

新增路由

404 錯誤是訪問了系統沒有監聽的路由導致的。下面我們要新增針對 http://fuck.io:1024/admin/article 的路由:

Route::group(['middleware' => 'auth', 'namespace' => 'Admin', 'prefix' => 'admin'], function() {
    Route::get('/', '[email protected]');
    Route::get('article', '[email protected]');
});

重新整理,出現詳細報錯資訊了:

進步之道

很多新手看到這個報錯直接就慌了:什麼鬼?全是英文看不懂呀。然後在文章下面把完整的錯誤棧全部粘貼出來。老實說我第一次見到 Laravel 報這個錯也是完全沒耐心去讀,不過我還是複製了最明顯的那句話“Class App\Http\Controllers\Admin\ArticleController does not exist”去 Google 了一下,從此我就再也沒搜尋過它了。

如果你遇到了奇怪的報錯,不要慌,穩住,Google 一下,我們能贏。

新建控制器

上圖中的報錯是控制器不存在。我們使用 Artisan 來新建控制器:

php artisan make:controller Admin/ArticleController

重新整理,錯誤又變了:

index 方法不存在。讓我們新增 index 方法:

public function index()
{
    return view('admin/article/index')->withArticles(Article::all());
}

新建檢視

上面我們已經新建過檢視,現在應該已經輕車熟路了。在 learnlaravel5/resources/views/admin 下新建 article 資料夾,在資料夾內新建一個 index.blade.php 檔案,內容如下:

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <div class="panel panel-default">
                <div class="panel-heading">文章管理</div>
                <div class="panel-body">
                    @if (count($errors) > 0)
                        <div class="alert alert-danger">
                            {!! implode('<br>', $errors->all()) !!}
                        </div>
                    @endif

                    <a href="{{ url('admin/article/create') }}" class="btn btn-lg btn-primary">新增</a>

                    @foreach ($articles as $article)
                        <hr>
                        <div class="article">
                            <h4>{{ $article->title }}</h4>
                            <div class="content">
                                <p>
                                    {{ $article->body }}
                                </p>
                            </div>
                        </div>
                        <a href="{{ url('admin/article/'.$article->id.'/edit') }}" class="btn btn-success">編輯</a>
                        <form action="{{ url('admin/article/'.$article->id) }}" method="POST" style="display: inline;">
                            {{ method_field('DELETE') }}
                            {{ csrf_field() }}
                            <button type="submit" class="btn btn-danger">刪除</button>
                        </form>
                    @endforeach

                </div>
            </div>
        </div>
    </div>
</div>
@endsection

 

重新整理,錯誤又變

 

Article 類不存在?原因很簡單:Article 類和當前控制器類不在一個名稱空間路徑下,不能直接呼叫。解決辦法就是主動匯入 \App\Article 類:

<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

use App\Article;

class ArticleController extends Controller
{
....

 

如果你還不熟悉名稱空間,請閱讀《PHP 名稱空間 解惑》

檢查成果

再次重新整理,你應該能看到如下畫面:

如果你沒到這個畫面也不用擔心,根據錯誤提示去 Google 吧,一定能解決的。

新增、編輯、刪除功能怎麼辦?

這三個功能我將在下一篇教程與大家分享,這是 2015 版 Laravel 教程做的不夠好的地方,其實這裡才是最應該掰開揉碎仔細講解的地方。

轉載他處,侵權聯絡刪除