Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP、NodeJ和会话_Php_Node.js_Sockets_Session_Keep Alive - Fatal编程技术网

PHP、NodeJ和会话

PHP、NodeJ和会话,php,node.js,sockets,session,keep-alive,Php,Node.js,Sockets,Session,Keep Alive,我有一个提供php文件的经典apache服务器,还有一个用于php网站上实时事件管理的nodeJS服务器(带有socket.io,但不是whithout express/connect)。有时我需要对连接到nodeJS服务器的客户端进行身份验证,但当用户重新加载页面时,这种身份验证将丢失,因为它也会重新加载socket.io客户端(我将套接字ID存储在服务器上,每次刷新时都会丢失) 问题是:在socket.io中有没有保持连接活动的方法,或者有没有链接ApachePHP会话和nodeJS服务器的

我有一个提供php文件的经典apache服务器,还有一个用于php网站上实时事件管理的nodeJS服务器(带有socket.io,但不是whithout express/connect)。有时我需要对连接到nodeJS服务器的客户端进行身份验证,但当用户重新加载页面时,这种身份验证将丢失,因为它也会重新加载socket.io客户端(我将套接字ID存储在服务器上,每次刷新时都会丢失)
问题是:在socket.io中有没有保持连接活动的方法,或者有没有链接ApachePHP会话和nodeJS服务器的方法?或者是一种使用cookies(知道我必须存储敏感数据,如用户密码和密钥)保持身份验证的方法?

您可以使用。Memcached是一个简单的键值存储,可以通过TCP访问;有一个问题

PHP使用会话id作为键将会话存储在memcached中。存储在memcached中的会话数据(值)是一个序列化的PHP对象,稍微有点扭曲。您可以在上阅读有关此不寻常序列化的更多信息。幸运的是,已经有了一个NPM模块:


现在来看看怎么做

假设

  • memcached可在127.0.0.1:11211访问
  • php.ini(或php.d/memcache.ini)配置为:
    session.save\u handler='memcached'
    session.save\u path='1!'tcp://127.0.0.1:11211“
  • 您已经安装了所需的NPM模块(2):
    NPM install memcached php unserialize
  • 你对CLI没问题
准备

首先,为了获得一些测试数据,保存以下php脚本(
s.php
):

好的,现在我们知道了会话id(
74ibpvem1no6ssros60om3mlo5
),并确认会话数据已设置。要确认它在memcached中,您可以运行
memcached tool 127.0.0.1:11211 dump
,它提供已知键:值对的转储,例如,我的测试台上有两个:

Dumping memcache contents
  Number of buckets: 1
  Number of items  : 3
Dumping bucket 2 - 3 total items
add 74ibpvem1no6ssros60om3mlo5 0 1403169638 17
some|s:5:"thing";
add 01kims55ut0ukcko87ufh9dpv5 0 1403168854 17
some|s:5:"thing";
到目前为止,我们已经1)在php中创建了会话id,2)在memcached中存储了来自php的会话数据,3)通过CLI确认数据存在

使用Node.js检索

这部分其实很简单。NPM模块已经完成了大部分起重工作。我编写了一个通过CLI运行的Node.js脚本,但您可以看到:

var Memcached = require('memcached');
var PHPUnserialize = require('php-unserialize');

var mem = new Memcached('127.0.0.1:11211'); // connect to local memcached
var key = process.argv[2]; // get from CLI arg

console.log('fetching data with key:',key);
mem.get(key,function(err,data) { // fetch by key
        if ( err ) return console.error(err); // if there was an error
        if ( data === false ) return console.error('could not retrieve data'); // data is boolean false when the key does not exist
        console.log('raw data:',data); // show raw data
        var o = PHPUnserialize.unserializeSession(data); // decode session data
        console.log('parsed obj:',o); // show unserialized object
});
假设上述内容保存为
m.js
,则可以使用
节点m.js 74ibpvem1no6ssros60om3mlo5
运行,该节点将输出如下内容:

fetching data with key: 74ibpvem1no6ssros60om3mlo5
raw data: some|s:5:"thing";
parsed obj: { some: 'thing' }
警告/陷阱


我的一个PHP应用程序将一些二进制数据存储在会话值中(即加密),但密钥和正常会话对象保持不变(如上面的示例所示)。在这种情况下,
memcached tool dump
将格式错误的序列化会话字符串打印到stdout;我想这可能是孤立于stdout的,但我错了在使用
PHPUnserialize.unserializeSession
时,解析数据时也遇到问题
(由
|
分隔)。我在网上尝试了其他一些会话反序列化方法,但没有成功。我假设memcached在内部维护正确的数据,因为它与本机PHP会话保存处理程序一起工作,所以在撰写本文时,我不太确定是反序列化方法还是memcached NPM模块没有正确检索/解释数据。当坚持使用非二进制数据(如ascii或utf-8)时,它应该按预期工作。

我认为此链接将对您有所帮助

< p>如果您的项目在数据库中存储会话-一些DO,那么您可以考虑使用数据库作为传输介质。
如果对您的特定案例的分析显示有希望,那么可以使用节点mysql(或类似的),请参见:

虽然线程很旧,但我想推荐我在项目中使用的线程。 除了memcached,您还可以使用Redis进行会话处理。 我使用的是php redis客户端。您可以在redis中保存会话,而不是将会话存储到文件中。大部分重物将由阿帕奇完成。对于每个请求,apache都会将会话值附加到cookie中,并从每个请求中读取会话值并进行验证

将php会话保存到redis所需的设置也非常简单

session.save_handler=redis session.save_路径=”tcp://host1:6379?weight=1, tcp://host2:6379?weight=2&timeout=2.5, tcp://host3:6379?weight=2"

就是这样。这将使php将会话保存到redis而不是文件。这也会将存储在文件中的会话移动到redis。

的答案帮助我完成身份验证,这是我已经采取的方法。谢谢你

我发布的原因是在使用时出于某种原因:

var PHPUnserialize = require('php-unserialize');
不断地给我错误

SyntaxError: String length mismatch
我不知道为什么?我写了一个函数,为我做这项工作,并希望分享,以防它可能会帮助其他人

function Unserialize(data){

  var result = {};

  if(data !== undefined){

    var preg = data.replace(/(^|s:[0-9]+:)|(^|i:)|(^|b:)|(")|(;$)/g,'').split(';'); 

    var a = [];
    preg.forEach(function(value){
      a.push(value.split('|'));
    });

    var b = [];
    a.forEach(function(value){
      if(Array.isArray(value)){
        Array.prototype.push.apply(b, value);
      }else{
        b.push(value);  
      }
    });

    var arr_A = [];
    var arr_B = [];
    b.forEach(function(value, k){
      if(k % 2 == 0){
        arr_A.push(value);
      }else{
        arr_B.push(value);
      }     
     });


     if (arr_A == null) return {};

     for (var i = 0, l = arr_A.length; i < l; i++) {
       if (arr_B) {
        result[arr_A[i]] = arr_B[i];
       } else {
        result[arr_A[i][0]] = arr_A[i][1];
       }
     }

  }

  return result;

}

您应该能够很容易地修改正则表达式以满足您的需要

在PHP中使用memcached作为会话存储处理程序,然后使用-现在您所需要的只是会话标识符。这似乎是可行的,但是PHP如何在memcached中存储会话呢?密钥是会话id,值是$\u会话变量的JSON编码字符串还是…?您可以维护一个包含登录用户的单独数组。使用套接字ID不是解决方案,因为刷新时,套接字会断开连接。如果用户注销,则会触发一个事件,从该数组中删除userdata。但要注意用户在未注销的情况下关闭浏览器的情况。您的数组可能会变得太大,包含冗余数据OK,所以我现在的位置是:在设置memcached之后,我通过PHPSESSID cookie(在socket.io授权中)获得了PHP会话ID。但是我无法保存这个php会话ID(将其保存在handshake.session\u ID中不起作用,我无法获取我的
SyntaxError: String length mismatch
function Unserialize(data){

  var result = {};

  if(data !== undefined){

    var preg = data.replace(/(^|s:[0-9]+:)|(^|i:)|(^|b:)|(")|(;$)/g,'').split(';'); 

    var a = [];
    preg.forEach(function(value){
      a.push(value.split('|'));
    });

    var b = [];
    a.forEach(function(value){
      if(Array.isArray(value)){
        Array.prototype.push.apply(b, value);
      }else{
        b.push(value);  
      }
    });

    var arr_A = [];
    var arr_B = [];
    b.forEach(function(value, k){
      if(k % 2 == 0){
        arr_A.push(value);
      }else{
        arr_B.push(value);
      }     
     });


     if (arr_A == null) return {};

     for (var i = 0, l = arr_A.length; i < l; i++) {
       if (arr_B) {
        result[arr_A[i]] = arr_B[i];
       } else {
        result[arr_A[i][0]] = arr_A[i][1];
       }
     }

  }

  return result;

}
var PHPUnserialize = Unserialize;

memcached.get(key, function(err, data){
   var memData = PHPUnserialize(data);
   console.log(memData.is_logged_in);
});