问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

PHP DUXCMS如何开启页面缓存

发布网友 发布时间:2022-04-06 02:47

我来回答

2个回答

懂视网 时间:2022-04-06 07:08

推荐:《PHP视频教程》《redis教程》

php redis 实现全页缓存系统

之前的一个项目说的一个功能,需要在后台预先存入某个页面信息放到数据库,比如app的注册协议,用户协议,这种.然后在写成一个php页面,app在调用接口的时候访问这个页面.当时我就发现一个问题,这些协议往往几个月才会修改一次,而每一次用户查看这些协议的时候,nginx都会重新从数据库读取文件,速度会很慢慢了.

如下图m_about.php是我生成的数据页,

企业微信截图_15998021311479.png

在虚拟机环境下从数据库加载出来重新生成文件需要2.4s(当然实际的测试环境会快一点).

既然这种页面数据都是更新少,为什么不缓存起来呢,想到之前看的redis常用应用里面有一个全页缓存系统(full page cache).不如写一个试试看.

代码思路

redis使用的是phpredis扩展,当然你也可是用predis扩展,只不过需要更改里面几个读取函数而已.

关于缓存系统的接口,我这里参考了laravel里面cache系统.这个系统的设计接口我觉得设置的很清晰,里面不只是包含redis,还可以使用文件,mysql,memcache.

当然全页缓存用不到那么多东西.只是借用他的函数设计.首先是函数getUrlText,这个是获取全页面的数据,这里没有想到太多,直接使用file_get_contents,当然你也可以改写成curl函数

/**
 * 获取对应的url的信息
 * @param string $url 对应的地址
 * @return boolean|string
 */
 public function getUrlText($url)
 {
 if (empty($url)) {
  return false;
 }
 return file_get_contents($url);

 }

其次是几个借鉴cache系统的函数,remember函数,记忆缓存,这个是对外的最重要的接口,一般在缓存系统里面直接使用它就好.

/**
 * 记录对应的缓存,如果之前存在则返回原本的缓存
 * @param string $cacheName 缓存名
 * @param string | callback $urlOrCallback 需要缓存的数据地址.可以是一个 网页地址也一个可回调类型,如果不是可回调类型,则判定是一个网址
 * @param null | int $ttl 缓存过期时间,如果不过期就是用默认值null
 * @throws Exception 如果无法访问地址
 * @return boolean|string 缓存成功返回获取到的页面地址
 */
 public function remember($cacheName, $urlOrCallback, $ttl = null)
 {
 $value = $this->get($cacheName);//检查缓存是否存在
 if (!$value) {
  //之前没有使用键
  if (is_callable($urlOrCallback)) {
  $text = $urlOrCallback();
  } else {
  //如果不是回调类型,则尝试读取网址
  $text = $this->getUrlText($urlOrCallback);
  }

  if (empty($text)) {
  throw new Exception('can not get value:' . $urlOrCallback);
  }
  $this->put($cacheName, $text, $ttl);
  return $text;
 } else {
  return $value;
 }

 }

refresh函数,刷新缓存函数,如果缓存页面被更新了,就去刷新它.

/**
 * 更新缓存,并返回当前的缓存
 * @param string $cacheName 缓存名
 * @param string | callback $urlOrCallback 需要缓存的数据地址.可以是一个 网页地址也一个可回调类型,如果不是可回调类型,则判定是一个网址
 * @param null | int $ttl 过期时间,如果不过期就是用默认值null
 * @return boolean|string 缓存成功返回获取到的页面地址
 */
public function refresh($cacheName, $urlOrCallback, $ttl = null)
{
 $this->delete($cacheName);
 return $this->remember($cacheName, $urlOrCallback, $ttl);
}

剩下的两个代码文件.一个是redisFPC.php,这是全页缓存的demo,一个是测试用的文件
fpcTest.php
这里是用的是github,连接到我本人的git博客上面.如果连接github有问题,可以看本文最后给的完整代码.

测试

我们在这里测试,第一次加载因为需要读取对应的m_ahout的信息,所以慢一点

企业微信截图_15998021867240.png

第二次加载因为从redislimian 读取了,所以会快的多
企业微信截图_1599802202828.png

使用建议

代码我认为已经给了足够多的接口了,在第一次缓存的时候使用remember函数记录缓存,之后如果缓存变化后使用refresh函数,更新缓存即可.如果可能的话,尽量使用ttl设置缓存的过期时间.

完整代码

redisFPC.php

<?php
namespace RedisFPC;
class RedisFPC
{
 /**
 * php redis的访问类
 * @var unknown
 */
 private $redis;

 /**
 * 构造函数
 * @param array $redis 使用phpredis的类
 * @param 是否连接成功
 */
 public function __construct($redis = [])
 {
 
 //$this->redis = $redis;
 $this->redis = new Redis();
 return $this->redis->connect('127.0.0.1');
 }
 /**
 * 记录对应的缓存,如果之前存在则返回原本的缓存
 * @param string $cacheName 缓存名
 * @param string | callback $urlOrCallback 需要缓存的数据地址.可以是一个 网页地址也一个可回调类型,如果不是可回调类型,则判定是一个网址
 * @param null | int $ttl 缓存过期时间,如果不过期就是用默认值null
 * @throws Exception 如果无法访问地址
 * @return boolean|string 缓存成功返回获取到的页面地址
 */
 public function remember($cacheName, $urlOrCallback, $ttl = null) 
 {
 $value = $this->get($cacheName);//检查缓存是否存在
 if (!$value) {
  //之前没有使用键
  if (is_callable($urlOrCallback)) {
  $text = $urlOrCallback();
  } else {
  //如果不是回调类型,则尝试读取网址
  $text = $this->getUrlText($urlOrCallback);
  }
  
  if (empty($text)) {
  throw new Exception('can not get value:' . $urlOrCallback);
  }
  $this->put($cacheName, $text, $ttl);
  return $text;
 } else {
  return $value;
 }
 
 }
 /**
 * 获取对应的缓存值
 * @param string $cacheName 缓存名
 * @return String | Bool,如果不存在返回false,否则返回对应的缓存页信息
 */
 public function get($cacheName)
 {
 return $this->redis->get($this->getKey($cacheName));
 }
 /**
 * 将对应的全页缓存保存到对应redis中
 * @param string $cacheName 缓存名
 * @param string $value
 * @param null | int $ttl 过期时间,如果不过期就是用默认值null
 * @return boolean 保存成功返回true
 */
 public function put($cacheName, $value, $ttl = null) 
 {
 if (is_null($ttl)) {
  return $this->redis->set($this->getKey($cacheName), $value);
 } else {
  return $this->redis->set($this->getKey($cacheName), $value, $ttl);
 }
 
 }
 /**
 * 删除对应缓存
 * @param string $cacheName 缓存名
 */
 public function delete($cacheName)
 {
 return $this->redis->delete($this->getKey($cacheName));
 }
 
 /**
 * 更新缓存,并返回当前的缓存
 * @param string $cacheName 缓存名
 * @param string | callback $urlOrCallback 需要缓存的数据地址.可以是一个 网页地址也一个可回调类型,如果不是可回调类型,则判定是一个网址
 * @param null | int $ttl 过期时间,如果不过期就是用默认值null
 * @return boolean|string 缓存成功返回获取到的页面地址
 */
 public function refresh($cacheName, $urlOrCallback, $ttl = null)
 {
 $this->delete($cacheName);
 return $this->remember($cacheName, $urlOrCallback, $ttl);
 }
 /**
 * 获取对应的url的信息
 * @param string $url 对应的地址
 * @return boolean|string
 */
 public function getUrlText($url)
 {
 if (empty($url)) {
  return false;
 } 
 return file_get_contents($url);
 
 }
 /**
 * 生成全页缓存键名
 * @param string $cacheName 需要缓存的名称
 * @return string 对应的在redis中的键名
 */
 private function getKey($cacheName)
 {
 return 'FPC:'. $cacheName;
 }
}

测试用的test代码
注意这里的url写的是本地的缓存url

<?php 
use RedisFPCRedisFPC;

require_once 'redisFPC.php';
/* $text = file_get_contents('http://localhost:1002/m_about.php');
var_dump($text); */
$url = 'http://localhost:1002/m_about.php';

$fpc = new RedisFPC();
echo $fpc->remember('服务协议', $url, 60*60*24);

热心网友 时间:2022-04-06 04:16

1.页面缓存。页面缓存指之前加载过的页面以文件方式缓存在服务器中,在一段时间内再次加载相同页面时无需重新执行页面逻辑直接加载静态页面。rubyPHP的页面缓存是自动进行的,在config/tpl.php中可配置是否启用缓存以及缓存文件的有效期。当然这仅仅是全局设置,在调用视图时可重新指定是否启用缓存以及缓存有效期。

