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&amp;&amp;mysql)五
Oct 09 PHP
php中取得URL的根域名的代码
Mar 23 PHP
PHP curl模拟浏览器采集阿里巴巴的实现代码
Apr 20 PHP
谷歌音乐搜索栏的提示功能php修正代码
May 09 PHP
PHP运行环境配置与开发环境的配置(图文教程)
Jun 04 PHP
php中利用explode函数分割字符串到数组
Feb 08 PHP
php读取csc文件并输出
May 21 PHP
php调用淘宝开放API实现根据卖家昵称获取卖家店铺ID的方法
Jul 29 PHP
Yii实现文章列表置顶功能示例
Oct 18 PHP
php基于curl实现的股票信息查询类实例
Nov 11 PHP
浅谈htmlentities 、htmlspecialchars、addslashes的使用方法
Dec 09 PHP
PHP基于redis计数器类定义与用法示例
Feb 08 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中使用BigMap实例
2015/03/30 PHP
php使用post数组的键值创建同名变量并赋值的方法
2015/04/03 PHP
PHP中JSON的应用技巧
2015/10/10 PHP
php格式化json函数示例代码
2016/05/12 PHP
laravel5.6 框架邮件队列database驱动简单demo示例
2020/01/26 PHP
JQuery 实现的页面滚动时浮动窗口控件
2009/07/10 Javascript
jQuery+css实现图片滚动效果(附源码)
2013/03/18 Javascript
javascript中[]和{}对象使用介绍
2013/03/20 Javascript
javascipt基础内容--需要注意的细节
2013/04/10 Javascript
js拖拽一些常见的思路方法整理
2014/03/19 Javascript
jquery控制display属性为none或block
2014/03/31 Javascript
使用nodejs、Python写的一个简易HTTP静态文件服务器
2014/07/18 NodeJs
javascript字符串循环匹配实例分析
2015/07/17 Javascript
js console.log打印对像与数组用法详解
2016/01/21 Javascript
jquery分页插件jquery.pagination.js实现无刷新分页
2016/04/01 Javascript
js实现简易垂直滚动条
2017/02/22 Javascript
js中编码函数:escape,encodeURI与encodeURIComponent详解
2017/03/21 Javascript
javascript 中iframe高度自适应(同域)实例详解
2017/05/16 Javascript
JS实现带动画的回到顶部效果
2017/12/28 Javascript
Vue 组件传值几种常用方法【总结】
2018/05/28 Javascript
微信小程序仿RadioGroup改变样式的处理方案
2018/07/13 Javascript
一文快速详解前端框架 Vue 最强大的功能
2019/05/21 Javascript
Vue-cli打包后部署到子目录下的路径问题说明
2020/09/02 Javascript
JS实现购物车基本功能
2020/11/08 Javascript
python网络编程学习笔记(10):webpy框架
2014/06/09 Python
python模拟enum枚举类型的方法小结
2015/04/30 Python
django ManyToManyField多对多关系的实例详解
2019/08/09 Python
PythonPC客户端自动化实现原理(pywinauto)
2020/05/28 Python
详解python实现可视化的MD5、sha256哈希加密小工具
2020/09/14 Python
联想马亚西亚官方网站:Lenovo Malaysia
2018/09/19 全球购物
Pottery Barn阿联酋:购买家具、家居装饰及更多
2019/12/08 全球购物
自荐信格式范文
2013/10/07 职场文书
《沉香救母》教学反思
2014/04/19 职场文书
社区平安建设方案
2014/05/25 职场文书
房地产销售经理岗位职责
2015/02/02 职场文书
Windows10下安装MySQL8
2021/04/06 MySQL