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 相关文章推荐
PHP开发文件系统实例讲解
Oct 09 PHP
php Undefined index的问题
Jun 01 PHP
php中模拟POST传递数据的两种方法分享
Sep 16 PHP
解析用PHP读写音频文件信息的详解(支持WMA和MP3)
May 10 PHP
Php无限级栏目分类读取的实现代码
Feb 19 PHP
PHP面向对象教程之自定义类
Jun 10 PHP
php+mysqli预处理技术实现添加、修改及删除多条数据的方法
Jan 30 PHP
PHP中PDO连接数据库中各种DNS设置方法小结
May 13 PHP
php基于mcrypt_encrypt和mcrypt_decrypt实现字符串加密解密的方法
Jul 12 PHP
thinkPHP5.0框架API优化后的友好性分析
Mar 17 PHP
php分享朋友圈的实现代码
Feb 18 PHP
Laravel多域名下字段验证的方法
Apr 04 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 编写大型网站问题集
2010/05/07 PHP
PHP学习笔记 IIS7下安装配置php环境
2012/10/29 PHP
用 Composer构建自己的 PHP 框架之使用 ORM
2014/10/30 PHP
PHP超牛逼无限极分类生成树方法
2015/05/11 PHP
jquery监控数据是否变化(修正版)
2011/04/12 Javascript
基于jquery的拖动布局插件
2011/11/25 Javascript
jquery 操作DOM案例代码分享
2012/04/05 Javascript
eval的两组性能测试数据
2012/08/17 Javascript
Node.js开源应用框架HapiJS介绍
2015/01/14 Javascript
js实现浏览器窗口大小被改变时触发事件的方法
2015/02/02 Javascript
3种不同的ContextMenu右键菜单实现代码
2016/11/03 Javascript
jquery实现焦点轮播效果
2017/02/23 Javascript
Vue组件化通讯的实例代码
2017/06/23 Javascript
浅谈React和Redux的连接react-redux
2017/12/04 Javascript
JS删除数组里的某个元素方法
2018/02/03 Javascript
vue+webpack 打包文件 404 页面空白的解决方法
2018/02/28 Javascript
React中嵌套组件与被嵌套组件的通信过程
2018/07/11 Javascript
vue .js绑定checkbox并获取、改变选中状态的实例
2018/08/24 Javascript
微信小程序日历/日期选择插件使用方法详解
2018/12/28 Javascript
浅谈react-router@4.0 使用方法和源码分析
2019/06/04 Javascript
Vue中实现权限控制的方法示例
2019/06/07 Javascript
原生js实现的移动端可拖动进度条插件功能详解
2019/08/15 Javascript
JavaScript获取某一天所在的星期
2019/09/05 Javascript
分享8个JavaScript库可更好地处理本地存储
2020/10/12 Javascript
用Python进行一些简单的自然语言处理的教程
2015/03/31 Python
python初学之用户登录的实现过程(实例讲解)
2017/12/23 Python
Python使用scipy模块实现一维卷积运算示例
2019/09/05 Python
django实现模板中的字符串文字和自动转义
2020/03/31 Python
keras topN显示,自编写代码案例
2020/07/03 Python
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
深入开展党的群众路线教育实践活动方案
2014/02/04 职场文书
环保公益广告语
2014/03/13 职场文书
遗嘱继承公证书
2014/04/09 职场文书
党员个人查摆剖析材料
2014/10/16 职场文书
优秀党支部申报材料
2014/12/24 职场文书
MySQL优化及索引解析
2022/03/17 MySQL