我正在尝试在PHP脚本中实现某种缓存,该脚本会出现在许多不同的客户端/站点上,这些客户端/站点将由相当非技术用户使用各种Web主机进行部署。由于用户的非技术性,我想避免要求他们调整文件权限。缓存需要跨会话,因此使用会话变量。如果我在ASP中编写这个,我会使用应用程序变量,但它们不存在于PHP中(据我所知)
有没有人对如何做到这一点有任何建议?
以下是我考虑的一些可能性,对这些的任何评论都会有用:
再一次,对这些想法或任何新想法的任何评论都将不胜感激。
更新:我尝试使用session_id()来使用共享会话状态,但它不起作用。每个会话都维护着自己的“GlobalCache”,任何想法为什么?:
// This code doesn't work, but the similar code in my answer does!
function test() {
if (!$_SESSION['session_count']) $_SESSION['session_count'] = 0;
$_SESSION['session_count']++;
$count = get_cache( 'count' );
print "pre application count: $count<br>";
if ( !$count )
$count = 0;
$count++;
print "session_id: " . session_id() . "<br>";
print "post application count: $count<br>";
print "session_count: " . $_SESSION['session_count'] . "<br>";
set_cache('count', $count);
}
function set_cache( $name, $value ) {
$old_session = session_id();
print "old_session (set): $old_session<br>";
session_id("GlobalCache");
print "new_session (set): " . session_id() . "<br>";
$_SESSION[$name] = $value;
session_id( $old_session );
}
function get_cache( $name ) {
$old_session = session_id();
print "old_session (get): $old_session<br>";
session_id("GlobalCache");
print "new_session (get): " . session_id() . "<br>";
$value = $_SESSION[$name];
session_id( $old_session );
return $value;
}
session_start();
test();
更新:有些人建议使用memcached,这对某些人来说实际上是一个很好的解决方案,但由于我无法控制终端服务器环境,因此不能选择。我们的想法是创建一个脚本,人们可以通过FTP直接创建一个开箱即用的共享主机帐户。
更新:有人建议用脚本创建我自己的缓存文件夹,但是我不需要在已经具有写权限的文件夹中创建这样的文件夹吗?
更新,解决方案:我最终弄清楚我的全局会话脚本中的问题,并发布了我自己的答案。感谢大家的帮助。
答案 0 :(得分:2)
好的,我想通过使用共享/全局会话状态模拟ASP样式的应用程序变量来解决这个问题。我在相关更新中的非工作代码进行了两项重要更改:
要切换会话状态,我们必须结束当前会话,切换到新会话,然后启动它。我已将此过程封装在switch_session()
由于我们正在切换会话ID,我们必须使用ob_start()/ ob_end_flush()来缓冲页面的输出,以便不会过早发送会话cookie。
完整的工作代码如下(清理过来!)。这可以通过在IE和Firefox窗口中加载页面轻松测试,并重新加载几次以观察计数器上升:
<?php
function test() {
// Do a regular session count
print "session_id: " . session_id() . "<br>";
if (!$_SESSION['session_count']) $_SESSION['session_count'] = 0;
$_SESSION['session_count']++;
print "session count: " . $_SESSION['session_count'] . "<br>";
// Do an application count
$count = get_cache( 'count' );
if ( !$count ) $count = 0;
$count++;
print "application count: $count<br>";
set_cache('count', $count);
}
function set_cache( $name, $value ) {
$old_session = switch_session("GlobalCache");
$_SESSION[$name] = $value;
switch_session( $old_session );
}
function get_cache( $name ) {
$old_session = switch_session("GlobalCache");
$value = $_SESSION[$name];
switch_session( $old_session );
return $value;
}
function switch_session( $session_id ) {
// switch the session and return the original
$old_id = session_id();
session_write_close();
session_id($session_id);
session_start();
return $old_id;
}
ob_start();
session_start();
test();
ob_end_flush();
?>
答案 1 :(得分:1)
您可以使用具有固定会话密钥的会话。
http://de.php.net/manual/en/function.session-id.php:
session_id([id])用于获取或设置当前会话的会话
id
。 如果指定了id,它将替换当前的会话ID。为此,需要在session_start()之前调用session_id()。
答案 2 :(得分:1)
在应用程序的目录中使用您自己的缓存目录。因此,您不必为各种服务器和/或PHP设置而烦恼,并获得最佳的可移植性。
答案 3 :(得分:0)
我投票支持“在我控制的服务器上缓存数据,并让客户端在每次点击时从那里下载新数据。”
所有其他路径都会导致某些疯狂。
答案 4 :(得分:0)
查看memcached for php-它的效果非常好。
答案 5 :(得分:0)
我使用作者更新的函数作为缓存简单数据库查询结果的方法,因为我期待高负载。我还存储了一个时间戳,以便我可以定义页面更新数据库结果的频率,而不仅仅是获取缓存的值。
我可以告诉你,这个缓存函数的性能比在每次请求时直接访问数据库要糟糕得多。我实际上杀了服务器。一旦我切换回简单查询数据库,服务器就全速运行,甚至没有注意到相当大的负载。