Laravel教程 五:MVC的基本流程

Laravel教程 五:MVC的基本流程

此文章爲原創文章,未經贊成,禁止轉載。php

期間受到不少私事影響,終於仍是要好好寫寫laravel的教程了。css

上一篇咱們說了數據庫和Eloquent的基本用法,如計劃同樣,這一篇文章咱們說說Laravel中Model,Controller,Views的工做流程,也就是下面這個順序:laravel

1.註冊路由 ---> 2.建立控制器 ---> 3. 控制器中獲取數據庫數據 ---> 4.在視圖中展現數據 

英文的表達可能會更加貼切一點:git

1.register routes ---> 2.make a controller ---> 3.fetch data from database ---> 4. load a view to display data 

在laravel中,最多見的流程就是這個樣子的,咱們在實現某個功能的時候,一般就是走上面的這個流程。好比咱們這個blog項目中,咱們須要實現下面的功能:github

1. 展現全部的文章 // blog首頁 2. 展現一篇文章 //文章詳情頁 3. 建立一篇文章 // 文章發佈頁面 4. 修改一篇文章 // 文章修改頁面 5. 刪除一篇文章 // 後臺管理 

在這一篇文章中,咱們集中精力解決一下第一個功能,因此咱們按照上面的流程來走一遍:sql

PS : 上次咱們使用artisan tinker這個工具在命令行中對數據庫的數據進行了CRUD,如今就要將這些應用到MVC當中了。chrome

註冊路由

咱們這裏會從頭開始,也就是會先刪除app/Http/Controllers/ArticleController.php這個文件數據庫

在系列文章的第二篇當中,咱們在app/Http/routes.php中註冊了咱們首頁的路由:json

Route::get('/','ArticleController@index'); 

能夠直接使用這個路由,因此咱們能夠進入下一步。api

建立控制器

這裏須要注意的是,若是你使用了Homestead,請先ssh登陸到你的虛擬機中執行命令;還有就是,請先刪除以前課程遺留的ArticleController,若是你想偷懶,能夠跳過這一步

建立控制器的時候你能夠手動建立,不過仍是推薦使用artisan這個命令行工具,在項目目錄之下,命令行執行:

php artisan make:controller ArticleController --plain 

這裏須要說明的是--plain這個參數代表只要一個簡單的controller,裏面不須要生成一堆如show(),create()等方法。

控制器中獲取數據庫數據

打開這個從新建立的ArticleController.php:

class ArticleController extends Controller { public function index() { $articles = Article::all(); return $articles; } } 

咱們建立一個index()方法,這是由於咱們在routes.php當中註冊的路由指定要加載ArticleControllerindex()方法,咱們在index()方法中使用Article::all()將數據庫中articles這張表中的全部的記錄查找出來,直接返回。

咱們用瀏覽器來訪問試試,會看到相似下面這個狀況:

替代文字

對,如你看到的同樣,若是你直接返回查找到得數據,Laravel會默認將這些數據轉換成json格式,由於laravel多是出於這樣的考慮:通常這種狀況下地返回,一般都是在建立api功能,好比你爲你的一個手機App寫的api同樣,json數據無疑是很好的選擇。

順便安利一下你們使用百度團隊的這個FeHelper這個chrome插件:

https://github.com/zxlie/FeHelper

可是在這裏咱們並非想直接返回json,取而代之的是,咱們的目的是加載視圖,將數據展現出來。因此這就是咱們下一步的工做了

在視圖中展現數據

這裏咱們首先須要修改的是ArticleController中的index()方法:

public function index() { $articles = Article::all(); return view('articles.index',compact('articles')); } 

咱們只是修改了return這一行的代碼,使用view()方法加載視圖,這個視圖就是位於resources/views/articles/中的index.blade.php(咱們尚未建立),最後使用compact('articles')將數據傳給視圖文件:關於這個視圖傳遞變量的問題,你能夠參考教程的第三篇

而後,咱們須要建立咱們的視圖文件,在resources/views/articles/下建立index.blade.php文件:

@extends('app') @section('content') <h1>這是index.blade.php</h1> @endsection 

寫上上面的內容,關於視圖文件的blade模板,能夠參考教程的第三篇,而後瀏覽器訪問一下看看:

替代文字

視圖文件正確以後,咱們須要將傳遞給視圖的$articles變量的內容展現出來:

@extends('app') @section('content') @foreach($articles as $article) <h1>{{ $article->title }}</h1> <p>{{ $article->intro }}</p> <hr> @endforeach @endsection 

咱們使用@foreach來將全部的文章循環出來,瀏覽器訪問看看:

替代文字

這裏咱們的首頁展現也就基本完成了,然而在咱們的實際blog中,咱們會在每一個標題出給出咱們的文章連接,也就是爲每一個文章添加一個詳情展現的頁面,用戶點擊文章的連接以後,咱們展現相應的文章詳情。咱們來實現這個功能

顯示文章詳情

經過文章展現來快速體驗上面的流程:

1.註冊路由

來到app/Http/routes.php中,咱們增長一個路由:

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

上面的路由articles/{id}指定咱們須要加載ArticleController中的show()方法。這裏須要注意的是{id}這個表達:這是表示id是一個路由變量,也就是當咱們訪問相似下面這兩個路由的時候:

http://blog.dev/articles/1 //id 爲1 http://blog.dev/articles/foo // id爲foo 

先不急着訪問,由於咱們尚未建立show()方法,這裏只是做爲說明。

在laravel中,路由變量寫在{}括號中,這個id對應咱們等下寫的show()方法的參數。

2.編寫show()

在ArticleController增長show()方法:

public function show($id) { return $id; } 

咱們在show($id)方法中,首先接受參數id,而後直接返回。如今咱們能夠訪問上面的兩個url了,看到的相似下面這個效果:

替代文字

3.獲取數據

然而在show()方法中,咱們也是須要從數據庫中加載獲取數據,因此咱們先修改show()方法:

public function show($id) { $article = Article::find($id); return $article; } 

咱們經過find()方法從數據庫中查找一條記錄,而後直接返回,咱們來看看效果:

替代文字

4.加載視圖

獲取數據以後,咱們須要加載相應地視圖來展現數據,仍是修改show()方法:

public function show($id) { $article = Article::find($id); return view('articles.show',compact('article')); } 

相似地,咱們使用view()加載show.blade.php,而後compact()將變量傳遞過去。因此咱們去建立show.blade.php視圖文件吧:

@extends('app') @section('content') <h1>{{ $article->title }}</h1> <hr> <p>{{ $article->content }}</p> @endsection 

這裏跟index.blade.php視圖文件差很少,咱們只是去掉了@foreach,在來訪問一下看看:

替代文字

到這裏,咱們的文章展現頁面也能夠說是完成了,然而當咱們訪問這個下面這個連接的時候:

http://blog.dev/articles/3 

報錯了!

替代文字

這是由於咱們在show()方法中使用$article = Article::find($id);來查找一篇文章,可是咱們的數據庫中的articles表並無id3的記錄,也就是id3的時候,$article變量已是null了,這個時候咱們若是仍是但願在視圖中使用{{ $article->title }},因此纔會出現錯誤:

Trying to get property of non-object.... 

PS: 若是你想調試,看看$article究竟是什麼,你能夠在laravel中使用dd($article)來調試

那這個要怎麼解決呢?有兩種方法:

第一,本身寫個if條件判斷:

public function show($id) { $article = Article::find($id); if(is_null($article)){ abort(404); } return view('articles.show',compact('article')); } 

若是$article爲空,直接abort()一個404頁面。再來訪問一下:

替代文字

這裏貌似仍是會看到一堆錯誤,爲何呢?那是由於在.env中咱們設置了APP_DEBUG=true,因此還會有下面的一堆錯誤,咱們在實際的線上部署環境中,APP_DEBUG=false纔是咱們的設置。咱們來體驗一把將APP_DEBUG=false,見證一下咱們的404頁面:

替代文字

這個404頁面,你能夠自定義:就是在resources/views/errors/文件夾下建立一個404.blade.php

實際例子就是這樣的(彩蛋):

https://jellybool.com/show404page

你也能夠在個人blog地址欄隨便輸入一堆東西,看看找不到文章的時候是什麼樣的404 page 。

第二,使用findOrFail()

上面的條件判斷其實很不錯了,可是這裏我仍是推薦使用findOrFail()這個方法:

public function show($id) { $article = Article::findOrFail($id); return view('articles.show',compact('article')); } 

findOrFail()表示首先嚐試find,若是找不到就fail,拋出一個Eloquent Exception,因此咱們再來訪問嘗試一下:

替代文字

咱們應該會獲得同樣的結果.

而後咱們回到咱們的index.blade.php中爲每篇文章添加連接:

@foreach($articles as $article) <h1><a href="/articles/{{ $article->id }}">{{ $article->title }}</a></h1> <p>{{ $article->intro }}</p> <hr> @endforeach 

訪問來看看:

替代文字

注意咱們這裏直接使用了href="/articles/{{ $article->id }}"進行連接,你也可使用action()這個方法:

@foreach($articles as $article) <h1><a href="{{ action('ArticleController@show',[$article->id]) }}">{{ $article->title }}</a></h1> <p>{{ $article->intro }}</p> <hr> @endforeach 

action()這個方法第一個參數代表要加載ArticleControllershow()方法,跟routes同樣,第二個參數用數組傳入相應地參數[$article->id]

你還有第三種選擇,使用url()方法:

@foreach($articles as $article) <h1><a href="{{ url('articles/',$article->id) }}">{{ $article->title }}</a></h1> <p>{{ $article->intro }}</p> <hr> @endforeach 

url()方法第一個參數傳入url路徑,第二個參數直接傳入變量。

上面的三種方法,選擇一種本身喜歡的就能夠了。

下一節

就寫到這裏吧,這一節大概也就是這樣的內容了,不知道這樣介紹,你們對Laravel的Model Controller Views的工做流程清晰了沒,不清晰的話能夠評論問我。。。

下一節,我即將說說怎麼實現建立一篇文章,就會順帶介紹Laravel的Forms表單。

最後,

Happy Hacking

相關文章
相關標籤/搜索