在写小程序时用的是自己新写的框架,为了不重复性请求用户信息所以将数据存到了session中(当然也可以redis)。
但是,在调试小程序时却始终获取不到session数据,因为是新框架、新环境,所以第一时间怀疑是环境问题。
耐心调试开始解决问题:
1.代码已经开启了session。
session_start();
2.查看phpinfo()中是否含有session模块。
3.检查session在配置文件、phpinfo中是否开启(php中默认是不会开启session的)
session.auto_start=0;//没开启
//phpinfo中模块为off
注意,如果配置文件中session.auto_start=1,同时代码中也执行了session_start时,这样会造成session_id不一致,后果就是获取不到想要的session值!!!。
4.vim修改session.auto_stat = 1后再查看php.ini,session.auto_start为on,开启完毕
注意,这样设置代码中就不需要执行session_start(),因为后台配置已经自动开启了,所以代码已经开启的前提下,这里再开启会重新生成id,除非你代码开启前有输出。
5.重启php-fpm,测试,还是没有数据。
6.检查缓存文件夹。注意,有的时候因为路径问题查看php.ini的路径配置不一定正确哦。所以,直接查看phpinfo中save_path是否有设置缓存文件。
结果,有设置。
7.再在代码中打印session_id();,并将要保存的session数据保存后立即打印到日志中,然后到上述session路径文件夹下执行ls | grep sess_'session_id'查找,有返回,vim打开,其中的值为刚刚保存的,这说明session是ok的,权限也正常,问题应该出现在获取的时候。
8.为了证明怀疑正确,不使用新框架,另起demo测试,结果证明是对的。
解决:
突然想起小程序是没有帮忙保存session,查看日志比较后发现果然session_id是不一致的,也就是说每次请求都被服务器认为是一个新的请求,当然就找不到之前的数据了。
我们可以将之前请求的session_id返回到小程序中,并在小程序缓存下来并放到header中,然后再每次请求接口时都带上去就可以了
var request = (api,params) => new Promise((resolve, reject) => { console.log(params) var headers; /*提交时自动上传header信息*/ headers = { 'content-type': 'application/x-www-form-urlencoded', 'cookie':wx.getStorageSync("session_id")//读取cookie }; wx.request({ url: baseUrl + api, data: params, header: headers,//传在请求的header里 success: (res) => { console.log("api res "); console.log(res); resolve(res.data); }, fail: err => { console.log("api err "); console.log(err); reject(err); } }) })
服务端重新赋予session_id即可。
最后附上session的运行机制:
Session机制是一种服务器端的机制,他将数据保存在服务器端。
当程序需要为某个客户端的请求创建一个Session的时候,服务器首先检查这个客户端的请求里是否已包含一个Session标识,称为sessionid,如果已包含一个sessionid则说明以前以为此用户创建过session,服务器就按照sessionid把这个session检索出来使用即可;否则不包含sessionid,为此客户端创建一个session并且生成一个与此session相关联的的sessionid,sessionid的值应该是一个既不会重复,又不容易被找到规律以仿照的字符串,这个sessionid将被在本次响应中返回给客户端以cookie形式保存。