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 相关文章推荐
PHP5.0对象模型探索之抽象方法和抽象类
Sep 05 PHP
目录,文件操作详谈―PHP
Nov 25 PHP
建站常用13种PHP开源CMS比较
Aug 23 PHP
php中邮箱地址正则表达式实现与详解
Apr 24 PHP
在yii中新增一个用户验证的方法详解
Jun 20 PHP
php用户注册页面利用js进行表单验证具体实例
Oct 17 PHP
使用PHP和HTML5 FormData实现无刷新文件上传教程
Sep 06 PHP
Zend Framework教程之Resource Autoloading用法实例
Mar 08 PHP
ThinkPHP自定义Redis处理SESSION的实现方法
May 16 PHP
php中照片旋转 (orientation) 问题的正确处理
Feb 16 PHP
PHP命名空间namespace及use的简单用法分析
Aug 03 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下关于Cannot use a scalar value as an array的解决办法
2010/08/08 PHP
php利用单例模式实现日志处理类库
2014/02/10 PHP
jQuery中的RadioButton,input,CheckBox取值赋值实现代码
2014/02/18 PHP
详解php比较操作符的安全问题
2015/12/03 PHP
Javascript的构造函数和constructor属性
2010/01/09 Javascript
20个非常有用的PHP类库 加速php开发
2010/01/15 Javascript
我遇到的参数传递中 双引号单引号嵌套问题
2010/02/11 Javascript
基于mootools 1.3框架下的图片滑动效果代码
2011/04/22 Javascript
jquery实现漂浮在网页右侧的qq在线客服插件示例
2013/05/13 Javascript
Jquery 实现表格颜色交替变化鼠标移过颜色变化实例
2013/08/28 Javascript
node.js中的socket.io入门实例
2014/04/26 Javascript
jQuery 选择器详解
2015/01/19 Javascript
详解JavaScript中的forEach()方法的使用
2015/06/08 Javascript
JS实现IE状态栏文字缩放效果代码
2015/10/24 Javascript
Angularjs之filter过滤器(推荐)
2016/11/27 Javascript
Bootstrap基本组件学习笔记之下拉菜单(7)
2016/12/07 Javascript
JavaScript DOM节点操作实例小结(新建,删除HTML元素)
2017/01/19 Javascript
Vue的土著指令和自定义指令实例详解
2018/02/04 Javascript
Vue常见面试题整理【值得收藏】
2018/09/20 Javascript
原生js实现移动端Touch轮播图的方法步骤
2019/01/03 Javascript
js神秘的电报密码 哈弗曼编码实现
2019/09/10 Javascript
vue父子模板传值问题解决方法案例分析
2020/02/26 Javascript
详解vue 组件的实现原理
2020/11/12 Javascript
Python简单实现安全开关文件的两种方式
2016/09/19 Python
Python解析excel文件存入sqlite数据库的方法
2016/11/15 Python
Python3.6实现连接mysql或mariadb的方法分析
2018/05/18 Python
Python pandas库中的isnull()详解
2019/12/26 Python
PyCharm+Pipenv虚拟环境开发和依赖管理的教程详解
2020/04/16 Python
详解Python爬虫爬取博客园问题列表所有的问题
2021/01/18 Python
猫途鹰:全球领先的旅游点评社区
2017/04/07 全球购物
英国手工制作的现代与经典的沙发和床:Love Your Home
2020/09/26 全球购物
大学生毕业自我评价范文分享
2013/11/07 职场文书
世界环境日活动总结
2015/02/11 职场文书
Pyhton模块和包相关知识总结
2021/05/12 Python
redis复制有可能碰到的问题汇总
2022/04/03 Redis
分享node.js实现简单登录注册的具体代码
2022/04/26 NodeJs