2016-06-18 5 views
1

PHP7にアップデートした後、私のアプリケーションのセッション処理に問題があります。カスタムsession_handlerがphp7(session_set_save_handler)で壊れた

大きな問題ではないようですが、PHPは、このエラー毎回スロー:

[18-Jun-2016 20:49:10 UTC] PHP Warning: session_decode(): Session is not active. You cannot decode session data in /var/www/app/phpsessionredis.php on line 90 

session_handlerは特別なものではありません。それはJSON化されたセッションデータをレディスなどに保存します。

class phpsessionredis implements \SessionHandlerInterface { 


    public function __construct(&$redis) { 

     $this->__rc = $redis; 

    } 

    public function open($savePath, $sessionName) { 
     return true; 
    } 

    public function destroy($id) { 
     try { $this->__rc->del($id); } 
     catch (\RedisException $e) { return false; } 
    } 

    public function close() { 
     return true; 
    } 
    public function write($id, $data) { 

     session_decode($data); // throws an error 

     try{ 

      $this->__rc->setex($id, 3600, json_encode($_SESSION)); 

     } catch (\RedisException $e) { return false; } 

     return true; 

    } 
    public function read($id) { 

     try { 

      $r = $this->__rc 
      ->multi() 
      ->get($id) 
      ->expire($id, 3600) 
      ->exec(); 

     } catch (\RedisException $e) { return false; } 

     $_SESSION = json_decode($r[0], true); 


     if(isset($_SESSION) && ! empty($_SESSION) && $_SESSION != null){ 

      return session_encode(); 

     } 

     return ''; 

    } 


    public function gc($maxLifetime) { 
     return true; 
    } 


} 


$sessionhandler = new phpsessionredis($redis); 
session_set_save_handler($sessionhandler); 
ob_start(); 
session_start(); 

助けを歓迎します。

答えて

1

PHP7にアップデートするときに同じ問題が発生しました。

session_decode()がアクティブなセッションを必要とするため警告が表示され、$ _SESSIONが設定されます。 これは不要です。データをシリアル化して、Redisに保存するだけです。

これは私が見つけた最良の解決策です。 このセッションでは、classを使用してセッションのシリアル化を解除できます。

<?php 
class Session { 
    public static function unserialize($session_data) { 
     $method = ini_get("session.serialize_handler"); 
     switch ($method) { 
      case "php": 
       return self::unserialize_php($session_data); 
       break; 
      case "php_binary": 
       return self::unserialize_phpbinary($session_data); 
       break; 
      default: 
       throw new Exception("Unsupported session.serialize_handler: " . $method . ". Supported: php, php_binary"); 
     } 
    } 

    private static function unserialize_php($session_data) { 
     $return_data = array(); 
     $offset = 0; 
     while ($offset < strlen($session_data)) { 
      if (!strstr(substr($session_data, $offset), "|")) { 
       throw new Exception("invalid data, remaining: " . substr($session_data, $offset)); 
      } 
      $pos = strpos($session_data, "|", $offset); 
      $num = $pos - $offset; 
      $varname = substr($session_data, $offset, $num); 
      $offset += $num + 1; 
      $data = unserialize(substr($session_data, $offset)); 
      $return_data[$varname] = $data; 
      $offset += strlen(serialize($data)); 
     } 
     return $return_data; 
    } 

    private static function unserialize_phpbinary($session_data) { 
     $return_data = array(); 
     $offset = 0; 
     while ($offset < strlen($session_data)) { 
      $num = ord($session_data[$offset]); 
      $offset += 1; 
      $varname = substr($session_data, $offset, $num); 
      $offset += $num; 
      $data = unserialize(substr($session_data, $offset)); 
      $return_data[$varname] = $data; 
      $offset += strlen(serialize($data)); 
     } 
     return $return_data; 
    } 
} 
?> 

あなたwrite()は次のようになります。

public function write($id, $data) { 

    $session_data = Session::unserialize($data); 
    try{ 

     $this->__rc->setex($id, 3600, json_encode($session_data)); 

    } catch (\RedisException $e) { return false; } 

    return true; 

} 
+0

Thxを。 (決して遅くない方が良い) – user2429266

0

これを正解として扱うべきかどうかはわかりませんが、それはうまくいくような解決策です。

ini_set('session.serialize_handler', 'php_serialize'); 

このオプションでは、session_decodeは不要で、writeメソッド内でunserialze()に置き換えることができます。

public function write($id, $data) { 

    $data = unserialize($data); 

    /** do something **/ 

} 

これは回避策のようです。

関連する問題