搜尋
首頁後端開發php教程如何用缓存技术?

请教各位高手,例如我的index.php页面主要如下:
include("IncDB.php"); 
session_start () ;
$result=mysql_query("SELECT * FROM userlinks where id='a02' and userid=‘".$_SESSION['id']."’ order by datetime desc limit 1",$link);
$row = mysql_fetch_row($result);
echo "$row[1]"; 
echo"
"; 
echo "$row[2]";

mysql_close($link); 
?> 

每次用户登录后,都要从数据库里读数据,再显示出来,会比较慢,有没有什么方法如缓存技术,当信息无变化时,能直接从某页面调取,而 不用每次再从数据库查询,然后再显示出来。谢谢大家。


回复讨论(解决方案)

我自己在网上看,可以用缓存技术,但我还是不明白具体怎么做?还请指教。谢谢!

是 可以用缓存
不过你的缓存策略是什么
缓存到哪里
如何知道数据发生了变化

这些你思考过吗?

我不懂啊哥,没思考过。因为上面这个页面会根据不同 的用户,内容也会变化,我琢磨缓存放在网站肯定不行吧,要不得为每一个用户建一个缓存备用,是不是应该在客户端?数据发生变化,是不是可以让后台来校验,但网页主动刷新时,就能把最新信息显示出来?

我的需求就是找一个办法,使得用户在打开这个页面时,不用每次都从数据库提数据,那样确实比较慢,因为该页面提取的数据比较多。

您能帮我看看怎么弄呢?谢谢!

不过这个页面如发生变化,有两种情况,一个是后台管理时做调整,内容会变化,这个可能几个月才能有一次,可以忽略;二是,用户通过EDIT.php页面修改userlinks里面的数据,这时候,内容就要发生变化了。
另外,我能把某个页面,如EDIT.php缓存到客户端吗?我发现每次用户打开都特别慢。
不知道我说清楚没有,大神。

你可以存SQL的查询结果,储存到缓存里面

文件缓存。

<?php include("IncDB.php"); session_start () ;$cache_file = dirname(__FILE__).'/cache.file';$expire = 60;$cache_data = json_decode(file_get_contents($cache_file), true);if(!$cache_data || time()-$cache_data['expire']>$expire){    $result=mysql_query("SELECT * FROM userlinks where id='a02' and userid=‘".$_SESSION['id']."’ order by datetime desc limit 1",$link);    $row = mysql_fetch_row($result);    $cache_data = json_encode(array('data'=>$row,'expire'=>time()));}else{    $row = $cache_data['data'];}echo "$row[1]"; echo"<br>"; echo "$row[2]";mysql_close($link); ?> 

谢谢各位大神。很抱歉,我很水,看了半天没明白这代码的含义,能帮我解释一下么?另外,6楼的代码是不是就是5楼说的,存SQL的查询结果,储存到缓存里面?
我觉得要是能实现把查询的数据存到本地,然后每次从本地读取就能实现我说的功能了。

我自己猜,好像代码是给缓存规定了一个更新时间,时间内就缓存读取,否则就数据库。如果这样,就不对了,因为,用户会通过edit.php页面随时就某个内容修改好多次,但也可能几个月都不改一次。因此如果对缓存规定更新时间不行。是否应该在edit页面中增加更新缓存的代码,而index页面直接读取本地缓存就行?如果本地没有,就读数据库?

对了,我贴的代码有误,提取的数据是多行,没有limit 1。不好意思。

建议你使用memcache缓存(把SQL的查询结果放到服务器的内存里),如果用户在edit.php更新了数据,那么就把memcache里的缓存清掉,然后index.php去查询缓存时,if(memcache缓存不存在){使用SQL语句更新数据}。

sorry,大哥,我不会啊,怎么用memcache啊?我在网上看到有说用这个的,是在edit页面增加语句么?还是其他?我啥都不懂啊。不好意思,能告诉我是什么代码,写在哪里?原谅我的无知。

index.php:

include("IncDB.php"); session_start () ;//使用memcache对象$memcache = new Memcache;$memcache->connect('memcache主机地址', 11211); //memcache默认端口号是11211if(!$memcache->get('results')){	$result = mysql_query("SELECT * FROM userlinks where id='a02' and userid=‘".$_SESSION['id']."’ order by datetime desc", $link);	$row = mysql_fetch_row($result);	echo "$row[1]"; 	echo"<br>"; 	echo "$row[2]";	mysql_close($link); 	$memcache->set('results', $row);}


