简体   繁体   English

PHP缓存而不会弄乱文件权限(另外,如何在PHP中模拟ASP应用程序变量)

[英]PHP Caching without messing with file permissions (Also, How to emulate ASP Application variables in PHP)

I'm trying to implement some kind of caching in a PHP script that will go out to many different clients/sites, which will be deployed by fairly non-technical users, using a variety of web hosts. 我正在尝试在PHP脚本中实现某种缓存,这些缓存将发送到许多不同的客户端/站点,这些客户端/站点将由相当非技术的用户使用各种Web主机进行部署。 Due to the non-technical nature of the users, I'd like to avoid asking them to tweak file permissions. 由于用户的非技术性,我想避免要求他们调整文件权限。 The caching needs to be across sessions, so using session variables is out. 缓存需要跨会话,因此使用会话变量。 If I was coding this in ASP I'd use application variables, but they don't exist in PHP (to my knowledge) 如果我在ASP中编写这个,我会使用应用程序变量,但它们不存在于PHP中(据我所知)

Does anyone have any suggestions on how to accomplish this? 有没有人对如何做到这一点有任何建议?

Here are some possibilities I've considered, any comments on these would be useful: 以下是我考虑过的一些可能性,对这些的任何评论都会有用:

  • Caching via files in system temp folders - I could use sys_get_temp_dir() (or some home rolled similar function on PHP4) to help find such a folder. 通过系统临时文件夹中的文件进行缓存 - 我可以使用sys_get_temp_dir()(或PHP4上的一些家庭滚动类似功能)来帮助找到这样的文件夹。 The disadvantage here, is it probably wouldn't work on hosts using the openbase_dir restriction 这里的缺点是它可能不适用于使用openbase_dir限制的主机
  • Some website I looked at mentioned tricking PHP into making all user sessions share the same session state thereby forcing session variables to act like session variables. 我看到的一些网站提到欺骗PHP使所有用户会话共享相同的会话状态,从而迫使会话变量像会话变量一样工作。 Of course I can't find that post now... This seems scary anyway. 当然我现在找不到那个帖子......无论如何这似乎很可怕。 (I'll update this question with the link to this post once I find it again) (一旦我再次找到,我会用这个帖子的链接更新这个问题)
  • Use a third party data store like Amazon's Simple Storage Service - seems like overkill 使用像亚马逊的简单存储服务这样的第三方数据存储 - 看起来有点过分
  • Cache the data on a server I control, and have the client download new data from there on each hit. 在我控制的服务器上缓存数据,让客户端在每次点击时从那里下载新数据。

Once again, any comments on these ideas or any new ones would be appreciated. 再次,对这些想法或任何新想法的任何评论将不胜感激。

UPDATE: I tried using session_id() to use a shared session state, but it doesn't work. 更新:我尝试使用session_id()来使用共享会话状态,但它不起作用。 Each session is maintaining its own "GlobalCache", any ideas why?: 每个会话都维护自己的“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();

UPDATE: some have suggested using memcached, which is in fact a great solution for some, but since I don't have control over the end server environment it isn't an option. 更新:一些人建议使用memcached,这对某些人来说实际上是一个很好的解决方案,但由于我无法控制终端服务器环境,因此不能选择。 The idea is to have a script that people can just FTP up to a shared hosting account that just works out of the box. 我们的想法是创建一个脚本,人们可以将FTP直接发送到一个开箱即用的共享主机帐户。

UPDATE: someone suggested creating my own cache folder with the script, but wouldn't I need to create such a folder inside a folder that already had write permissions? 更新:有人建议用脚本创建我自己的缓存文件夹,但是我不需要在已经具有写权限的文件夹中创建这样的文件夹吗?

UPDATE, SOLUTION FOUND: I ended up figuring out the problems in my global session script and have posted my own answer to that effect. 更新,解决方案:我最终找出了我的全局会话脚本中的问题,并发布了我自己的答案。 Thanks for the help everyone. 感谢大家的帮助。

Okay, I figured out how to do this by emulating ASP-style application variables using a shared/global session state. 好吧,我想通过使用共享/全局会话状态模拟ASP样式的应用程序变量来解决这个问题。 Two key changes from my non-working code in the relevant update: 我在相关更新中的非工作代码的两个主要更改:

  1. To switch session state, we must end the current session, switch to the new one, then start it. 要切换会话状态,我们必须结束当前会话,切换到新会话,然后启动它。 I've encapsulated this process in switch_session() 我在switch_session()中封装了这个过程

  2. Since we are switching session ids around we have to buffer the page's output using ob_start()/ob_end_flush() so that the session cookie isn't sent too soon. 由于我们正在切换会话ID,因此我们必须使用ob_start()/ ob_end_flush()缓冲页面的输出,以便不会过早发送会话cookie。

The full working code follows (cleaned up too!). 完整的工作代码如下(清理过来!)。 This can be easily tested by loading the page in an IE and a Firefox window, and reloading each several times to watch the counters rise: 这可以通过在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();
?>

You could use sessions with a fixed session key. 您可以使用具有固定会话密钥的会话。

http://de.php.net/manual/en/function.session-id.php : http://de.php.net/manual/en/function.session-id.php

session_id([id]) is used to get or set the session id for the current session. session_id([id])用于获取或设置当前会话的会话id If id is specified, it will replace the current session id. 如果指定了id,它将替换当前的会话ID。 session_id() needs to be called before session_start() for that purpose. 为此,需要在session_start()之前调用session_id()。

Use your own cache dir in your application's dir. 在应用程序的目录中使用自己的缓存目录。 Therewith you don't have to struggle with various server and/or PHP settings and get the best portability. 因此,您不必为各种服务器和/或PHP设置而烦恼,并获得最佳的可移植性。

I used the updated function by the author as a way to cache a simple database query result since I was expecting high load. 我使用作者更新的函数作为缓存简单数据库查询结果的方法,因为我期待高负载。 I also stored a timestamp so that I could define how often the page would renew the database result rather than just taking the cached value. 我还存储了一个时间戳,以便我可以定义页面更新数据库结果的频率,而不仅仅是获取缓存的值。

I can tell you that this cache function had much much much worse performance than going straight for the database at each request. 我可以告诉你,这个缓存函数的性能比在每次请求时直接访问数据库要糟糕得多。 I actually killed the server. 我实际上杀了服务器。 Once I switched back to simply querying the database the server got up to full speed and the pretty big load was not even noticed. 一旦我切换回简单查询数据库,服务器就全速运行,甚至没有注意到相当大的负载。

I vote for "Cache the data on a server I control, and have the client download new data from there on each hit." 我投票支持“在我控制的服务器上缓存数据,让客户端在每次点击时从那里下载新数据”。

All other paths lead to certain madness. 所有其他路径都会导致某种疯狂。

Check out memcached for php- it works really well. 查看memcached for php-它的效果非常好。

http://www.php.net/memcache http://www.php.net/memcache

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM