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 Mssql操作简单封装支持存储过程
Dec 11 PHP
PHP 强制下载文件代码
Oct 24 PHP
解析php中var_dump,var_export,print_r三个函数的区别
Jun 21 PHP
解析php多线程下载远程多个文件
Jun 25 PHP
解析php 版获取重定向后的地址(代码)
Jun 26 PHP
PHP使用GIFEncoder类生成的GIF动态图片验证码
Jul 01 PHP
PHP中把对象转换为关联数组代码分享
Apr 09 PHP
怎样搭建PHP开发环境
Jul 28 PHP
PHP判断一个数组是另一个数组子集的方法详解
Jul 31 PHP
php微信公众号开发之翻页查询
Oct 20 PHP
PHP addslashes()函数讲解
Feb 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文件下载处理方法分析
2015/04/22 PHP
PHP defined()函数的使用图文详解
2019/07/20 PHP
offsetParent 算法分析
2010/04/05 Javascript
关于document.cookie的使用javascript
2010/10/29 Javascript
javascript学习笔记(十五) js间歇调用和超时调用
2012/06/20 Javascript
js限制textarea每行输入字符串长度的代码
2012/10/31 Javascript
Javascript模块化编程(三)require.js的用法及功能介绍
2013/01/17 Javascript
javascript在子页面中函数无法调试问题解决方法
2014/01/17 Javascript
jQuery使用之设置元素样式用法实例
2015/01/19 Javascript
JS实现旋转木马式图片轮播效果
2017/01/18 Javascript
javascript 中null和undefined区分和比较
2017/04/19 Javascript
浅谈es6 javascript的map数据结构
2017/12/14 Javascript
深入理解Vue Computed计算属性原理
2018/05/29 Javascript
Vue Router的懒加载路径的解决方法
2018/06/21 Javascript
Bootstrap标签页(Tab)插件切换echarts不显示问题的解决
2018/07/13 Javascript
微信小程序遍历Echarts图表实现多个饼图
2019/04/25 Javascript
微信小程序下拉菜单效果的实例代码
2019/05/14 Javascript
JS中的算法与数据结构之二叉查找树(Binary Sort Tree)实例详解
2019/08/16 Javascript
python备份文件以及mysql数据库的脚本代码
2013/06/10 Python
轻松掌握python设计模式之访问者模式
2016/11/18 Python
Python实现的异步代理爬虫及代理池
2017/03/17 Python
老生常谈Python进阶之装饰器
2017/05/11 Python
pytorch 把MNIST数据集转换成图片和txt的方法
2018/05/20 Python
Python datetime包函数简单介绍
2019/08/28 Python
python3实现绘制二维点图
2019/12/04 Python
html5 video标签屏蔽右键视频另存为的js代码
2013/11/12 HTML / CSS
YSL圣罗兰美妆官方旗舰店:购买YSL口红
2018/04/16 全球购物
高性能装备提升营地:Kammok
2019/02/27 全球购物
Sperry澳大利亚官网:源自美国帆船鞋创始品牌
2019/07/29 全球购物
浪费资源的建议书
2014/03/12 职场文书
《分一分》教学反思
2014/04/13 职场文书
2014幼儿园班主任工作总结
2014/12/04 职场文书
运动会广播稿300字
2015/08/19 职场文书
CSS 实现多彩、智能的阴影效果
2021/05/12 HTML / CSS
php+laravel 扫码二维码签到功能
2021/05/15 PHP
python使用BeautifulSoup 解析HTML
2022/04/24 Python