2016 版 Laravel 系列入门教程(四)【最适合中国人的 Laravel 教程】
本教程示例代码见: https://github.com/johnlui/Learn-Laravel-5
在任何地方卡住,最快的办法就是去看示例代码。
本篇文章中,我将跟大家一起实现 Article 的新增、编辑和删除功能,仔细解读每一段代码,相信本篇文章看完,你就能够 get Laravel 使用之道。
RESTful 资源控制器
资源控制器是 Laravel 内部的一种功能强大的约定,它约定了一系列对某一种资源进行“增删改查”操作的路由配置,让我们不再需要对每一项需要管理的资源都写 N 行重复形式的路由。中文文档见:http://www.golaravel.com/laravel/docs/5.1/controllers/#restful-resource-controllers
我们只需要写一行简单的路由:
Route::resource('photo', 'PhotoController');
就可以得到下面 7 条路由配置:

左边是 HTTP 方法,中间是 URL 路径,右边是 控制器中对应的函数,只要某个请求符合这七行中某一行的要求,那么这条请求就会触发最后一列的方法。这是 Laravel 对于 RESTful 的规范,它不仅仅帮我们省去了几行路由配置代码,更是如何合理规划 URL 的指路明灯,相信你会从中学到很多。
下面我们正式开始一项一项地实现 Article 的新增、编辑、删除功能:
开始行动
配置资源路由
将当前路由配置中的 Route::get('article', 'ArticleController@index'); 改成 Route::resource('article', 'ArticleController'); ,哦了。
新增 Article
新增一篇文章需要两个动作:第一步,获取“新增Article”的页面;第二步,提交数据到后端,插入一篇文章到数据库。
获取“新增Article”的页面
第二行路由可以满足我们的需求:

那下一步就明了了,在 ArticleController 中新增 create 方法,放回一个可以输入文章的页面:
ArticleController 中:
public function create()
{
return view('admin/article/create');
}
新增视图文件learnlaravel5/resources/views/admin/article/create.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">
<strong>新增失败</strong> 输入不符合要求<br><br>
{!! implode('<br>', $errors->all()) !!}
</div>
@endif
<form action="{{ url('admin/article') }}" method="POST">
{!! csrf_field() !!}
<input type="text" name="title" class="form-control" required="required" placeholder="请输入标题">
<br>
<textarea name="body" rows="10" class="form-control" required="required" placeholder="请输入内容"></textarea>
<br>
<button class="btn btn-lg btn-info">新增文章</button>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
点击文章管理页面最上面的“新增”按钮,你将得到以下页面:

视图调用
上文中我使用 return view('admin/article/create'); 返回了视图文件。
view() 方法是 Laravel 中一个全局的方法,用于调用视图文件,他接受一个字符串参数,并会按照这个参数去调取对应的路由,这很容易理解。实际上'admin/article/create' 跟 'admin.article.create' 是等价的,而且看起来后者更加优雅,不过本宝宝十分推荐前者。代码优雅是好事儿,不过本质上代码是写给人看的,一切提高代码理解成本的行为都是错误的。
提交数据到后端
“新增Article”的页面已经展示出来,下一步就是提交数据到后端了,理解提交数据,要从表单开始。
表单
视图文件中有一个表单:
<form action="{{ url('admin/article') }}" method="POST">
{!! csrf_field() !!}
<input type="text" name="title" class="form-control" required="required" placeholder="请输入标题">
<br>
<textarea name="body" rows="10" class="form-control" required="required" placeholder="请输入内容"></textarea>
<br>
<button class="btn btn-lg btn-info">新增文章</button>
</form>
这是一个非常普通的 form 表单,只有两点需要我们费点心思去理解。
第一,表单的 action。form 是 HTML 规范,在点击了表单中的提交按钮后,浏览器会使用 method 方法将某些数据组装好发送给 action,这里我们动态生成了一个 URL 作为 action,并且指定了表单提交需要使用 POST 方法。
第二,csrf_field。这是 Laravel 中内置的防止应对 CSRF 攻击的防范措施,任何 POST PUT PATCH 请求都会被检测是否提交了 CSRF 字段。
{!! csrf_field() !!}
实际上会生成一个隐藏的 input:
<input type="hidden" name="_token" value="GYZ8OHDAbZICMcEvcTiS82qlZs2XrELklpEl159S">
这一行也可以这么写:
<input type="hidden" name="_token" value="{{ csrf_token() }}">
如果你的系统有很多的 Ajax,而你又不想降低安全性,这里的 csrf_token() 函数将会给你巨大的帮助。
后端接收数据
我们在页面中填入了一些数据,点击了提交按钮,这条请求会被分配到那里呢?

第三行解答了我们的问题。好了,新建 store 方法:
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required|unique:articles|max:255',
'body' => 'required',
]); $article = new Article;
$article->title = $request->get('title');
$article->body = $request->get('body');
$article->user_id = $request->user()->id; if ($article->save()) {
return redirect('admin/article');
} else {
return redirect()->back()->withInput()->withErrors('保存失败!');
}
}
检验成果
填入数据:

点击按钮,页面跳转到“文章管理”页,将此页面拉到最底部:

恭喜你,文章新增成功!
详细注释
下面我已注释的形式细细解析每一段代码的作用:
public function store(Request $request) // Laravel 的依赖注入系统会自动初始化我们需要的 Request 类
{
// 数据验证
$this->validate($request, [
'title' => 'required|unique:articles|max:255', // 必填、在 articles 表中唯一、最大长度 255
'body' => 'required', // 必填
]); // 通过 Article Model 插入一条数据进 articles 表
$article = new Article; // 初始化 Article 对象
$article->title = $request->get('title'); // 将 POST 提交过了的 title 字段的值赋给 article 的 title 属性
$article->body = $request->get('body'); // 同上
$article->user_id = $request->user()->id; // 获取当前 Auth 系统中注册的用户,并将其 id 赋给 article 的 user_id 属性 // 将数据保存到数据库,通过判断保存结果,控制页面进行不同跳转
if ($article->save()) {
return redirect('admin/article'); // 保存成功,跳转到 文章管理 页
} else {
// 保存失败,跳回来路页面,保留用户的输入,并给出提示
return redirect()->back()->withInput()->withErrors('保存失败!');
}
}
编辑 Article
这两行路由配置可以满足我们的需求:

上面一行:展示“编辑某一篇文章”的页面;下面一行:上传数据更新这篇文章。
这个就当做第二个小作业留给你们,尝试自己去构建吧~这里面还有个小坑,参考我的代码就可以迅速地解决呦~
删除 Article
删除某个资源跟新增、编辑相比最大的不同就是运行方式的不同:删除按钮看起来是一个独立的按钮,其实它是一个完整的表单,只不过只有这一个按钮暴露在页面上:
<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>
大家可能注意到了这句代码 {{ method_field('DELETE') }} ,这是什么意思呢?这是 Laravel 特有的请求处理系统的特殊约定。虽然 DELETE 方法在 RFC2616中是可以携带 body 的(甚至 GET 方法都是可以携带的),但是由于历史的原因,不少 web server 软件都将 DELETE 方法和 GET 方法视作不可携带 body 的方法,有些 web server 软件会丢弃 body,有些干脆直接认为请求不合法拒绝接收。所以在这里,Laravel 的请求处理系统要求所有非 GET 和 POST 的请求全部通过 POST 请求来执行,再将真正的方法使用 _method 表单字段携带给后端代码。上面小作业中的小坑便是这个,PUT/PATCH 请求也要通过 POST 来执行。
另外,这里还有一些小问题:PUT/PATCH 请求通过 POST 方法执行仅限于 form 提交,对 Ajax 请求目前来看是无效的,看来我要去给 Laravel 提交一个 patch 了。:whale:
在控制器中增加删除文章对应的是 destroy 方法:
public function destroy($id)
{
Article::find($id)->delete();
return redirect()->back()->withInput()->withErrors('删除成功!');
}
点击删除按钮,检验效果:

