在PHP命令行中访问会话


Accessing session in PHP command line?

我知道命令行不是web服务器,所以你不能访问$_SESSION。但我不知道还能做什么。

我一直在遵循这个教程,使用websockets创建一个聊天:http://www.phpbuilder.com/articles/application-architecture/optimization/creating-real-time-applications-with-php-and-websockets.html

我的问题是,我不知道如何安全地获得消息发送者的用户名。我可以将其包含在消息发送函数中,但由于它是在Javascript中,每个人都可以将自己的用户名编辑为其他人。

我如何安全地获得用户的用户名,即$_SESSION['username'] ?

var Server;
Server = new FancyWebSocket('ws://0.0.0.0:9000');
send( "test" );

我愿意接受各种建议,比如websockets的替代方案。我正在为我的网站创建一个实时聊天。

第一种选择当然是AJAX请求。AJAX没有WebSockets所具有的不能快速方便地访问会话的问题。任何足够频繁的采样率都与实时无法区分。

现在,对于我在WebSockets中实现的相当冗长的解决方案:

WebSocket服务器在握手期间可以使用HTTP报头,包括cookie。在你正在使用的服务器,PHP-Websockets,头存储在$headers属性。

例如:

var_dump($user->headers);
array(14) {
  ["get"]=>
  string(8) "/echobot"
  ["host"]=>
  string(14) "127.0.0.1:9000"
  ...snip...
  ["cookie"]=>
   string(100) "PHPSESSID=jan9uknpc06mk4ddghph4870t1; MyCookie=My+Value%21%40%23%24%25; MyNonhttponlyCookie=My+Value"
}

这些cookie是从

生成的
session_start();
$_SESSION['Hi!'] = array('Hello!', 'where' => 'world!');
setcookie('MyCookie', 'My Value;!@#$%', 0, '/', '127.0.0.1', false, true);
setcookie('MyNonhttponlyCookie', 'My Value', 0, '/', '127.0.0.1', false, false);

因此,$user->headers['cookie']的值是一个以分号和空格(;)分隔的键值对集合,其中的值是URL编码的,并与它的键用等号分隔。如果在cookie名称中放入保留字符,PHP会报错。因此,cookie密钥不能包含任何url编码的值。)

快速提取这些文件的方法如下

$cookies = array();
$cookiesParts = explode('; ', $user->headers['cookie']);
foreach ($cookiesParts as $cookieParts) {
    $interimCookie = explode('=', $cookieParts);
    $cookies[$interimCookie[0]] = urldecode($interimCookie[1]);
}
var_dump($cookies);
array(3) {
  ["PHPSESSID"]=>
  string(26) "jan9uknpc06mk4ddghph4870t1"
  ["MyCookie"]=>
  string(14) "My Value;!@#$%"
  ["MyNonhttponlyCookie"]=>
  string(8) "My Value"
}

我们现在有了会话ID。再次检查session_name(),它将为您提供实际保存会话ID的cookie的密钥。

我们可以序列化和反序列化存储在服务器上的会话文件,这是由session_save_path()指向的…但我想作弊。

由于内置的会话系统锁定了会话文件,我们不能只是保持会话文件打开并不断观察变化,也不能长时间锁定文件。

如果我们能像使用$_SESSION超全局方法(如$myUser->_session['key'] = 'value';)一样使用__get()__set()魔术方法,那将是理想的,但是PHP不允许将这些方法作为数组处理。相反,我们必须设置一个更普通的命名方法。
<?php
class MyUser extends WebSocketUser {
    public $session_id; // gets set somewhere. Good place is probably is your implementation of the `connected($user)` abstract method.
    public getSession($key) {
        session_id($this->session_id);
        session_start();
        $val = $_SESSION[$key];
        session_write_close(); // very important!
        return $val;
    }
    public setSession($key, $value) {
        session_id($this->session_id);
        session_start();
        $_SESSION[$key] = value;
        session_write_close(); // still very important!
    }
}

(注意:我也针对这个问题提出了我的功能请求,以我在这里的cookie解析和会话处理的最终实现为基础,这样我就可以在工作时记住我今晚的研究。)