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


本教程示例代碼見: https://github.com/johnlui/Learn-Laravel-5

在任何地方卡住,最快的辦法就是去看示例代碼。

本文是本系列教程的完結篇,我們將一起給 Article 加入評論功能,讓游客在前台頁面可以查看、提交、回復評論,並完成后台評論管理功能,可以刪除、編輯評論。Article 和評論將使用 Laravel Eloquent 提供的“一對多關系”功能大大簡化模型見關系的開發復雜度。最終,我們將得到一個個人博客系統的雛形,並布置一個大作業,供大家實戰練習。

本篇文章中我將會使用一些 Laravel 的高級功能,這些高級功能對新手理解系統是不利的,但卻可以進一步提高熟手的開發效率。

回顧 Eloquent

前面我們已經說過,Laravel Eloquent ORM 是 Laravel 中最強大的部分,也是 Laravel 能如此流行最重要的原因。中文文檔在: http://laravel-china.org/docs/5.1/eloquent

learnlaravel5/app/Article.php 就是一個最簡單的 Eloquent Model 類:

<?php

namespace App; use Illuminate\Database\Eloquent\Model; class Article extends Model { // }

若想進一步了解 Eloquent,推薦閱讀系列文章: 深入理解 Laravel Eloquent

開始構建評論系統

基礎規划

我們需要新建一個表專門用來存放數據庫,每條評論都屬於某一篇文章。評論之間的層級關系比較復雜,本文為入門教程,主要是為了帶領大家體驗模型間關系,就不在做過多的規划,將“回復別人的評論”暫定為簡單的在評論內容前面增加@john 這樣的字符串。

建立 Model 類和數據表

創建名為 Comment 的 Model 類,並順便創建附帶的 migration,在 learnlaravel5 目錄下運行命令:

php artisan make:model Comment -m

這樣一次性建立了 Comment 類和 2016_06_03_220325_create_comments_table 兩個文件。修改 migration 文件的 up 方法為:

public function up()
{
    Schema::create('comments', function (Blueprint $table) { $table->increments('id'); $table->string('nickname'); $table->string('email')->nullable(); $table->string('website')->nullable(); $table->text('content')->nullable(); $table->integer('article_id'); $table->timestamps(); }); }

之后運行命令:

php artisan migrate

去數據庫里瞧瞧,comments 表已經躺在那兒啦。

建立“一對多關系”

在 Article 模型中增加一對多關系的函數:

<?php

namespace App; use Illuminate\Database\Eloquent\Model; class Article extends Model { public function hasManyComments() { return $this->hasMany('App\Comment', 'article_id', 'id'); } }

搞定啦!Eloquent 中模型間關系就是這么簡單!

構建前台 UI

讓我們修改前台的視圖文件,想辦法把評論功能加入進去。

創建前台的 ArticleController 類

運行命令:

php artisan make:controller ArticleController

增加路由:

Route::get('article/{id}', 'ArticleController@show');

此處的 {id} 指代任意字符串,在我們的規划中,此字段為文章 ID,為數字,但是本行路由卻會嘗試匹配所有請求,所以當你遇到了奇怪的路由調用的方法跟你想象的不一樣時,記得檢查路由順序。路由匹配方式為前置匹配:任何一條路由規則匹配成功,會立刻返回結果,后面的路由便沒有了機會。

給 ArticleController 增加 show 函數:

public function show($id) { return view('article/show')->withArticle(Article::with('hasManyComments')->find($id)); }

創建前台文章展示視圖

新建 learnlaravel5/resources/views/article/show.blade.php 文件:

<!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.2.0/css/bootstrap.min.css" rel="stylesheet"> <script src="//cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script> <script src="//cdn.bootcss.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> </head> <div id="content" style="padding: 50px;"> <h4> <a href="/"><< 返回首頁</a> </h4> <h1 style="text-align: center; margin-top: 50px;">{{ $article->title }}</h1> <hr> <div id="date" style="text-align: right;"> {{ $article->updated_at }} </div> <div id="content" style="margin: 20px;"> <p> {{ $article->body }} </p> </div> <div id="comments" style="margin-top: 50px;"> @if (count($errors) > 0) <div class="alert alert-danger"> <strong>操作失敗</strong> 輸入不符合要求<br><br> {!! implode('<br>', $errors->all()) !!} </div> @endif <div id="new"> <form action="{{ url('comment') }}" method="POST"> {!! csrf_field() !!} <input type="hidden" name="article_id" value="{{ $article->id }}"> <div class="form-group"> <label>Nickname</label> <input type="text" name="nickname" class="form-control" style="width: 300px;" required="required"> </div> <div class="form-group"> <label>Email address</label> <input type="email" name="email" class="form-control" style="width: 300px;"> </div> <div class="form-group"> <label>Home page</label> <input type="text" name="website" class="form-control" style="width: 300px;"> </div> <div class="form-group"> <label>Content</label> <textarea name="content" id="newFormContent" class="form-control" rows="10" required="required"></textarea> </div> <button type="submit" class="btn btn-lg btn-success col-lg-12">Submit</button> </form> </div> <script> function reply(a) { var nickname = a.parentNode.parentNode.firstChild.nextSibling.getAttribute('data'); var textArea = document.getElementById('newFormContent'); textArea.innerHTML = '@'+nickname+' '; } </script> <div class="conmments" style="margin-top: 100px;"> @foreach ($article->hasManyComments as $comment) <div class="one" style="border-top: solid 20px #efefef; padding: 5px 20px;"> <div class="nickname" data="{{ $comment->nickname }}"> @if ($comment->website) <a href="{{ $comment->website }}"> <h3>{{ $comment->nickname }}</h3> </a> @else <h3>{{ $comment->nickname }}</h3> @endif <h6>{{ $comment->created_at }}</h6> </div> <div class="content"> <p style="padding: 20px;"> {{ $comment->content }} </p> </div> <div class="reply" style="text-align: right; padding: 5px;"> <a href="#new" onclick="reply(this);">回復</a> </div> </div> @endforeach </div> </div> </div> </body> </html>

構建評論存儲功能

我們需要創建一個 CommentsController 控制器,並增加一條“存儲評論”的路由。運行命令:

php artisan make:controller CommentController

控制器創建成功,接下來我們增加一條路由:

Route::post('comment', 'CommentController@store');

給這個類增加 store 函數:

public function store(Request $request)
{
    if (Comment::create($request->all())) { return redirect()->back(); } else { return redirect()->back()->withInput()->withErrors('評論發表失敗!'); } }

批量賦值

我們采用批量賦值方法來減少存儲評論的代碼, 批量賦值中文文檔 。

給 Comment 類增加 $fillable 成員變量:

protected $fillable = ['nickname', 'email', 'website', 'content', 'page_id'];

檢查成果

前台文章展示頁:

提交幾條評論之后:

恭喜你,前台評論功能構建完成!

【大作業】構建后台評論管理功能

評論跟 Article 一樣,是一種可以管理的資源列表。2015 版教程的最后,我風風火火地羅列了一堆又一堆的代碼,其實對讀者寶寶們幾乎沒有作用。在此,我將這個功能作為大作業布置給大家。大作業嘛,當然是沒有標准答案的,不過我還是提供效果圖給寶寶們:

在做這個大作業的過程中,你將會反復地回頭去看前面的教程,反復地閱讀中文文檔,會仔細閱讀我的代碼,等你完成大作業的時候,Laravel 5 就真正入門啦~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM