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性能优化 产生高度优化代码
Jul 22 PHP
PHP无刷新上传文件实现代码
Sep 19 PHP
PHP数字字符串左侧补0、字符串填充和自动补齐的几种方法
May 10 PHP
PHP判断表单复选框选中状态完整例子
Jun 24 PHP
PHP下通过QRCode类库创建中间带网站LOGO的二维码
Jul 12 PHP
推荐一款MAC OS X 下php集成开发环境mamp
Nov 08 PHP
PHP中一些可以替代正则表达式函数的字符串操作函数
Nov 17 PHP
PHP开发框架laravel安装与配置教程
Mar 13 PHP
php实现将字符串按照指定距离进行分割的方法
Mar 14 PHP
PHP实现加密文本文件并限制特定页面的存取的效果
Oct 21 PHP
ThinkPHP框架实现的MySQL数据库备份功能示例
May 24 PHP
PHP mongodb操作类定义与用法示例【适合mongodb2.x和mongodb3.x】
Jun 16 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
Syphon 使用方法
2021/03/03 冲泡冲煮
php修改时间格式的代码
2011/05/29 PHP
php生成局部唯一识别码LUID的代码
2012/10/06 PHP
php等比例缩放图片及剪切图片代码分享
2016/02/13 PHP
Laravel 队列使用的实现
2019/01/08 PHP
javascript Keycode对照表
2009/10/24 Javascript
基于JQUERY的两个ListBox子项互相调整的实现代码
2011/05/07 Javascript
jQuery选择器简明总结(含用法实例,一目了然)
2014/04/25 Javascript
JavaScript中的eval()函数使用介绍
2014/12/31 Javascript
js实现a标签超链接提交form表单的方法
2015/06/24 Javascript
JavaScritp添加url参数并将参数加入到url中及更改url参数的方法
2015/10/26 Javascript
直接拿来用的页面跳转进度条JS实现
2016/01/06 Javascript
javascript嵌套函数和在函数内调用外部函数的区别分析
2016/01/31 Javascript
基于BootStrap的图片轮播效果展示实例代码
2016/05/23 Javascript
利用Vue.js实现checkbox的全选反选效果
2017/01/18 Javascript
servlet+jquery实现文件上传进度条示例代码
2017/01/25 Javascript
JavaScript制作简单的框选图表
2017/05/15 Javascript
Angular2使用Angular CLI快速搭建工程(一)
2017/05/21 Javascript
angular4 如何在全局设置路由跳转动画的方法
2017/08/30 Javascript
浅谈JavaScript的innerWidth与innerHeight
2017/10/12 Javascript
详解Node.js模板引擎Jade入门
2018/01/19 Javascript
AngularJS实现与后台服务器进行交互的示例讲解
2018/08/13 Javascript
vue+VeeValidate 校验范围实例详解(部分校验,全部校验)
2018/10/19 Javascript
Vuex中的State使用介绍
2019/01/19 Javascript
jQuery内容过滤选择器与子元素过滤选择器用法实例分析
2019/02/20 jQuery
JavaScript实现的九种排序算法
2019/03/04 Javascript
Vuex中的Mutations的具体使用方法
2020/06/01 Javascript
[38:27]完美世界DOTA2联赛PWL S2 Forest vs FTD.C 第二场 11.26
2020/11/30 DOTA
Python数据结构与算法之完全树与最小堆实例
2017/12/13 Python
python for循环输入一个矩阵的实例
2018/11/14 Python
Django ORM 聚合查询和分组查询实现详解
2019/08/09 Python
Python如何定义有默认参数的函数
2020/08/10 Python
python实现三种随机请求头方式
2021/01/05 Python
暑假社会实践心得体会
2014/09/02 职场文书
免职证明样本
2014/10/23 职场文书
办公室主任岗位职责范本
2015/03/31 职场文书