欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

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

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

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/postindexpost.index
GET/post/createcreatepost.create
POST/poststorepost.store
GET/post/{post}showpost.show
GET/post/{post}/editeditpost.edit
PUT/PATCH/post/{post}updatepost.update
DELETE/post/{post}destroypost.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变量里):

/**
* 创建新文章表单页面
*
* @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;
}

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

  • 天涯
    1. 天涯
      学院君 5.2的报错啦 NotFoundHttpException in RouteCollection.php line 161: 这个什么情况呢       

    擦,我的错,我忘了昨天更改了服务器根目录了。

  • 天涯

    学院君 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
    {
    //
    }

  • 赵福春
    1. 微凉清风
      请问学院君
      删除表单方法为DELETE
      admin/article/3?_method/DELETE
      如果不用ajax要怎么处理.这样子似乎不行~没有定到删除方法.       

    你应该是写错了 你这个格式是GET的 而是应该用POST 然后加入隐藏的_method的
    form应该这样写

    {! csrf_feild() !}

  • 微凉清风

    请问学院君
    删除表单方法为DELETE
    admin/article/3?_method/DELETE
    如果不用ajax要怎么处理.这样子似乎不行~没有定到删除方法.

  • JH

    [太开心] [太开心] [太开心] [太开心] [太开心] [太开心] [太开心] [太开心]

  • 博士

    实例在5.2版本会报错,FatalErrorException in PostController.php line 73:
    syntax error, unexpected ':', expecting ']'
    学院君 要怎么解决啊

  • 学院君
    1. 复写纸
      RESTful不是需要URI代表实体,用名词来表示,但是使用Route::sourece的生成的crate.post不是动词来这了吗,这里需要理解为是一种服务吗?       

    这个确实违背了RESTful风格 但是在非RIA的web应用又确实需要这种间接页面(新增和编辑页面)


来自 http://laravelacademy.org/post/549.html
普通分类: