办法的对待,方法自动验证表单音讯

简简单单概括:

本节我们将以小说的增删改查作为实例系统讲述缓存的应用,那些实例是对前边成立RESTFul风格控制器完毕小说增删改查那篇教程的改建和升级换代,大家将在其基础上融合进Eloquent
ORM和模型事件,将利用的风貌直接拉到生成环境。

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

电动验证是ThinkPHP模型层提供的一种多少证实办法,可以在动用create创造数量对象的时候自动举办数据表达。

1、二者都可用来收取post表单提交的数码。

1、准备干活

1、创建RESTFul风格控制器
办法的对待,方法自动验证表单音讯。注:关于怎么样是RESTFul风格及其规范可参照那篇作品:精晓RESTful架构。
本文大家根本啄磨创立一个RESTFul风格的控制器用于对博客小说进行增删改查,创制那样的控制器很简短,在行使根目录运行如下Artisan命令即可:

原理:

2、I(‘post.’)方法可一直吸收赋值给变量如$post=I(‘post.’),create()方法源于父类模型封装,需先实例化父类模型,如:$post=M(‘Test’)->create()。

路由及控制器

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

create()方法收集表单($_POST)新闻并赶回,同时触公布单自动验证,过滤不合规字段,

3、I(‘post.’)方法内置默许过滤方法htmlspecialchars可过滤html实体,create()方法需手动创制。

路由的概念和控制器的创导保持和创建RESTFul风格控制器达成文章增删改查中同样。

<?php

在控制器中动用create()方法,(再次回到值为true/false),会自动触发模型类中的$_validate属性(为父类Model中的方法,在子类Model中重写),在$_validate中自定义表达规则(验证规则下边会详细表明),当create()方法没有数量即重临值为false时,通过$xxx对象->getError();获取并赶回错误音信!

4、create()方法包罗一多元 自动验证 自动处理
字段映射等机制(需自定义规则),I(‘post.’)方法无。

成立数据表

    namespace App\Http\Controllers;

应用电动验证必须比照以下规则格式定义:

5、I(‘post.’)方法可接受所有表单字段,create()方法成立的数量对象会自动过滤掉与数据表中字段不般配的表单字段。

关于小说对应数据表大家在数据库一对应用查询创设器达成对数据库的高等查询已有提及,那里大家运用在此之前创造的数据表即可。

    use Illuminate\Http\Request;

protected $_validate = array(     
    array(验证字段1,验证规则,错误提示,[验证条件,附加规则,验证时间]), 
    array(验证字段2,验证规则,错误提示,[验证条件,附加规则,验证时间]),
     ......
);    

6、I(‘post.’)方法多用于字段数据较少,不须要一星罗棋布活动作用的境况,create()方法则相反。

制造小说模型

    use App\Http\Requests;
    use App\办法的对待,方法自动验证表单音讯。Http\Controllers\Controller;

里头验证字段,验证规则,错误提醒是必填项,验证条件,附加规则,验证时间为可选!