edit.php:
//在edit.php里,用户更新了数据,则清除memcache缓存。//用户更新数据代码.....$memcache = new Memcache;$memcache->connect('memcache主机地址', 11211); //memcache默认端口号是11211$memcache->delete('results', 0); //0表示该元素立即删除

既然 也可能几个月都不改一次,那么直接生成和使用静态页就是了,何必用什么缓存?

谢谢大神们。我回去试试。谢谢!
回xuzuning,是后台改,几个月才一次,但用户改,可能频率就高了。谢谢关心。

我追问一下misakaqunianx.,我不懂啊。1、根据您给的方法我提取数据比如有10条,缓存这10条数据后,如果用户后来改了其中的一条如第5条,也能通过EDIT页面的$memcache实现精确更新该条数据么?
2、在index页面中,哪一句是说从本地缓存提取数据的?我看不明白。
3、如果用户在本地有两个用户名,不会影响吧?
不好意思,问的太弱了。

谢谢大神们!

我追问一下misakaqunianx.,我不懂啊。1、根据您给的方法我提取数据比如有10条,缓存这10条数据后,如果用户后来改了其中的一条如第5条,也能通过EDIT页面的$memcache实现精确更新该条数据么?
2、在index页面中,哪一句是说从本地缓存提取数据的?我看不明白。
3、如果用户在本地有两个用户名,不会影响吧?
不好意思,问的太弱了。


只要你的用户修改了任意数据,你就把memcache的缓存清除掉,这样就可以保证不管修改了什么,都会重新用SQL查询数据库。
$memcache->get('results')是从内存里取出缓存(memcache不是文件缓存,而是放到服务器内存里缓存)
如果要使用memcache,需要开启memcache的扩展,方法就百度去吧。

我要是上传到空间里去,就不必要我还要增加您说的代码即可吧?再开启扩展了吧,服务商自己应该开好了吧,谢谢。

我要是上传到空间里去,就不必要我还要增加您说的代码即可吧?再开启扩展了吧,服务商自己应该开好了吧,谢谢。


一般情况下,服务商都是开启了的。

谢谢,我回去试后结贴,谢谢。

好像不行啊,我增加以后,页面什么都显示不了了。我还有几个疑问请教:
1、按照我的理解,逻辑是先判断缓存有无数据,如有则从缓存提取数据;如没有,则从数据库提取数据,并ECHO,然后 $memcache->set('results', $row);但是您的代码,我理解不了这个思路,没有if else,只有if。
2、如果我的页面中需要提取好几次数据,如$result = mysql_query...,还有$result1 = mysql_query...,是不是每次提取数据时都得加这些代码?还是一个页面,只要设置一次,然后get('results'),get('results1'),get('results2')就可以了?
3、$memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211); //memcache默认端口号是11211
这一句,我能加到IncDB.php(这是链接数据库设置的文件)中去,统一调用么?
谢谢指点。

能教教我么?谢谢啊。

这个。。。。。。。

大神们,有空稍微理一下我吧...

好像不行啊,我增加以后,页面什么都显示不了了。我还有几个疑问请教:
1、按照我的理解,逻辑是先判断缓存有无数据,如有则从缓存提取数据;如没有,则从数据库提取数据,并ECHO,然后 $memcache->set('results', $row);但是您的代码,我理解不了这个思路,没有if else,只有if。
2、如果我的页面中需要提取好几次数据,如$result = mysql_query...,还有$result1 = mysql_query...,是不是每次提取数据时都得加这些代码?还是一个页面,只要设置一次,然后get('results'),get('results1'),get('results2')就可以了?
3、$memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211); //memcache默认端口号是11211
这一句,我能加到IncDB.php(这是链接数据库设置的文件)中去,统一调用么?
谢谢指点。


1、我忘了写了   else{ $row = $memcache->get('results'); }
2、每次提取数据时都需要加这些代码先判断缓存。
3、不需要放到数据库配置里,memcache是缓存扩展,放在系统配置里就可以了。

