Laravel使用memcached缓存对文章增删改查进行优化的方法


Posted in PHP onOctober 08, 2016

本文实例讲述了Laravel使用memcached缓存对文章增删改查进行优化的方法。分享给大家供大家参考,具体如下:

这里我们将以文章的增删改查作为实例系统讲述缓存的使用,这个实例是对之前创建RESTFul风格控制器实现文章增删改查这篇教程的改造和升级,我们将在其基础上融合进Eloquent ORM和模型事件,将应用的场景直接拉到生成环境。

1、准备工作

路由及控制器

路由的定义和控制器的创建保持和创建RESTFul风格控制器实现文章增删改查中一样。

创建数据表

关于文章对应数据表我们在数据库部分使用查询构建器实现对数据库的高级查询已有提及,这里我们使用之前创建的数据表即可。

创建文章模型

关于文章模型Post的创建也和之前Eloquent ORM部分讲ORM概述、模型定义及基本查询中创建的一致。

2、修改控制器

在之前我们是通过缓存实现对文章的增删改查操作,这里我们将其修改为通过数据库实现增删改查操作:

<?php
  namespace App\Http\Controllers;
  use Illuminate\Http\Request;
  use Cache;
  use App\Models\Post;
  use App\Http\Requests;
  use App\Http\Controllers\Controller;
  class PostController extends Controller
  {
    /**
     * 显示文章列表.
     *
     * @return Response
     */
    public function index()
    {
      //使用all获取所有数据,如果数据量大采用分页获取
      $posts = Post::all();
      if(!$posts)
        exit('还没有发布任何文章!');
      $html = '<ul>';
      foreach ($posts as $post) {
        $html .= '<li><a href='.route('post.show',['post'=>$post]).'>'.$post->title.'</li>';
      }
      $html .= '</ul>';
      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 = new Post;
      $post->title = $title;
      $post->content = $content;
      $post->save();
      return redirect()->route('post.show',['post'=>$post]);
    }
    /**
     * 显示指定文章
     *
     * @param int $id
     * @return Response
     */
    public function show($id)
    {
      $post = Cache::get('post_'.$id);
      if(!$post){
        $post = Post::find($id);
        if(!$post)
          exit('指定文章不存在!');
        Cache::put('post_'.$id,$post,60*24*7);
      }
      if(!Cache::get('post_views_'.$id))
        Cache::forever('post_views_'.$id,0);
      $views = Cache::increment('post_views_'.$id);
      Cache::forever('post_views_'.$id,$views);
      $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;
      return $html;
    }
    /**
     * 显示编辑指定文章的表单页面
     *
     * @param int $id
     * @return Response
     */
    public function edit($id)
    {
      $post = Post::find($id);
      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)
    {
      $post = Post::find($id);
      if(!$post)
        exit('指定文章不存在!');
      $title = $request->input('title');
      $content = $request->input('content');
      $post->title = $title;
      $post->content = $content;
      $post->save();
      return redirect()->route('post.show',['post'=>$post]);
    }
    /**
     * 从存储器中移除指定文章
     *
     * @param int $id
     * @return Response
     */
    public function destroy($id)
    {
      $post = Post::find($id);
      if(!$post)
        exit('指定被删除文章不存在!');
      if($post->delete()){
        redirect()->route('post.index');
      }else{
        exit('删除文章失败!');
      }
    }
  }

需要注意的是在show方法中,我们首先从缓存中取文章数据,缓存中不存在才会去数据库取,同时将数据回写到缓存中,由于对数据库的操作大部分都是读操作,所以这一点小小的改进对性能却有很大提升,尤其是在海量数据时。此外我们还将访问量持久化到缓存中以提升性能。

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

我们还可以通过模型事件在文章进行增删改的时候触发相应事件将修改保存到缓存中,这里我们简单讲模型事件注册到AppServiceProvider的boot方法中:

//保存之后更新缓存数据
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);
  }
});
//删除之后清除缓存数据
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);
});

我们将缓存有效期设置为一周。这样在文章创建或更新时会将数据保存到缓存,而删除文章时也会从缓存中移除数据,从而保证被删除后的文章查看详情时也不能浏览。

希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。