关于小说模型Post的创制也和在此以前Eloquent
ORM部分讲ORM概述、模型定义及主干查询中开创的同一。

    class PostController extends Controller
    {
        /**
         * 呈现小说列表.
         *
         * @return Response
         */
        public function index()
        {
            //
        }

表达字段(必填):表单字段。

2、修改控制器

        /**
         * 创造新文章表单页面
         *
         * @return Response
         */
        public function create()
        {
            //
        }

证实规则(必填):require
字段必须、email 邮箱、url URL地址、number 数字,仍能够构成附加规则使用。

在前面大家是由此缓存完毕对文章的增删改查操作,那里我们将其修改为经过数据库已毕增删改查操作:

        /**
         * 将新成立的篇章存储到存储器
         *
         * @param Request
$request
         * @return Response
         */
        public function store(Request $request)
        {
            //
        }

谬误提示(必填):验证失利时重临的提醒新闻。

<?php

        /**
         * 呈现指定著作
         *
         * @param int $id
         * @return Response
         */
        public function show($id)
        {
            //
        }

证实条件(可选):有0,1,2二种,0:_POST中设有的字段验证,默许;1:验证规则定义了就必须注明;2:值不为空时验证.

    namespace App\Http\Controllers;

        /**
         * 彰显编辑指定小说的表单页面
         *
         * @param int $id
         * @return Response
         */
        public function edit($id)
        {
            //
        }

外加规则:

    use Illuminate\Http\Request;

        /**
         * 在存储器中创新指定作品
         *
         * @param Request $request
         * @param int $id
         * @return Response
         */
        public function update(Request $request, $id)
        {
            //
        }

regex 正则验证,定义的验证规则是一个正则表达式(默认)
function 函数验证,定义的验证规则是一个函数名
callback 方法验证,定义的验证规则是当前模型类的一个方法
confirm 验证表单中的两个字段是否相同,定义的验证规则是一个字段名
equal 验证是否等于某个值,该值由前面的验证规则定义
notequal 验证是否不等于某个值,该值由前面的验证规则定义(3.1.2版本新增)
in 验证是否在某个范围内,定义的验证规则可以是一个数组或者逗号分割的字符串
notin 验证是否不在某个范围内,定义的验证规则可以是一个数组或者逗号分割的字符串(3.1.2版本新增)
length 验证长度,定义的验证规则可以是一个数字(表示固定长度)或者数字范围(例如3,12 表示长度从3到12的范围)
between 验证范围,定义的验证规则表示范围,可以使用字符串或者数组,例如1,31或者array(1,31)
notbetween 验证不在某个范围,定义的验证规则表示范围,可以使用字符串或者数组(3.1.2版本新增)
expire 验证是否在有效期,定义的验证规则表示时间范围,可以到时间,例如可以使用 2012-1-15,2013-1-15 表示当前提交有效期在2012-1-15到2013-1-15之间,也可以使用时间戳定义
ip_allow 验证IP是否允许,定义的验证规则表示允许的IP地址列表,用逗号分隔,例如201.12.2.5,201.12.2.6
ip_deny 验证IP是否禁止,定义的验证规则表示禁止的ip地址列表,用逗号分隔,例如201.12.2.5,201.12.2.6
unique 验证是否唯一,系统会根据字段目前的值查询数据库来判断是否存在相同的值,当表单数据中包含主键字段时unique不可用于判断主键字段本身

    use Cache;
    use App\Models\Post;

        /**
         * 从存储器中移除指定小说
         *
         * @param int $id
         * @return Response
         */
        public function destroy($id)
        {
            //
        }
    }
2、为RESTFul风格控制器注册路由
接下去大家在routes.php文件中为该控制器注册路由:

注脚时间(可选):共有1,2,3三种,1:新增多少时候证实;2:编辑数据时候证实;3:全体场馆下验证(默许);也能够能够依据作业必要充实其余的辨证时间

    use App\Http\Requests;
    use App\Http\Controllers\Controller;

Route::resource(‘post’,’PostController’);
该路由包蕴了指向四个动作的子路由:

下边附上代码:以登记为例

    class PostController extends Controller
    {
        /**
         * 显示小说列表.
         *
         * @return Response
         */
        public function index()
        {
           
//使用all获取具有数据,假若数据量大利用分页获取
            $posts = Post::all();
            if(!$posts)
                exit(‘还未曾公布任何作品!’);

措施 路径 动作 路由名称
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格局访问

前台页面比较不难,代码就不贴出来了,下边是前台登记界面截图

            $html = ‘<ul>’;

3、实例教程——作品增删改查
接下去咱们演示基本的增删改查操作,关于数据库的操作我们前面再讲,那里大家运用缓存作为存储器(Laravel默许使用文件缓存)。

www.5929.com 1

            foreach ($posts as
$post) {
                $html .= ‘<li><a
href=’.route(‘post.show’,[‘post’=>$post]).’>’.$post->title.'</li>’;
            }

瞩目:大家那边运用了Cache门面,使用前并非忘了在PostController顶部选用use
Cache;引入。关于Cache的用法,可参看缓存文档。
3.1 新增小说

控制器代码:

            $html .= ‘</ul>’;

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

//注册
    public function register(){
       $user = new \Model\UserModel();

       //两个逻辑:收集,展示
      if (!empty($_POST)) {

        //create()方法收集表单($_POST)信息并返回,同时触发表单自动验证,过滤非法字段
        $date = $user->create();
        //通过create()方法的返回值$date判断验证是否成功
        if ($date) {  //返回实在数据的时候才进行添加
          //implode()把数组变为字符串
          $date['user_hobby'] = implode(',', $date['user_hobby']);
          $info = $user->add($date);
          if ($info) {

            //跳转首页            
            $this->redirect('Index/index');
          }
        }else{

          //把错误信息分配到前台模板
          $error = $user->getError();
          $this->assign('error',$error);
        }
      }
       //调用view视图
      $this->display();
    }

            return $html;
        }

/**
* 成立新小说表单页面
*
* @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;
}

模型类代码:

        /**
         * 创造新作品表单页面
         *
         * @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)];

class UserModel extends Model{

    //是否批量处理验证,批量获取全部的错误验证信息
    protected $patchValidate = true;    //默认为false

    //自动验证定义
    protected $_validate = array(

        //array(字段,验证规则,错误提示,验证条件,附加规则,验证时间)
        //①用户名验证,不能为空
        array('username','require','用户名不能为空'),
        array('username','','该用户名已经被占用','0','unique'),
        //②密码验证,不为空
        array('password','require','密码不能为空'),
        //③验证确认密码,必须填写,与密码保持一致
        array('password2','require','确认密码必须填写'),
        array('password2','password','两次密码保持一致',0,'confirm'),
        //④邮箱验证
        array('user_email','email','邮箱格式不正确',2),
        //⑤qq验证,数字组成,5-12位
        array('user_qq','number','qq必须是数字'),
        array('user_qq','5,12','位数在5-12位之间',0,'length'),
        //⑥学历验证,必须选一个
        array('user_xueli','2,5','学位必须选择一个',0,'between'),
        //⑦爱好验证,必须选择二个以上
        //因为爱好返回的是数组,附加规则中没有可以直接用的规则,所以需自定义方法,用callback方法验证
        array('user_hobby','check_hobby','爱好必须选两项或以上',1,'callback'),
        );

    //定义方法进行爱好验证
    //参数$arg代表被验证的表单信息
    function check_hobby($arg)
    {
        //判断数组长度是否大于2
        if (count($arg)<2) {
            return false;    //会自动输出验证错误信息
        }
        return true;
    }
}

        /**
         * 将新创设的篇章存储到存储器
         *
         *www.5929.com, @param Request
$request
         * @return Response
         */
        public function store(Request $request)
        {
            $title = $request->input(‘title’);
            $content = $request->input(‘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;

把验证的错误音讯在模板中给体现出来(部分代码)

            $post = new Post;
            $post->title = $title;
            $post->content = $content;
            $post->save();

    Cache::put(‘posts’,$posts,60);
    return
redirect()->route(‘post.show’,[‘post’=>Cache::get(‘post_id’)]);
}
3.2 查看小说

<td style="width:13%; text-align: right;">
    <label for="User_username" class="required">用户名 
    *</label>
</td>

<td style="width:87%;">
    <input class="inputBg" size="25" name="username" id="User_username" type="text" value="" />                  
    <{$error.username|default:""}>
</td>

            return
redirect()->route(‘post.show’,[‘post’=>$post]);
        }

访问

结果:

        /**
         * 彰显指定小说
         *
         * @param int $id
         * @return Response
         */
        public function show($id)
        {

/**
* 呈现指定文章
*
* @param int $id
* @return Response
*/
public function show($id)
{
    $posts = Cache::get(‘posts’,[]);
    if(!$posts || !$posts[$id])
        exit(‘Nothing Found!’);
    $post = $posts[$id];

www.5929.com 2

            $post = Cache::get(‘post_’.$id);
            if(!$post){
                $post = Post::find($id);
                if(!$post)
                    exit(‘指定小说不设有!’);
                Cache::put(‘post_’.$id,$post,60*24*7);
            }

    $editUrl = route(‘post.edit’,[‘post’=>$id]);
    $html = <<<DETAIL
        <h3>{$post[‘title’]}</h3>
        <p>{$post[‘content’]}</p>
        <p>
            <a href=”{$editUrl}”>编辑</a>
        </p>
DETAIL;

 

            if(!Cache::get(‘post_views_’.$id))
                Cache::forever(‘post_views_’.$id,0);
            $views = Cache::increment(‘post_views_’.$id);
            Cache::forever(‘post_views_’.$id,$views);

    return $html;
}
3.3 编辑成文

            $editUrl = route(‘post.edit’,[‘post’=>$post]);
            $deleteUrl = route(‘post.destroy’,[‘post’=>$post]);
            $html = <<<POST
                <h3>{$post->title}</h3>
                <p>{$post->content}</p>
                <i>已有{$views}人阅读</i>
                <p>
                    <a href=”{$editUrl}”>编辑</a>
                </p>
POST;

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

            return $html;
        }

/**
* 突显编辑指定作品的表单页面
*
* @param int $id
* @return Response
*/
public function edit($id)
{
    $posts = Cache::get(‘posts’,[]);
    if(!$posts || !$posts[$id])
        exit(‘Nothing Found!’);
    $post = $posts[$id];

        /**
         * 突显编辑指定小说的表单页面
         *
         * @param int $id
         * @return Response
         */
        public function edit($id)
        {
            $post = Post::find($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;

            if(!$post)
                exit(‘指定文章不存在!’);

}

            $postUrl = route(‘post.update’,[‘post’=>$post]);
            $csrf_field = csrf_field();
            $html = <<<CREATE
                <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>
CREATE;
            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’);

        /**
         * 在存储器中更新指定小说
         *
         * @param Request $request
         * @param int $id
         * @return Response
         */
        public function update(Request $request, $id)
        {
            $post = Post::find($id);
            if(!$post)
                exit(‘指定文章不设有!’);

    $posts[$id][‘title’] = trim($title);
    $posts[$id][‘content’] = trim($content);

            $title = $request->input(‘title’);
            $content = $request->input(‘content’);

    Cache::put(‘posts’,$posts,60);
    return
redirect()->route(‘post.show’,[‘post’=>Cache::get(‘post_id’)]);
}
3.4 删除文章

            $post->title = $title;
            $post->content = $content;

我们还足以动用destroy方法删除小说:

            $post->save();

/**
* 从存储器中移除指定小说
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
    $posts = Cache::get(‘posts’,[]);
    if(!$posts || !$posts[$id])
        exit(‘Nothing Deleted!’);

            return
redirect()->route(‘post.show’,[‘post’=>$post]);
        }

    unset($posts[$id]);
    Cache::decrement(‘post_id’,1);

        /**
         * 从存储器中移除指定小说
         *
         * @param int $id
         * @return Response
         */
        public function destroy($id)
        {
            $post = Post::find($id);
            if(!$post)
                exit(‘指定被删去小说不存在!’);

    return redirect()->route(‘post.index’);

            if($post->delete()){
                redirect()->route(‘post.index’);
            }else{
                exit(‘删除小说败北!’);
            }
        }
    }

}
要去除文章,要求参考编辑表单伪造删除表单方法为DELETE(一般接纳AJAX删除),那里不再演示。