哥 啊,是在代码的最后,加上else{ $row = $memcache->get('results'); }就可以了?系统配置是什么?我的就是这个页面,如果不把那些代码($memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211);)放在一个文件里调用,如IncDB.php,我每次都得再写啊。我没有专门的系统配置页面。

使用 memcache 需要安装 memcached 服务器和与 php 版本对应的 php_memcache 扩展

如果是全局使用,那么
$memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211);
只需写一次,当然可以写在嵌入文件中
但你并不能保证不会在函数里使用

其实你的核心问题还是我一开始就提出的:你如何知道内容发生的变化
如果你不解决这个问题,什么其他技术手段的是枉然的

哥 啊,是在代码的最后,加上else{ $row = $memcache->get('results'); }就可以了?系统配置是什么?我的就是这个页面,如果不把那些代码($memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211);)放在一个文件里调用,如IncDB.php,我每次都得再写啊。我没有专门的系统配置页面。


既然没有配置文件,那就放到IncDB.php里就好了。
<?phpinclude("IncDB.php"); session_start () ;//使用memcache对象$memcache = new Memcache;$memcache->connect('memcache主机地址', 11211); //memcache默认端口号是11211if(($row = $memcache->get('results')) == false){		//缓存里没有得到results,则去数据库查询	$result = mysql_query("SELECT * FROM userlinks where id='a02' and userid=‘".$_SESSION['id']."’ order by datetime desc", $link);	$row = mysql_fetch_row($result);	mysql_close($link); 	$memcache->set('results', $row); //查询数据库之后再放入缓存}echo "$row[1]"; echo"<br>"; echo "$row[2]";?>

使用 memcache 需要安装 memcached 服务器和与 php 版本对应的 php_memcache 扩展

如果是全局使用,那么
$memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211);
只需写一次,当然可以写在嵌入文件中
但你并不能保证不会在函数里使用

其实你的核心问题还是我一开始就提出的:你如何知道内容发生的变化
如果你不解决这个问题,什么其他技术手段的是枉然的


是用户在EDIT页面,修改数据后,该内容才会发生变化。也就是说,我可以写在IncDB.php文件里调用就可以了?谢谢!

谢谢两位大神。。。我试试。

memcached 的内容是保存在内存中的,因此系统重启后,缓存的内容都会消失。
所以仅在修改的时候写缓存是不够的

那有办法么?我的初衷就是想提高网页响应速度,memcached能够实现么?

另外,如果我有1万个用户,那么在服务器上就得要存1万套数据?不知是否理解正确。我觉得能存在客户端最好,但不知怎么把一条条数据存在客户端并读取。

要做缓存,肯定要考虑更新数据的情况,比如你说的用户有可能修改资料。 你在程序里,就在用户修改资料后,把相应的缓存删掉就行了。

谢谢楼上的提示。
我崩溃了,就是不行,也没有报错。我是这么写的

include("IncDB.php"); 
session_start () ;
 $memcache = new Memcache;
$memcache->connect('localhost',11211) or die("链接失败!");
if(($row = $memcache->get('results')) == false){
 $result = mysql_query("SELECT * FROM userlinks where id='a02' and userid='".$_SESSION['id']."' order by datetime desc ", $link);
    $row = mysql_fetch_row($result);
 echo "$row[1]"; 
echo"
"; 
echo "$row[2]";
    $memcache->set('results', $row); 
 mysql_close($link);}
else{ $row = $memcache->get('results'); 
echo "$row[1]"; 
echo"
"; 
echo "$row[2]";}

?> 

谢谢楼上的提示。
我崩溃了,就是不行,也没有报错。我是这么写的

include("IncDB.php"); 
session_start () ;
 $memcache = new Memcache;
$memcache->connect('localhost',11211) or die("链接失败!");
if(($row = $memcache->get('results')) == false){
 $result = mysql_query("SELECT * FROM userlinks where id='a02' and userid='".$_SESSION['id']."' order by datetime desc ", $link);
    $row = mysql_fetch_row($result);
 echo "$row[1]"; 
echo"
"; 
echo "$row[2]";
    $memcache->set('results', $row); 
 mysql_close($link);}
else{ $row = $memcache->get('results'); 
echo "$row[1]"; 
echo"
"; 
echo "$row[2]";}

?> 


在程序的各个位置打印一下可能出错的变量,排错是个麻烦的过程。

这么晚还回了?感谢。弱弱的问,咋写啊。不要问我有多水~~~

这么晚还回了?感谢。弱弱的问,咋写啊。不要问我有多水~~~


用var_dump()来打印啊。。。话说,这个memcache缓存你完全可以自己找点资料,看看别人的博客去学习的。。。

这么问永远没个头,把里面提到的几个关键的内容去学习一下,然后在学习的时候遇到不明白的地方再来问效率会更好 不然下次你还是得问这些问题。

memcache
文件缓存

我其实是研究了几天之后,还是没搞明白才发帖求助的,可能是基础太差,也可能是智商不在家,反正没搞懂。

我写成这样,是不是就能打印错误了?

include("IncDB.php"); 
session_start () ;
 $memcache = new Memcache;
$memcache->connect('localhost',11211) or die("链接失败!");
if(($row = $memcache->get('results')) == false){
 $result = mysql_query("SELECT * FROM userlinks where id='a02' and userid='".$_SESSION['id']."' order by datetime desc ", $link);
    $row = mysql_fetch_row($result);
var_dump($row)
 echo "$row[1]"; 
echo"
"; 
echo "$row[2]";
    $memcache->set('results', $row); 
 mysql_close($link);}
else{ $row = $memcache->get('results'); 
echo "$row[1]"; 
echo"
"; 
echo "$row[2]";
var_dump($row)}

?> 

既然你是在调试程序,并多出打印点
那么你应该给出程序的运行结果吧?

xuzuning 好,我现在单位,没法把页面上传到空间,所有还不知道调试结果。另外,我那个多出打印点的代码对吗?
还有,我觉得您说的策略的确是问题,而且,我也觉得要是能把数据存到客户端是最好的。我的每个页面很简单,也很小,但内容都是从数据库里提取数据显示,而每个用户页面显示的内容,除了用户自己修改会立即有变化以外,其他一般变化不大(可能几个月才变一点)。因为每次从数据库提数慢,我就想如果能实现把每个用户的数据缓存在客户端,然后当其自己修改时再更新该缓存就可以了。不知道是否可以实现。另外,这些页面,当我在本地测试时很快,一上传空间就慢的没法用了。

再回PhpNewnew,我其实各种途径学习缓存有一个多礼拜,但确实没搞懂。我也知道老麻烦别人不好。放心,如果我还是没学会,我会及时结贴的。谢谢关心。



 你这个 用 memcache  是不行的。这个缓存技术用不了,你这个上面。

最好,缓存到服务器文件,注明一下时间。然后,用户每次改,也记录时间。时间不对上,就重新缓存。

这是概念。。

其实你现在的问题,是打开慢,这个暂时还不需要缓存的,你在数据表中,加索引,打开就很快了。

我看到这个帖子http://www.2cto.com/kf/201407/319353.html
上面好像就说了,可以在客户端存储读取数据。我不知道是否可行。

你先把概念弄清楚!本地是一个相对概念:
浏览器访问你的 php 网站,那么浏览器所在的机器就是本地
php 访问数据库服务器,那么 php 所在的机器就是本地
你给的那个连接中并没有说把数据缓存到了客户端(当然相对于数据库,php也是客户端)

如果你这的希望将页面缓存到客户的浏览器缓冲区去的话,只需要当客户再次访问时发个 304 头就可以了
当然你依然还是要知道数据是否发生了变化。于是问题又回到了原点: 你如何知道内容发生的变化
只有这个问题解决了,才有上技术手段的可能

用户在修改了内容以后就内容就发生变化了。我知道你有种对牛弹琴的感觉,但我确实low,也没办法。sorry
如果换个角度,我的原始需求就是希望不用每次访问数据库获得数据,来提高响应速度,您有什么建议?谢谢大神。

1. 先写一个memcache的简单实例,网上查下有很多,熟悉了之后,再应用到自己的代码中。

2. 提一点,memcache有一个过期时间的,设置了过期时间,就不用担心数据存到里面会越来越大了。

3. 大致思路,
a. 每次更新数据,更新之后,去memcached检查,如果存在,则更新memcached;如果不存在,则不做动作。
b. 每次访问数据,先去memcahced检查,如果存在则直接取出使用;如果不存在则从数据库获取,并存于memcached。

