HTTP控制器实例教程 —— 创建RESTFul风格控制器实现文章增删改查


基本控制器及控制器路由、控制器中间件都比较简单,这里不再赘述,相关文档参考HTTP 控制器文档一节。

1、创建RESTFul风格控制器

注:关于什么是RESTFul风格及其规范可参考这篇文章:理解RESTful架构。

本文我们主要讨论创建一个RESTFul风格的控制器用于对博客文章进行增删改查,创建这样的控制器很简单,在应用根目录运行如下Artisan命令即可:

  1. php artisan make:controller PostController

该命令会在app/Http/Controllers目录下生成一个PostController.php文件,该控制器内容如下:

  1. <?php
  2.  
  3. namespace App\Http\Controllers;
  4.  
  5. use Illuminate\Http\Request;
  6.  
  7. use App\Http\Requests;
  8. use App\Http\Controllers\Controller;
  9.  
  10. class PostController extends Controller
  11. {
  12. /**
  13. * 显示文章列表.
  14. *
  15. * @return Response
  16. */
  17. public function index()
  18. {
  19. //
  20. }
  21.  
  22. /**
  23. * 创建新文章表单页面
  24. *
  25. * @return Response
  26. */
  27. public function create()
  28. {
  29. //
  30. }
  31.  
  32. /**
  33. * 将新创建的文章存储到存储器
  34. *
  35. * @param Request $request
  36. * @return Response
  37. */
  38. public function store(Request $request)
  39. {
  40. //
  41. }
  42.  
  43. /**
  44. * 显示指定文章
  45. *
  46. * @param int $id
  47. * @return Response
  48. */
  49. public function show($id)
  50. {
  51. //
  52. }
  53.  
  54. /**
  55. * 显示编辑指定文章的表单页面
  56. *
  57. * @param int $id
  58. * @return Response
  59. */
  60. public function edit($id)
  61. {
  62. //
  63. }
  64.  
  65. /**
  66. * 在存储器中更新指定文章
  67. *
  68. * @param Request $request
  69. * @param int $id
  70. * @return Response
  71. */
  72. public function update(Request $request, $id)
  73. {
  74. //
  75. }
  76.  
  77. /**
  78. * 从存储器中移除指定文章
  79. *
  80. * @param int $id
  81. * @return Response
  82. */
  83. public function destroy($id)
  84. {
  85. //
  86. }
  87. }

2、为RESTFul风格控制器注册路由

接下来我们在routes.php文件中为该控制器注册路由:

  1. 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,则访问的是PostControllerindex方法,我们可以通过route('post.index')生成对应路由URL。类似的,如果我们以POST方式访问http://laravel.app:8000/post,则访问的是PostControllerstore方法,对应的POST表单action属性值则可以通过route('post.store')来生成。

3、实例教程——文章增删改查

接下来我们演示基本的增删改查操作,关于数据库的操作我们后面再讲,这里我们使用缓存作为存储器(Laravel默认使用文件缓存)。

注意:我们这里用到了Cache门面,使用前不要忘了在PostController顶部使用use Cache;引入。关于Cache的用法,可参考缓存文档。

3.1 新增文章

首先我们新增一篇文章,定义PostController控制器的create方法和store方法如下(视图部门我们放到后面讲,这里就将HTML放到PHP变量里):

  1. /**
  2. * 创建新文章表单页面
  3. *
  4. * @return Response
  5. */
  6. public function create()
  7. {
  8. $postUrl = route('post.store');
  9. $csrf_field = csrf_field();
  10. $html = <<<CREATE
  11. <form action="$postUrl" method="POST">
  12. $csrf_field
  13. <input type="text" name="title"><br/><br/>
  14. <textarea name="content" cols="50" rows="5"></textarea><br/><br/>
  15. <input type="submit" value="提交"/>
  16. </form>
  17. CREATE;
  18. return $html;
  19. }
  20.  
  21. /**
  22. * 将新创建的文章存储到存储器
  23. *
  24. * @param Request $request
  25. * @return Response
  26. */
  27. public function store(Request $request)
  28. {
  29. $title = $request->input('title');
  30. $content = $request->input('content');
  31. $post = ['title'=>trim($title),'content'=>trim($content)];
  32.  
  33. $posts = Cache::get('posts',[]);
  34. if(!Cache::get('post_id')){
  35. Cache::add('post_id',1,60);
  36. }else{
  37. Cache::increment('post_id',1);
  38. }
  39. $posts[Cache::get('post_id')] = $post;
  40.  
  41. Cache::put('posts',$posts,60);
  42. return redirect()->route('post.show',['post'=>Cache::get('post_id')]);
  43. }

