2015-07-20 77 views
1

我知道命令行不是web服務器,所以你不能訪問$_SESSION。但我不知道還有什麼要做。在PHP命令行中訪問會話?

我一直在關注這個教程創建使用的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的替代方案。我正在爲我的網站創建實時聊天。

+1

在握手期間,HTTP頭文件(包括cookie)可供WS服務器使用。在那個特定的服務器中,頭文件在屬性'$ headers'下的用戶類中作爲數組實現。稍後我會添加一個完整的答案(並添加一個功能請求來解析cookie),但這應該有助於您朝着正確的方向前進。 – Ghedipunk

回答

1

當然,第一種選擇是AJAX請求。 AJAX不存在無法快速輕鬆訪問WebSockets所具有的會話的問題。任何足夠頻繁的採樣率與實時無法區分。現在

,我在WebSockets的實施而冗長的解決方案:

HTTP頭握手期間可用於WebSocket的服務器,包括餅乾。在您使用的服務器中,PHP-Websockets的標題存儲在$headers屬性中。

例如:從

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

因此產生

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,的$user->headers['cookie']值是分號和空間(;)分隔的關鍵值對,其中的值的集合是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;[email protected]#$%" 
    ["MyNonhttponlyCookie"]=> 
    string(8) "My Value" 
} 

我們現在有會話ID。仔細檢查session_name(),它會給你實際上保存會話ID的cookie的關鍵字。

我們可以序列化和反序列化存儲在服務器中的會話文件,指向session_save_path() ......但我想作弊。

由於內置會話系統會鎖定會話文件,因此我們不能只保留會話文件並持續監視更改,也不能長時間鎖定文件。

這將是理想的,如果我們能在這裏使用的__get()__set()魔術方法以同樣的方式,我們會使用超全局$_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解析和會話處理這裏,讓我能記得我的研究,今晚我的工作)

+0

嗨,謝謝你的幫助!我真的不知道如何實現和使用MyUser類。你能幫我嗎? – kopa

+0

在您的FancyWebSocket類中,您需要將受保護的屬性'$ userClass'指定爲新用戶類的名稱。除此之外,它是基本的OOP。 – Ghedipunk

+0

抱歉,我沒有關注你。我沒有'FancyWebSocket'類,我有一個'PHPWebSocket'類。在我的任何文件中都沒有叫'$ userClass'? – kopa