2.SQL缓存。sql缓存指之前执行过的查询sql语句以及他的结果缓存在内存中,在一段时间内用相同的sql语句执行查询操作时不经过数据库直接返回内存中数据。rubyPHP使用Redis以键值方式缓存sql语句以及他的对应结果。rubyPHP能够在php7上完美运行。(附:关于windows php7 redis 扩展的下载参照我的另一篇博客:http://blog.csdn.net/fanghailiang2016/article/details/51396649)。rubyPHP重写了mysql_query以及mongo_query方法,在执行查询sql查询语句时会优先加载未过期的缓存数据。与页面缓存类似,sql缓存的全局配置路径为config/redis.php,在具体执行sql语句前可重新执行是否使用缓存以及缓存有效期。

3.读写分离。读写分离是建立在主从同步基础上为了减轻服务器压力,将查询语句转移到从服务器上执行的解决方案。rubyPHP重写了mysql_query,mongo_query函数,除了对查询语句进行内存级缓存的优化,同时也将查询语句放到了从服务器上执行。mysql的主从配置文件路径为config/mysql.php。

4.html压缩。html压缩配合页面缓存,前者降低了服务器端压力,后者减少了输出内容所占空间,将html文件中的空格换行等进行压缩,减少了输出文件的大小,在一定程度上保护了html的安全。

rubyPHP在代码结构上模仿CI,在功能上模仿thinkPHP。

rubyPHP的功能包含以下几方面:

1.使用了thinkPHP的M方法操作数据库。对于一些简单的sql语句无需手工写,用熟悉的M()->where()->limit()->find()这样的语法即可完成。曾经面试有人问我为什么thinkPHP的M方法能够进行连续操作,现在终于明白是使用了单利模式。

2.屏蔽了数据库的差异。M方法的另一个优点是用来组件sql语句,对高层屏蔽数据库差异。当然,对于复杂的查询,M方法是做不到的,此时可以使用已被重写过的mysql_query以及mongo_query执行你的sql语句。

3.自定义路由。这一点模仿了CI的route.php,将url同控制器的映射关系写到一个配置文件里。

不足之处:

view文件不支持变量循环输出。目前的解决方案是使用angularjs调用接口在页面输出内容。框架示例程序便是一个使用angularjs的和bootstrap的界面。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
在公交车上实施扒窃,会受到怎样的处罚? 交通违法行为识别 公交车扒窃会如何处罚? 郑州鱼缸清洗找哪家公司做得比较好? 郑州有没有专业维修鱼缸,清洗鱼缸的? ...的鱼缸,放在办公室养些鱼水草之类的。郑州哪里有卖这样的鱼缸。_百... 我们公司想要定做个观赏鱼缸,不知道郑州哪家公司最专业? 谁知道郑州生态鱼缸定做哪家做的效果最好? 联想电脑启用无线功能的功能键? 笔记本电脑怎么连接网笔记本电脑怎样连接无线网 thinkphp 怎么做redis缓存技术 如何使用phpredis缓存静态页面 php 分页查询怎么redis缓存 php面向对象中对属性和方法定义的问题 在php中,将一个对象赋给了一个属性,那调这个属性的对象是那个, PHP中对象属性的作用是什么? php中如何修改数据库元素的多个属性? PHP中使用DOM方法如何根据XML子节点值或子节点属性删除所在的父节点? 求解php怎么修改js文件中对象的属性,并保存文件 帮忙啊。。。快点 高分 PHP扩展 怎么访问常量属性 PHP修改属性 php中使用正则表达式或其他方法去除html标签的样式属性(不能写死的) PHP XML增加删除节点属性 如何使用php正则去掉table的所有属性? PHP中 unset删除对象中的私有属性后 用isset判断这个属性是否存在,但是一直返回true php如何删除标签内的属性 php 题目 在 windows 平台下部署 php 开发环境,通常需要安装什么组件,每个组件 怎么在自己电脑机器上快速搭建PHP开发测试环境 php开发环境可以在win7系统上搭建吗? php用redis缓存和用数组缓存的区别 redis是缓存系统还是数据库 PHP web缓存 php文件缓存,redis 哪个更快 有大神知道emlog支持PHP的redis扩展缓存吗? 怎么用php代码实现登录 PHP怎么实现登录和注册? 如何用php 做游客登录功能 PHP用二维数组实现登陆功能 如何用php实现自动登录别的网站 用PHP语言做一个简单的登陆页面 怎么用php实现模态框的登录? 用php实现网页的登录功能,请问如何用session 获得登录状态以及登录的用户名 在Thinkphp中 自己怎么写一个简单的登录功能出来,求代码 求PHP大神,用PHP编写一个程序:根据下面的表和登录页面,编写一个实现登录的程序。要PHP编的 求个简单的网站登录功能的代码(php实现)。在线等,急。 如何用php程序清空文件夹(包括子目录)内的所有文件 有什么办法可以找出多层目录下的php文件? 请教一个问题,怎么让LNMP环境的PHP支持snmp这个扩展 windows下php对snmp的支持