4. memcached有个小缺点,数据类型单一,且不会将数据写入硬盘。如果有这方面的需求,建议看看redis。redis还有主从备份。
redis用法请参照第1-3点,将memcached都改成redis。

还是没学会,我放弃了!谢谢各位大神。。。。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
您什麼時候使用特質與PHP中的抽像類或接口?您什麼時候使用特質與PHP中的抽像類或接口?Apr 10, 2025 am 09:39 AM

在PHP中,trait適用於需要方法復用但不適合使用繼承的情況。 1)trait允許在類中復用方法,避免多重繼承複雜性。 2)使用trait時需注意方法衝突,可通過insteadof和as關鍵字解決。 3)應避免過度使用trait,保持其單一職責,以優化性能和提高代碼可維護性。

什麼是依賴性注入容器(DIC),為什麼在PHP中使用一個?什麼是依賴性注入容器(DIC),為什麼在PHP中使用一個?Apr 10, 2025 am 09:38 AM

依賴注入容器(DIC)是一種管理和提供對象依賴關係的工具,用於PHP項目中。 DIC的主要好處包括:1.解耦,使組件獨立,代碼易維護和測試;2.靈活性,易替換或修改依賴關係;3.可測試性,方便注入mock對象進行單元測試。

與常規PHP陣列相比,解釋SPL SplfixedArray及其性能特徵。與常規PHP陣列相比,解釋SPL SplfixedArray及其性能特徵。Apr 10, 2025 am 09:37 AM

SplFixedArray在PHP中是一種固定大小的數組,適用於需要高性能和低內存使用量的場景。 1)它在創建時需指定大小,避免動態調整帶來的開銷。 2)基於C語言數組,直接操作內存,訪問速度快。 3)適合大規模數據處理和內存敏感環境,但需謹慎使用,因其大小固定。

PHP如何安全地上載文件?PHP如何安全地上載文件?Apr 10, 2025 am 09:37 AM

PHP通過$\_FILES變量處理文件上傳,確保安全性的方法包括:1.檢查上傳錯誤,2.驗證文件類型和大小,3.防止文件覆蓋,4.移動文件到永久存儲位置。

什麼是無效的合併操作員(??)和無效分配運算符(?? =)?什麼是無效的合併操作員(??)和無效分配運算符(?? =)?Apr 10, 2025 am 09:33 AM

JavaScript中處理空值可以使用NullCoalescingOperator(??)和NullCoalescingAssignmentOperator(??=)。 1.??返回第一個非null或非undefined的操作數。 2.??=將變量賦值為右操作數的值,但前提是該變量為null或undefined。這些操作符簡化了代碼邏輯,提高了可讀性和性能。

什麼是內容安全策略(CSP)標頭,為什麼重要?什麼是內容安全策略(CSP)標頭,為什麼重要?Apr 09, 2025 am 12:10 AM

CSP重要因為它能防範XSS攻擊和限制資源加載,提升網站安全性。 1.CSP是HTTP響應頭的一部分,通過嚴格策略限制惡意行為。 2.基本用法是只允許從同源加載資源。 3.高級用法可設置更細粒度的策略,如允許特定域名加載腳本和样式。 4.使用Content-Security-Policy-Report-Only頭部可調試和優化CSP策略。

什麼是HTTP請求方法(獲取,發布,放置,刪除等),何時應該使用?什麼是HTTP請求方法(獲取,發布,放置,刪除等),何時應該使用?Apr 09, 2025 am 12:09 AM

HTTP請求方法包括GET、POST、PUT和DELETE,分別用於獲取、提交、更新和刪除資源。 1.GET方法用於獲取資源,適用於讀取操作。 2.POST方法用於提交數據,常用於創建新資源。 3.PUT方法用於更新資源,適用於完整更新。 4.DELETE方法用於刪除資源,適用於刪除操作。

什麼是HTTP,為什麼對Web應用程序至關重要?什麼是HTTP,為什麼對Web應用程序至關重要?Apr 09, 2025 am 12:08 AM

HTTPS是一種在HTTP基礎上增加安全層的協議,主要通過加密數據保護用戶隱私和數據安全。其工作原理包括TLS握手、證書驗證和加密通信。實現HTTPS時需注意證書管理、性能影響和混合內容問題。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。