在 PHP 命令行中访问会话?
Accessing session in PHP command line?
我了解到命令行不是网络服务器,因此您无法访问$_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" );
我乐于接受各种建议,例如 websocket 的替代方案。我正在为我的网站创建实时聊天。
当然,第一个选择是 AJAX 请求。 AJAX 不存在无法快速轻松地访问 WebSockets 所具有的 session 的问题。任何足够频繁的采样率都与实时无法区分。
现在,关于我在 WebSockets 中实现的 long-winded 解决方案:
HTTP headers 在握手期间可用于 WebSocket 服务器,包括 cookie。在您使用的服务器 PHP-Websockets 中,headers 存储在 $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']
的值为分号和space(;
)分隔的collection键值对,其中值为URL 编码并用等号与其密钥分开。 (PHP 如果您在 cookie 名称中放置保留字符,则会抱怨。因此 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"
}
我们现在有了 session ID。仔细检查 session_name()
,这将为您提供实际持有 session ID 的 cookie 的密钥。
我们可以序列化和反序列化存储在服务器中的 session 文件,session_save_path()
指向该文件...但我想作弊。
因为built-insession系统锁定了session文件,我们不能一直保持session文件打开并不断观察变化,我们也不能自己长时间锁定文件。
如果我们可以像使用 $_SESSION
超全局(例如 $myUser->_session['key'] = 'value';
), 但 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!
}
}
(注意:我也将我的 feature request 指向这个问题,以我最终实现的 cookie 解析和 session 处理为基础,这样我就可以记住今晚的研究,因为我工作。)
我了解到命令行不是网络服务器,因此您无法访问$_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" );
我乐于接受各种建议,例如 websocket 的替代方案。我正在为我的网站创建实时聊天。
当然,第一个选择是 AJAX 请求。 AJAX 不存在无法快速轻松地访问 WebSockets 所具有的 session 的问题。任何足够频繁的采样率都与实时无法区分。
现在,关于我在 WebSockets 中实现的 long-winded 解决方案:
HTTP headers 在握手期间可用于 WebSocket 服务器,包括 cookie。在您使用的服务器 PHP-Websockets 中,headers 存储在 $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']
的值为分号和space(;
)分隔的collection键值对,其中值为URL 编码并用等号与其密钥分开。 (PHP 如果您在 cookie 名称中放置保留字符,则会抱怨。因此 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"
}
我们现在有了 session ID。仔细检查 session_name()
,这将为您提供实际持有 session ID 的 cookie 的密钥。
我们可以序列化和反序列化存储在服务器中的 session 文件,session_save_path()
指向该文件...但我想作弊。
因为built-insession系统锁定了session文件,我们不能一直保持session文件打开并不断观察变化,我们也不能自己长时间锁定文件。
如果我们可以像使用 $_SESSION
超全局(例如 $myUser->_session['key'] = 'value';
), 但 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!
}
}
(注意:我也将我的 feature request 指向这个问题,以我最终实现的 cookie 解析和 session 处理为基础,这样我就可以记住今晚的研究,因为我工作。)