Laravel教程 五:MVC的基本流程
Laravel教程 五:MVC的基本流程
此文章为原创文章,未经同意,禁止转载。
期间受到很多私事影响,终于还是要好好写写laravel的教程了。
上一篇我们说了数据库和Eloquent的基本用法,如计划一样,这一篇文章我们说说Laravel中Model,Controller,Views的工作流程,也就是下面这个顺序:
1.注册路由 ---> 2.创建控制器 ---> 3. 控制器中获取数据库数据 ---> 4.在视图中展示数据
英文的表达可能会更加贴切一点:
1.register routes ---> 2.make a controller ---> 3.fetch data from database ---> 4. load a view to display data
在laravel中,最常见的流程就是这个样子的,我们在实现某个功能的时候,通常就是走上面的这个流程。比如我们这个blog项目中,我们需要实现下面的功能:
1. 展示所有的文章 // blog首页
2. 展示一篇文章 //文章详情页
3. 创建一篇文章 // 文章发布页面
4. 修改一篇文章 // 文章修改页面
5. 删除一篇文章 // 后台管理
在这一篇文章中,我们集中精力解决一下第一个功能,所以我们按照上面的流程来走一遍:
PS : 上次我们使用
artisan tinker
这个工具在命令行中对数据库的数据进行了CRUD,现在就要将这些应用到MVC当中了。
注册路由
我们这里会从头开始,也就是会先删除
app/Http/Controllers/ArticleController.php
这个文件
在系列文章的第二篇当中,我们在app/Http/routes.php
中注册了我们首页的路由:
Route::get('/','ArticleController@index');
可以直接使用这个路由,所以我们可以进入下一步。
创建控制器
这里需要注意的是,如果你使用了
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
Laravel教程 五:MVC的基本流程的更多相关文章
- Laravel 5系列教程五:MVC的基本流程
免费视频教程地址https://laravist.com/series/laravel-5-basic 期间受到很多私事影响,终于还是要好好写写laravel的教程了. 上一篇我们说了数据库和Eloq ...
- Laravel教程 二:路由,视图,控制器工作流程
Laravel教程 二:路由,视图,控制器工作流程 此文章为原创文章,未经同意,禁止转载. View Controller 上一篇教程我们走了那么长的路,终于把Laravel安装好了,这一篇教程我们就 ...
- 2017.3.31 spring mvc教程(二)核心流程及配置详解
学习的博客:http://elf8848.iteye.com/blog/875830/ 我项目中所用的版本:4.2.0.博客的时间比较早,11年的,学习的是Spring3 MVC.不知道版本上有没有变 ...
- Laravel教程 三:视图变量传递和Blade
Laravel教程 三:视图变量传递和Blade 此文章为原创文章,未经同意,禁止转载. Blade 上一篇我们简单地说了Router,Views和Controllers的工作流程,这一次我就按照上一 ...
- Laravel教程 七:表单验证 Validation
Laravel教程 七:表单验证 Validation 此文章为原创文章,未经同意,禁止转载. Laravel Form 终于要更新这个Laravel系列教程的第七篇了,期间去写了一点其他的东西. 就 ...
- 2016 版 Laravel 系列入门教程(三)【最适合中国人的 Laravel 教程】
本教程示例代码见: https://github.com/johnlui/Learn-Laravel-5 在任何地方卡住,最快的办法就是去看示例代码. 在本篇文章中,我们将尝试构建一个带后台的简单博客 ...
- Laravel教程 六:表单 Forms
Laravel教程 六:表单 Forms 此文章为原创文章,未经同意,禁止转载. Form laravel 5.2 之后请使用 laravelcollective/html 替换 illuminate ...
- Laravel教程 四:数据库和Eloquent
Laravel教程 四:数据库和Eloquent 此文章为原创文章,未经同意,禁止转载. Eloquent Database 上一篇写了一些Laravel Blade的基本用法和给视图传递变量的几种方 ...
- Laravel 5 系列入门教程(一)【最适合中国人的 Laravel 教程】
Laravel 5 系列入门教程(一)[最适合中国人的 Laravel 教程] 分享⋅ johnlui⋅ 于 2年前 ⋅ 最后回复由 skys215于 11个月前 ⋅ 17543 阅读 原文发表在 ...
随机推荐
- RelayCommand命令
原文:http://www.cnblogs.com/xiepeixing/archive/2013/08/13/3255152.html 常用Wpf开发中我们在ViewModel中实现INotifyP ...
- Verilog学习笔记基本语法篇(九)········ 任务和函数
task 和 function 说明语句分别用来定义任务和函数,利用任务和函数可以把函数模块分成许多小的任务和函数便于理解和调试.任务和函数往往还是大的程序模块在不同地点多次用到的相同的程序段.输入. ...
- ls -F一种非常有用的ls格式
ls -F一种非常有用的ls格式 tz/y/yupeng > ls -F#q# News/ doc/ images/ mbox ...
- (转载)Apache下error.log文件太大的处理
偶尔发现Apache下的错误日志非常的大,有5G多,先停止Apache服务的所有进程,最简单就是输命令:net stop apache2.4,然后删除 Apache/logs/目录下的 error.l ...
- linux下c++开发环境安装(eclipse+cdt)
方法一: 此外,众所周知,Eclipse是Java程序,因此很容易就实现了跨平台,也是众所周知,Java的大型程序非常吃内存,即使有512MB内存, 仍然感觉Eclipse的启动速度很慢.个人认为1G ...
- StringBuffer类 和 StringBuilder类
上一篇中讲解了String类的用法.那么String有什么特点呢? 字符串特点:字符串是常量,其值在创建后就不能被修改.字符串的内容一旦发生变化,就会创建一个新的对象. 代码验证字符串特点: publ ...
- SilverLight自定义ImageButton
SilverLight中XAML的写法和WPF一样,但是发现在自定义按钮上,没有WPF来的容易,下面说说我制作SilverLight中的ImageButton的一些思路. 在SilverLight中, ...
- http 请求头设置缓存
nginx不缓存设置 2013-08-15 10:47:39 分类: LINUX 在开发调试web的时候,经常会碰到因浏览器缓存(cache)而经常要去清空缓存或者强制刷新来测试的烦恼,提供下apa ...
- HoloLens开发手记 - Unity之Keyboard input 键盘输入
虽然HoloLens支持很多种输入方式,包括蓝牙键盘在内.但是大部分应用还是不能断定用户有物理键盘可以输入,所以虚拟键盘输入还是必须要提供的. Unity提供了一个TouchScreenKeyboar ...
- 嵌入式Linux利用Wifi搭建无线服务器(物联网实践之无线网关)
在 http://www.cnblogs.com/heat-man/p/4564539.html中,在嵌入式Linux开发板上我们从最底层实现了一个智能家居的远程控制系统,然而采取的是用网线连接到交换 ...