此文章为原创文章,未经赞成,禁止转载。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
当中注册的路由指定要加载ArticleController
的index()
方法,咱们在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
表并无id
为3
的记录,也就是id
为3
的时候,$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()
这个方法第一个参数代表要加载ArticleController
的show()
方法,跟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