恭喜你,文章新增、编辑、删除功能构建成功!
2016 版 Laravel 系列入门教程(四)【最适合中国人的 Laravel 教程】的更多相关文章
- 2016 版 Laravel 系列入门教程
2016 版 Laravel 系列入门教程 (1) - (5) http://www.golaravel.com/post/2016-ban-laravel-xi-lie-ru-men-jiao-ch ...
- Laravel 5 系列入门教程(一)【最适合中国人的 Laravel 教程】
Laravel 5 系列入门教程(一)[最适合中国人的 Laravel 教程] 分享⋅ johnlui⋅ 于 2年前 ⋅ 最后回复由 skys215于 11个月前 ⋅ 17543 阅读 原文发表在 ...
- Laravel 系列入门教程(三)【最适合中国人的 Laravel 教程】
在本篇文章中,我们将尝试构建一个带后台的简单博客系统.我们将会使用到 路由.MVC.Eloquent ORM 和 blade 视图系统. 简单博客系统规划 我们在教程一中已经新建了一个继承自 Eloq ...
- 2016 版 Laravel 系列入门教程(五)【最适合中国人的 Laravel 教程】
本教程示例代码见: https://github.com/johnlui/Learn-Laravel-5 在任何地方卡住,最快的办法就是去看示例代码. 本文是本系列教程的完结篇,我们将一起给 Arti ...
- 2016 版 Laravel 系列入门教程(三)【最适合中国人的 Laravel 教程】
本教程示例代码见: https://github.com/johnlui/Learn-Laravel-5 在任何地方卡住,最快的办法就是去看示例代码. 在本篇文章中,我们将尝试构建一个带后台的简单博客 ...
- 2016 版 Laravel 系列入门教程(一)【最适合中国人的 Laravel 教程】
本教程示例代码见: https://github.com/johnlui/Learn-Laravel-5 在任何地方卡住,最快的办法就是去看示例代码. 本文基于 Laravel 5.2 版本,无奈 5 ...
- 2016 版 Laravel 系列入门教程(二)【最适合中国人的 Laravel 教程】
本教程示例代码见: https://github.com/johnlui/Learn-Laravel-5 在任何地方卡住,最快的办法就是去看示例代码. 本篇文章中,我将跟宝宝们一起学习 Laravel ...
- Laravel 系列入门教程(四)【最适合中国人的 Laravel 教程】
本篇文章中,我将跟大家一起实现 Article 的新增.编辑和删除功能,仔细解读每一段代码,相信本篇文章看完,你就能够 get Laravel 使用之道. RESTful 资源控制器 资源控制器是 L ...
- Laravel 系列入门教程(五)【最适合中国人的 Laravel 教程】
本文是本系列教程的完结篇,我们将一起给 Article 加入评论功能,让游客在前台页面可以查看.提交.回复评论,并完成后台评论管理功能,可以删除.编辑评论.Article 和评论将使用 Laravel ...
随机推荐
- [转]ionic $state.go passed $stateParams
本文转自:http://stackoverflow.com/questions/19516771/state-go-toparams-not-passed-to-stateparams If you ...
- [转]用NPOI操作EXCEL--数据有效性
本文转自:http://www.cnblogs.com/atao/archive/2009/09/22/1572170.html 在有些情况下(比如Excel引入),我们可能不允许用户在Excel随意 ...
- WEB安全--业务安全漏洞
0x00 索引说明 在OWASP的分享,关于业务安全的漏洞检测模型. 0x01 身份认证安全 1 暴力破解 在没有验证码限制或者一次验证码可以多次使用的地方,使用已知用户对密码进行暴力破解或者用一个通 ...
- 《TCP/IP详解 卷一》读书笔记-----TCP数据流
1.Delayed Acknowledgements:TCP通常不会在收到数据之后立即返回一个ACK,而是会有一个延时,希望能ACK报文段中带上一些数据,通常这个延时为200ms 2.Nagle Al ...
- 【MVC 4】6.SportsSore:导航
作者:[美]Adam Freeman 来源:<精通ASP.NET MVC 4> 前面的文章[MVC 4]5.SportsSore —— 一个真实的应用程序 建立了 Sports ...
- Android配置----小米手机通过wifi连接ADB调试Android应用
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...
- 关于eclipse入门开发c/c++文章推荐
1. 关于编译说明. http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/ 2. 关于快捷键与代码阅读 http://www.cn ...
- for循环的三种写法
第一种写法 传统的方法,遍历数组 String[] arr = { "amy", "heinrich", "cindy", "g ...
- javascript中的队列结构
1.概念 队列和栈结构不同,栈是一种后进先出的结构,而队列是一种先进先出的结构.队列也是一种表结构,不同的是队列只能在队尾插入元素,在队首删除元素,可以将队列想象成一个在超时等待排队付钱的队伍,或者在 ...
- NSPredicate简单应用
1.筛选纯字符串数组的内容 NSArray *array = [[NSArray alloc]initWithObjects:@"beijing",@"shanghai& ...