PHP 缓存而不弄乱文件权限(另外,如何在 PHP 中模拟 ASP 应用程序变量)
Posted
技术标签:
【中文标题】PHP 缓存而不弄乱文件权限(另外,如何在 PHP 中模拟 ASP 应用程序变量)【英文标题】:PHP Caching without messing with file permissions (Also, How to emulate ASP Application variables in PHP) 【发布时间】:2010-10-02 23:50:43 【问题描述】:我正在尝试在 php 脚本中实现某种缓存,该脚本将发送到许多不同的客户端/站点,这些缓存将由相当非技术用户使用各种 Web 主机进行部署。由于用户的非技术性质,我想避免要求他们调整文件权限。缓存需要跨会话,因此不使用会话变量。如果我在 ASP 中对此进行编码,我会使用应用程序变量,但它们在 PHP 中不存在(据我所知)
有人对如何实现这一点有任何建议吗?
以下是我考虑过的一些可能性,任何关于这些的 cmets 都会很有用:
通过系统临时文件夹中的文件缓存 - 我可以使用 sys_get_temp_dir()(或 PHP4 上的一些家庭滚动类似函数)来帮助找到这样的文件夹。这里的缺点是它可能无法在使用 openbase_dir 限制的主机上运行 我看过的一些网站提到欺骗 PHP 使所有用户会话共享相同的会话状态,从而迫使会话变量像会话变量一样工作。当然,我现在找不到那个帖子了……无论如何,这似乎很可怕。 (一旦我再次找到该帖子的链接,我将使用此帖子的链接更新此问题) 使用第三方数据存储,如 Amazon 的简单存储服务 - 似乎有点矫枉过正 在我控制的服务器上缓存数据,并让客户端在每次点击时从那里下载新数据。再一次,任何关于这些想法或任何新想法的 cmet 将不胜感激。
更新: 我尝试使用 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 上传到一个开箱即用的共享主机帐户。
更新: 有人建议使用脚本创建我自己的缓存文件夹,但我不需要在已经具有写入权限的文件夹中创建这样的文件夹吗?
更新,找到解决方案: 我最终找出了我的全局会话脚本中的问题,并为此发布了我自己的答案。谢谢大家的帮助。
【问题讨论】:
【参考方案1】:好的,我想出了如何通过使用共享/全局会话状态模拟 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();
?>
【讨论】:
【参考方案2】:您可以使用具有固定会话密钥的会话。
http://de.php.net/manual/en/function.session-id.php:
session_id([id]) 用于获取或设置当前会话的会话
id
。 如果指定了 id,它将替换当前会话 id。为此,需要在 session_start() 之前调用 session_id()。
【讨论】:
【参考方案3】:在应用程序的目录中使用您自己的缓存目录。因此,您不必为各种服务器和/或 PHP 设置而苦恼,并获得最佳的可移植性。
【讨论】:
并确保缓存子目录是PHP在第一次运行时创建的,所以它是目录的所有者,以后可以写入 …并保护它免受来自互联网的请求。【参考方案4】:我投票赞成“在我控制的服务器上缓存数据,并让客户端在每次点击时从那里下载新数据。”
所有其他路径都会导致某些疯狂。
【讨论】:
【参考方案5】:查看 memcached 的 php - 它工作得非常好。
http://www.php.net/memcache
【讨论】:
memcache 很酷,但这里不是一个选项,因为我无法控制部署脚本副本的服务器。【参考方案6】:我使用作者的更新函数作为缓存简单数据库查询结果的一种方式,因为我期待高负载。我还存储了一个时间戳,以便我可以定义页面更新数据库结果的频率,而不仅仅是获取缓存值。
我可以告诉你,这个缓存函数的性能比在每次请求时直接访问数据库要差得多。我实际上杀死了服务器。一旦我切换回简单地查询数据库,服务器就会全速运行,甚至没有注意到相当大的负载。
【讨论】:
以上是关于PHP 缓存而不弄乱文件权限(另外,如何在 PHP 中模拟 ASP 应用程序变量)的主要内容,如果未能解决你的问题,请参考以下文章
如何在不弄乱内容的情况下标记 dequeueReusableCell?