1、创建RESTFul风格控制器
注:关于什么是RESTFul风格及其规范可参考这篇文章:理解RESTful架构。
本文我们主要讨论创建一个RESTFul风格的控制器用于对博客文章进行增删改查,创建这样的控制器很简单,在应用根目录运行如下Artisan命令即可:
php artisan make:controller PostController
该命令会在app/Http/Controllers
目录下生成一个PostController.php
文件,该控制器内容如下:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Http\Controllers\Controller; class PostController extends Controller { /** * 显示文章列表. * * @return Response */ public function index() { // } /** * 创建新文章表单页面 * * @return Response */ public function create() { // } /** * 将新创建的文章存储到存储器 * * @param Request $request * @return Response */ public function store(Request $request) { // } /** * 显示指定文章 * * @param int $id * @return Response */ public function show($id) { // } /** * 显示编辑指定文章的表单页面 * * @param int $id * @return Response */ public function edit($id) { // } /** * 在存储器中更新指定文章 * * @param Request $request * @param int $id * @return Response */ public function update(Request $request, $id) { // } /** * 从存储器中移除指定文章 * * @param int $id * @return Response */ public function destroy($id) { // } }
2、为RESTFul风格控制器注册路由
接下来我们在routes.php
文件中为该控制器注册路由:
Route::resource('post','PostController');
该路由包含了指向多个动作的子路由:
方法 | 路径 | 动作 | 路由名称 |
---|---|---|---|
GET | /post | index | post.index |
GET | /post/create | create | post.create |
POST | /post | store | post.store |
GET | /post/{post} | show | post.show |
GET | /post/{post}/edit | edit | post.edit |
PUT/PATCH | /post/{post} | update | post.update |
DELETE | /post/{post} | destroy | post.destroy |
比如我们在浏览器中以GET方式访问http://laravel.app:8000/post
,则访问的是PostController
的index
方法,我们可以通过route('post.index')
生成对应路由URL。类似的,如果我们以POST方式访问http://laravel.app:8000/post
,则访问的是PostController
的store
方法,对应的POST表单action属性值则可以通过route('post.store')
来生成。
3、实例教程——文章增删改查
接下来我们演示基本的增删改查操作,关于数据库的操作我们后面再讲,这里我们使用缓存作为存储器(Laravel默认使用文件缓存)。
注意:我们这里用到了
Cache
门面,使用前不要忘了在PostController
顶部使用use Cache;
引入。关于Cache的用法,可参考缓存文档。
3.1 新增文章
首先我们新增一篇文章,定义PostController
控制器的create
方法和store
方法如下(视图部门我们放到后面讲,这里就将HTML放到PHP变量里):
/** * 创建新文章表单页面 * * @return Response */ public function create() { $postUrl = route('post.store'); $csrf_field = csrf_field(); $html = <<<CREATE <form action="$postUrl" method="POST"> $csrf_field <input type="text" name="title"><br/><br/> <textarea name="content" cols="50" rows="5"></textarea><br/><br/> <input type="submit" value="提交"/> </form> CREATE; return $html; } /** * 将新创建的文章存储到存储器 * * @param Request $request * @return Response */ public function store(Request $request) { $title = $request->input('title'); $content = $request->input('content'); $post = ['title'=>trim($title),'content'=>trim($content)]; $posts = Cache::get('posts',[]); if(!Cache::get('post_id')){ Cache::add('post_id',1,60); }else{ Cache::increment('post_id',1); } $posts[Cache::get('post_id')] = $post; Cache::put('posts',$posts,60); return redirect()->route('post.show',['post'=>Cache::get('post_id')]); }
3.2 查看文章
访问http://laravel.app:8000/post/create
页面,填写表单,点击“提交”,保存成功后,页面跳转到详情页:
/** * 显示指定文章 * * @param int $id * @return Response */ public function show($id) { $posts = Cache::get('posts',[]); if(!$posts || !$posts[$id]) exit('Nothing Found!'); $post = $posts[$id]; $editUrl = route('post.edit',['post'=>$id]); $html = <<<DETAIL <h3>{$post['title']}</h3> <p>{$post['content']}</p> <p> <a href="{$editUrl}">编辑</a> </p> DETAIL; return $html; }
3.3 编辑文章
同理我们定义编辑文章对应的edit
方法和update
方法如下:
/** * 显示编辑指定文章的表单页面 * * @param int $id * @return Response */ public function edit($id) { $posts = Cache::get('posts',[]); if(!$posts || !$posts[$id]) exit('Nothing Found!'); $post = $posts[$id]; $postUrl = route('post.update',['post'=>$id]); $csrf_field = csrf_field(); $html = <<<UPDATE <form action="$postUrl" method="POST"> $csrf_field <input type="hidden" name="_method" value="PUT"/> <input type="text" name="title" value="{$post['title']}"><br/><br/> <textarea name="content" cols="50" rows="5">{$post['content']}</textarea><br/><br/> <input type="submit" value="提交"/> </form> UPDATE; return $html; } /** * 在存储器中更新指定文章 * * @param Request $request * @param int $id * @return Response */ public function update(Request $request, $id) { $posts = Cache::get('posts',[]); if(!$posts || !$posts[$id]) exit('Nothing Found!'); $title = $request->input('title'); $content = $request->input('content'); $posts[$id]['title'] = trim($title); $posts[$id]['content'] = trim($content); Cache::put('posts',$posts,60); return redirect()->route('post.show',['post'=>Cache::get('post_id')]); }
3.4 删除文章
我们还可以使用destroy
方法删除文章:
/** * 从存储器中移除指定文章 * * @param int $id * @return Response */ public function destroy($id) { $posts = Cache::get('posts',[]); if(!$posts || !$posts[$id]) exit('Nothing Deleted!'); unset($posts[$id]); Cache::decrement('post_id',1); return redirect()->route('post.index'); }
要删除文章,需要参考编辑表单伪造删除表单方法为DELETE
(一般使用AJAX删除),这里不再演示。
3.5 文章列表
最后我们再来定义一个用于显示所有文章列表的index
方法:
/** * 显示文章列表. * * @return Response */ public function index() { $posts = Cache::get('posts',[]); if(!$posts) exit('Nothing'); $html = '<ul>'; foreach ($posts as $key=>$post) { $html .= '<li><a href='.route('post.show',['post'=>$key]).'>'.$post['title'].'</li>'; } $html .= '</ul>'; return $html; }
升级阅读:基于模型+缓存对文章增删改查实例进行优化
擦,我的错,我忘了昨天更改了服务器根目录了。
学院君 5.2的报错啦 NotFoundHttpException in RouteCollection.php line 161: 这个什么情况呢
分的有点细,有些容易混淆
/**
* 显示指定文章
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
}
/**
* 显示编辑指定文章的表单页面
*
* @param int $id
* @return Response
*/
public function edit($id)
{
//
}
其实这2个可以放一起,分开 增 删 改 查 4个就可以了,个人认为,查全部在show也差不多
我将列表中的点击查看修改为删除,href='. route('post.destroy',['post'=>'1']) .' 为何总是无法删除?总是调到show方法里呢?难道destroy有啥特殊的访问方式么?
5.2 执行后没有增删改查
执行后
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
class PostController extends Controller
{
//
}
删除表单方法为DELETE
admin/article/3?_method/DELETE
如果不用ajax要怎么处理.这样子似乎不行~没有定到删除方法.
你应该是写错了 你这个格式是GET的 而是应该用POST 然后加入隐藏的_method的
form应该这样写
{! csrf_feild() !}
请问学院君
删除表单方法为DELETE
admin/article/3?_method/DELETE
如果不用ajax要怎么处理.这样子似乎不行~没有定到删除方法.
实例在5.2版本会报错,FatalErrorException in PostController.php line 73:
syntax error, unexpected ':', expecting ']'
学院君 要怎么解决啊
这个确实违背了RESTful风格 但是在非RIA的web应用又确实需要这种间接页面(新增和编辑页面)