3.2 查看文章

访问http://laravel.app:8000/post/create页面,填写表单,点击“提交”,保存成功后,页面跳转到详情页:

  1. /**
  2. * 显示指定文章
  3. *
  4. * @param int $id
  5. * @return Response
  6. */
  7. public function show($id)
  8. {
  9. $posts = Cache::get('posts',[]);
  10. if(!$posts || !$posts[$id])
  11. exit('Nothing Found!');
  12. $post = $posts[$id];
  13.  
  14. $editUrl = route('post.edit',['post'=>$id]);
  15. $html = <<<DETAIL
  16. <h3>{$post['title']}</h3>
  17. <p>{$post['content']}</p>
  18. <p>
  19. <a href="{$editUrl}">编辑</a>
  20. </p>
  21. DETAIL;
  22.  
  23. return $html;
  24. }

3.3 编辑文章

同理我们定义编辑文章对应的edit方法和update方法如下:

  1. /**
  2. * 显示编辑指定文章的表单页面
  3. *
  4. * @param int $id
  5. * @return Response
  6. */
  7. public function edit($id)
  8. {
  9. $posts = Cache::get('posts',[]);
  10. if(!$posts || !$posts[$id])
  11. exit('Nothing Found!');
  12. $post = $posts[$id];
  13.  
  14. $postUrl = route('post.update',['post'=>$id]);
  15. $csrf_field = csrf_field();
  16. $html = <<<UPDATE
  17. <form action="$postUrl" method="POST">
  18. $csrf_field
  19. <input type="hidden" name="_method" value="PUT"/>
  20. <input type="text" name="title" value="{$post['title']}"><br/><br/>
  21. <textarea name="content" cols="50" rows="5">{$post['content']}</textarea><br/><br/>
  22. <input type="submit" value="提交"/>
  23. </form>
  24. UPDATE;
  25. return $html;
  26.  
  27. }
  28.  
  29. /**
  30. * 在存储器中更新指定文章
  31. *
  32. * @param Request $request
  33. * @param int $id
  34. * @return Response
  35. */
  36. public function update(Request $request, $id)
  37. {
  38. $posts = Cache::get('posts',[]);
  39. if(!$posts || !$posts[$id])
  40. exit('Nothing Found!');
  41.  
  42. $title = $request->input('title');
  43. $content = $request->input('content');
  44.  
  45. $posts[$id]['title'] = trim($title);
  46. $posts[$id]['content'] = trim($content);
  47.  
  48. Cache::put('posts',$posts,60);
  49. return redirect()->route('post.show',['post'=>Cache::get('post_id')]);
  50. }

3.4 删除文章

我们还可以使用destroy方法删除文章:

  1. /**
  2. * 从存储器中移除指定文章
  3. *
  4. * @param int $id
  5. * @return Response
  6. */
  7. public function destroy($id)
  8. {
  9. $posts = Cache::get('posts',[]);
  10. if(!$posts || !$posts[$id])
  11. exit('Nothing Deleted!');
  12.  
  13. unset($posts[$id]);
  14. Cache::decrement('post_id',1);
  15.  
  16. return redirect()->route('post.index');
  17.  
  18. }

要删除文章,需要参考编辑表单伪造删除表单方法为DELETE(一般使用AJAX删除),这里不再演示。

3.5 文章列表

最后我们再来定义一个用于显示所有文章列表的index方法:

  1. /**
  2. * 显示文章列表.
  3. *
  4. * @return Response
  5. */
  6. public function index()
  7. {
  8. $posts = Cache::get('posts',[]);
  9. if(!$posts)
  10. exit('Nothing');
  11.  
  12. $html = '<ul>';
  13.  
  14. foreach ($posts as $key=>$post) {
  15. $html .= '<li><a href='.route('post.show',['post'=>$key]).'>'.$post['title'].'</li>';
  16. }
  17.  
  18. $html .= '</ul>';
  19.  
  20. return $html;
  21. }

升级阅读:基于模型+缓存对文章增删改查实例进行优化