PHP 相关文章推荐
基于文本的访客签到簿
Oct 09 PHP
PHP编程中字符串处理的5个技巧小结
Nov 13 PHP
php一句话cmdshell新型 (非一句话木马)
Apr 18 PHP
php 验证码制作(网树注释思想)
Jul 20 PHP
Ajax实时验证用户名/邮箱等是否已经存在的代码打包
Dec 01 PHP
探讨php中header的用法详解
Jun 07 PHP
部署PHP时的4个配置修改说明
Oct 19 PHP
php获得客户端浏览器名称及版本的方法(基于ECShop函数)
Dec 23 PHP
[原创]smarty简单模板变量输出方法
Jul 09 PHP
phpmailer绑定邮箱的实现方法
Dec 01 PHP
php实现的数组转xml案例分析
Sep 28 PHP
tp5.1 实现setInc字段自动加1
Oct 18 PHP
PHP  实现等比压缩图片尺寸和大小实例代码
Oct 08 #PHP
Laravel Memcached缓存驱动的配置与应用方法分析
Oct 08 #PHP
yii通过小物件生成view的方法
Oct 08 #PHP
php获取服务器操作系统相关信息的方法
Oct 08 #PHP
Yii2创建多界面主题(Theme)的方法
Oct 08 #PHP
php微信开发之自定义菜单完整流程
Oct 08 #PHP
yii2.0数据库迁移教程【多个数据库同时同步数据】
Oct 08 #PHP
You might like
PHP的面试题集
2006/11/19 PHP
Discuz! 5.0.0论坛程序中加入一段js代码,让会员点击下载附件前自动弹出提示窗口
2007/04/18 PHP
php mail to 配置详解
2014/01/16 PHP
PHP读取并输出XML文件数据的简单实现方法
2017/12/22 PHP
js replace正则表达式应用案例讲解
2013/01/17 Javascript
JavaScript子类用Object.getPrototypeOf去调用父类方法解析
2013/12/05 Javascript
简单谈谈javascript代码复用模式
2015/01/28 Javascript
JavaScript中通过prototype属性共享属性和方法的技巧实例
2015/03/13 Javascript
WordPress中利用AJAX异步获取评论用户头像的方法
2016/01/08 Javascript
Javascript的表单验证长度
2016/03/16 Javascript
大型JavaScript应用程序架构设计模式
2016/06/29 Javascript
vue项目中使用tinymce编辑器的步骤详解
2018/09/11 Javascript
解决Vue中引入swiper,在数据渲染的时候,发生不滑动的问题
2018/09/27 Javascript
js中获取URL参数的共用方法getRequest()方法实例详解
2018/10/24 Javascript
vue实现记事本功能
2019/06/26 Javascript
微信小程序 多行文本显示...+显示更多按钮和收起更多按钮功能
2019/09/26 Javascript
[03:09]DOTA2亚洲邀请赛 LGD战队出场宣传片
2015/02/07 DOTA
python数组过滤实现方法
2015/07/27 Python
Python callable()函数用法实例分析
2018/03/17 Python
python保存数据到本地文件的方法
2018/06/23 Python
python MNIST手写识别数据调用API的方法
2018/08/08 Python
django的ORM模型的实现原理
2019/03/04 Python
python二进制读写及特殊码同步实现详解
2019/10/11 Python
python将字符串转变成dict格式的实现
2019/11/18 Python
收藏!10个免费高清视频素材网站!【设计、视频剪辑必备】
2021/03/18 杂记
使用Html5 Stream开发实时监控系统
2020/06/02 HTML / CSS
日本最大的眼镜购物网站:Oh My Glasses
2016/11/13 全球购物
澳大利亚冒险体验:Adrenaline(跳伞、V8赛车、热气球等)
2017/09/18 全球购物
车库门开启器、遥控器和零件:Chamberlain
2019/04/09 全球购物
美国在线鞋类零售商:LifeStride
2019/06/09 全球购物
ShellScript面试题一则-ShellScript编程
2014/06/24 面试题
遗嘱公证书标准样本
2014/04/08 职场文书
户外活动总结范文
2014/04/30 职场文书
2015年宣传部个人工作总结
2015/05/14 职场文书
运动会广播稿200字
2015/08/19 职场文书
合作意向书范本
2019/04/17 职场文书