亟需专注的是在show方法中,大家率先从缓存中取小说数量,缓存中不存在才会去数据库取,同时将数据回写到缓存中,由于对数据库的操作大多数都是读操作,所以这点小小的创新对质量却有很大升级,更加是在海量数据时。其余大家还将访问量持久化到缓存中以升高品质。

3.5 小说列表

3、在模型事件中动用缓存

最终我们再来定义一个用于浮现所有小说列表的index方法:

咱俩仍可以通过模型事件在篇章展开增删改的时候接触相应事件将修改保存到缓存中,那里大家简要讲模型事件注册到AppServiceProvider的boot方法中:

/**
* 呈现文章列表.
*
* @return Response
*/
public function index()
{
    $posts = Cache::get(‘posts’,[]);
    if(!$posts)
        exit(‘Nothing’);

//保存之后更新缓存数据
Post::saved(function($post){
    $cacheKey = ‘post_’.$post->id;
    $cacheData = Cache::get($cacheKey);
    if(!$cacheData){
        Cache::add($cacheKey,$post,60*24*7);
    }else{
        Cache::put($cacheKey,$post,60*24*7);
    }
});

    $html = ‘<ul>’;

//删除之后清除缓存数据
Post::deleted(function($post){
    $cacheKey = ‘post_’.$post->id;
    $cacheData = Cache::get($cacheKey);
    if($cacheData){
        Cache::forget($cacheKey);
    }
    if(Cache::get(‘post_views_’.$post->id))
        Cache::forget(‘post_views_’.$post->id);
});

    foreach ($posts as
$key=>$post) {
        $html .= ‘<li><a
href=’.route(‘post.show’,[‘post’=>$key]).’>’.$post[‘title’].'</li>’;
    }

咱俩将缓存有效期设置为一周。那样在篇章创立或更新时会将数据保存到缓存,而除去小说时也会从缓存中移除数据,从而确保被剔除后的稿子查看详情时也不能浏览。

    $html .= ‘</ul>’;

    return $html;
}

Leave a Comment.