Workman无法获取MVC框架Session数据解决方法

最近在做一个自己家用的物联网项目,其中服务器端采用thinkphp5和workman搭建的后台,开发过程中发现workman获取不到thinkphp的Session数据。经过研究最终找到了一个思路,现在波波将相关思路分享如下。

其实仔细阅读Workman文档会发现Workman运行在CLI模式下,其Session用法与thinkPHP的会话方式有很大的区别,所以这里波波引用了一个Session共享的方法。如下图所示:

Workman无法获取MVC框架Session数据解决方法

这个方法就是我们把MVC的Session数据保存在Redis中,Workman需要读取MVC框架Session的时候可以直接读取Redis数据,这个过程中需要PHP开启Redis扩展,不仅运行与CGI模式下的需要开启,运行于CLI模式下的PHP同样需要开启(主要防止多版本共存情况出现错误)。

原理就是Session共享的思路,很简单。下面波波分享一下波波为Workman写的Redis数据驱动。与workman一起运行于CLI模式下。

  1. <?php
  2. /**
  3.  * Created by bobo.
  4.  * DateTime: 2019/11/16 13:40
  5.  * Function:Workman MVC session验证器
  6.  */
  7. namespace app\pigeon\model;
  8. class EventsModel{
  9.     //Redis配置
  10.     protected $options = [
  11.         'host'       => '127.0.0.1',
  12.         'port'       => 6379,
  13.         'password'   => '',
  14.         'select'     => 0,
  15.         'timeout'    => 0,
  16.         'expire'     => 0,
  17.         'persistent' => false,
  18.         'prefix'     => '',
  19.     ];
  20.     //构造函数
  21.     public function __construct($options = []){
  22.         if (!extension_loaded('redis')) {
  23.             throw new \Exception('not support: redis');
  24.         }
  25.         if (!emptyempty($options)) {
  26.             $this->options = array_merge($this->options, $options);
  27.         }
  28.         $func          = $this->options['persistent'] ? 'pconnect' : 'connect';
  29.         $this->handler = new \Redis;
  30.         $this->handler->$func($this->options['host'], $this->options['port'], $this->options['timeout']);
  31.         if ('' != $this->options['password']) {
  32.             $this->handler->auth($this->options['password']);
  33.         }
  34.         if (0 != $this->options['select']) {
  35.             $this->handler->select($this->options['select']);
  36.         }
  37.     }
  38.     protected function getCacheKey($name){
  39.         return $this->options['prefix'] . $name;
  40.     }
  41.     public function has($name)
  42.     {
  43.         return $this->handler->get($this->getCacheKey($name)) ? true : false;
  44.     }
  45.     //设置标签
  46.     protected function setTagItem($name)
  47.     {
  48.         if ($this->tag) {
  49.             $key       = 'tag_' . md5($this->tag);
  50.             $this->tag = null;
  51.             if ($this->has($key)) {
  52.                 $value   = explode(',', $this->get($key));
  53.                 $value[] = $name;
  54.                 $value   = implode(',', array_unique($value));
  55.             } else {
  56.                 $value = $name;
  57.             }
  58.             $this->set($key$value, 0);
  59.         }
  60.     }
  61.     //查询Redis数据
  62.     public function get($name$default = false){
  63.         $value = $this->handler->get($this->getCacheKey($name));
  64.         if (is_null($value)) {
  65.             return $default;
  66.         }
  67.         $jsonData = json_decode($value, true);
  68.         // 检测是否为JSON数据 true 返回JSON解析数组, false返回源数据
  69.         return (null === $jsonData) ? $value : $jsonData;
  70.     }
  71.     //写入Redis数据
  72.     public function set($name$value$expire = null)
  73.     {
  74.         if (is_null($expire)) {
  75.             $expire = $this->options['expire'];
  76.         }
  77.         if ($expire instanceof \DateTime) {
  78.             $expire = $expire->getTimestamp() - time();
  79.         }
  80.         if ($this->tag && !$this->has($name)) {
  81.             $first = true;
  82.         }
  83.         $key = $this->getCacheKey($name);
  84.         //对数组/对象数据进行缓存处理,保证数据完整性
  85.         $value = (is_object($value) || is_array($value)) ? json_encode($value) : $value;
  86.         if (is_int($expire) && $expire) {
  87.             $result = $this->handler->setex($key$expire$value);
  88.         } else {
  89.             $result = $this->handler->set($key$value);
  90.         }
  91.         isset($first) && $this->setTagItem($key);
  92.         return $result;
  93.     }
  94. }

因为我在写这部分代码的时候结合MVC写到了model层,大家可以自己重新定义命名空间。到此彻底解决了workman无法获取Session数据的问题了。

总结:

其实关于用户信息的验证有很多种方法,为什么我一直纠结必须用Session呢?因为对于MVC框架来说,用户的Session意味着用户在线的活跃状态,随着用户关闭页面而终止(其实有过期时间),这在最大程度上可以保障用户信息的安全性和有效性。那么做为一个后端开发的人来讲,我们必须要力求逻辑的严谨性,虽然失误总是不可避免,BUG总会出现,但是只有力求完美才能给客户、给自己开发出稳定、安全的系统。

 

你想把广告放到这里吗?

发表评论

您必须 登录 才能发表留言!