【问题标题】:php session sharing, in a desperate attempt to execute code in a different scopephp会话共享,拼命尝试在不同范围内执行代码
【发布时间】:2011-09-15 11:34:57
【问题描述】:

我想知道为什么这样的事情不起作用(实际上不起作用):

4.php :

<php
session_start();

$my_id = session_id();

$_SESSION['username'] = (($_SESSION['username'] == 'nimic') ? 's-a schimbat' : $_GET['test']);

file_put_contents('comm.g', PHP_EOL.$my_id, FILE_APPEND);

sleep(3); // can be left out

echo $_SESSION['username'];

?>

4.php 是一个简单的页面,它只设置 $_SESSION 的“用户名”组件,然后将会话 ID 写入文件,然后回显 $_SESSION['username'] 值。

然后:

3.php :

<php

while(true)
{
    if(file_exists("comm.g"))
    {
        $c = file("comm.g");
        unlink("comm.g");

        session_start();
        foreach($c as $k => $v)
        {
            if($v != '')
            {
                $my_id = session_id();
                session_write_close();
                session_id($v);
                session_start();
                file_put_contents("result.cc", $_SESSION['username'].'---'.$v.'END'.PHP_EOL.PHP_EOL, FILE_APPEND);
                $_SESSION['username'] = 'somethingelse';
                session_id($my_id);
                session_start();
            }
        }
        session_write_close();
    }
}
?>

3.php 由 cronjob 运行,每分钟运行大约 30 秒(直到服务器终止它)。无论如何,在result.cc 中,我发现(在这 30 秒内)预期的结果...... $_GET['test'] 的值。

但它并没有修改$_SESSION['username']的值,我什至没想到实际上会有这样的行为,我知道睡眠是不够的,但仍然,刷新不应该修改?...

我知道我的代码很糟糕,这只是一个测试,如果它有效,它会得到改进。

但我似乎没有弄清楚。我究竟做错了什么? 其实我做错了很多事情,系统本身不应该这样使用,我也知道,但是,现在这是我唯一的选择。我对这件事有更复杂的想法,但如果这行不通,其他的也行不通。

我的意图实际上是在单独的线程中执行代码,以便我可以逃避一些更改(例如为文件方案注册一个包装器,并且在需要时无法取消注册(恢复)它,在包装器类中是)我在那里做的。非正统的方法,我知道……

那么,您有什么想法可以帮忙吗?谢谢。

编辑 1

即使让我想到了一个有趣的想法@Ben 的回答并不准确......实际上在 cookie 中只保留了会话 ID,我通过使用文件替换了对 cookie 的需求,以便 cronjob 知道应该使用哪个会话进行修改,我得到了 $_SESSION['username'] 对于任何“注册”会话的正确值,但即便如此,我也无法修改该死的值,就像它们被标记为只读一样。现在,重新考虑,我发现这个想法仍然存在,是可行的,并且是一个解决方案。 所以我的问题仍然存在......为什么它不起作用?

【问题讨论】:

    标签: php session ipc cron-task


    【解决方案1】:

    这是你的问题:3.php is run by a cronjob

    会话需要 cookie,这需要 Web 浏览器和浏览器状态。如果您将脚本作为 cron 作业运行,则没有会话。

    您可能要考虑的实际问题的解决方案是 Runkit Sandbox:http://php.net/manual/en/runkit.sandbox.php

    【讨论】:

    • Runkit Sandbox 可能确实是一个解决方案,但不幸的是不是一个选项。所以我无法安装任何扩展。而在那些可用的之间,这不在其中。
    • @blind,啊,我现在明白了。 foreach() 上方的 session_start() 让我失望——那条线在 cron 的上下文中不应该做任何事情,所以我什至没有真正研究你的其余代码。此外,无需保存会话 ID 并在该循环中恢复它。 Cron 没有要存储的本地会话!也就是说,这可能失败的原因有很多,我建议删除所有不必要的代码,然后在更改值后添加“session_commit()”。不知道这是否会解决它,但这是一种可能性。我将用代码示例添加另一个答案
    • 是的,session_commit 与 session_write_close 相同,但我的意思是把它放在数据之后,而不是在你改回会话之前。您将在代码示例中看到我的意思。
    【解决方案2】:

    好的,这是3.php 的示例,删除了不必要的代码,并在数据分配后立即添加了“session_write_close()”。不知道它是否会起作用,但值得一试。此外,当文件不存在时,没有任何东西可以减慢它的 while(true) 循环将坐在那里并使用 100% 的 cpu(直到服务器杀死它),更不用说持续的文件系统访问了。真的,你应该在那里增加一个睡眠来抑制它。那么废话不多说:

    <?php
    
    while(true)
    {
        if(file_exists("comm.g"))
        {
            $c = file("comm.g");
            unlink("comm.g");
    
            foreach($c as $k => $v)
            {
                if($v != '')
                {
                    session_id($v);
                    session_start();
                    file_put_contents("result.cc", $_SESSION['username'].'---'.$v.'END'.PHP_EOL.PHP_EOL, FILE_APPEND);
                    $_SESSION['username'] = 'somethingelse';
                    session_write_close();
                }
            }
        }
        usleep(200000); // Sleep for 1/5 of a second, to avoid a 100% cpu hog and constant stream of file system accesses
    }
    
    ?>
    

    【讨论】:

    • 现在以一种奇怪的方式,它没有让我得到 result.cc 中 $_SESSION['username'] 的值...错误日志显示如下: [date time] PHP 警告: session_start() [function.session-start]:无法发送会话缓存限制器 - 标头已在第 15 行的 /***/3.php 中发送或 [日期时间] PHP 警告:session_start() [function.session-start]:无法发送会话 cookie - 标头已在 /***/3.php 中发送第 15 行
    • @blind,m 哦,我刚刚意识到您使用的是&lt;php,而不是&lt;?php。我在我的示例中修复了这个问题,但您也应该在代码中修复它。另外,请确保在打开&lt;?php之前没有空行(或任何其他输出)。
    • 我已经检查过了,在我留下评论之前我认为,否则我会返回编辑它......无论如何,我现在测试它,对4.php添加一个小修改,一个"echo" 看到 $_SESSION['username'] 之前它会被修改成 $_GET['test']... 但在 result.cc 中的输出仍然是:---9eb425a474c8c13d925edee9c1da2011 END 不幸的是,它就像用户会话已关闭...因为来自 comm.g 的会话 ID 无用
    猜你喜欢
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 2016-08-05
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    相关资源
    最近更新 更多