Source for file Session.php

Documentation is available at Session.php

  1. <?php
  2. // vim: foldmethod=marker
  3. /**
  4.  *  Session.php
  5.  *
  6.  *  @author     Masaki Fujimoto <fujimoto@php.net>
  7.  *  @license    http://www.opensource.org/licenses/bsd-license.php The BSD License
  8.  *  @package    Ethna
  9.  *  @version    $Id: 8848afe7c9ad34755d9310889de6dd982fc2c59c $
  10.  */
  11.  
  12. // {{{ Ethna_Session
  13. /**
  14.  *  セッションクラス
  15.  *
  16.  *  @author     Masaki Fujimoto <fujimoto@php.net>
  17.  *  @access     public
  18.  *  @package    Ethna
  19.  */
  20. {
  21.     /**#@+
  22.      *  @access private
  23.      */
  24.  
  25.     /** @protected    object  Ethna_Logger    loggerオブジェクト */
  26.     protected $logger;
  27.  
  28.     /** @protected    string  セッション名 */
  29.     protected $session_name;
  30.  
  31.     /** @protected    string  セッションデータ保存ディレクトリ */
  32.     protected $session_save_dir;
  33.  
  34.     /** @protected    bool    セッション開始フラグ */
  35.     protected $session_start = false;
  36.  
  37.     /** @protected    bool    匿名セッションフラグ */
  38.     protected $anonymous = false;
  39.  
  40.     /** @protected    array   Configuration for session */
  41.     protected $config = array(
  42.         'handler'           => 'files',
  43.         'path'              => 'tmp',
  44.         'check_remote_addr' => true,
  45.         'cache_limiter'     => 'nocache',
  46.         'cache_expire'      => '180',
  47.         'suffix'            => 'SESSID',
  48.     );
  49.  
  50.     /**#@-*/
  51.  
  52.     /**
  53.      *  Ethna_Sessionクラスのコンストラクタ
  54.      *
  55.      *  @access public
  56.      *  @param  string  $appid      アプリケーションID(セッション名として使用)
  57.      *  @param  string  $save_dir   セッションデータを保存するディレクトリ
  58.      */
  59.     public function __construct($ctl, $appid)
  60.     {
  61.         $this->ctl = $ctl;
  62.         $this->logger = $this->ctl->getLogger();
  63.  
  64.         $config = $this->ctl->getConfig()->get('session');
  65.         if ($config) {
  66.             $this->config = array_merge($this->config, $config);
  67.         }
  68.  
  69.         $this->session_save_dir = $this->config['path'];
  70.         if (($dir = $this->ctl->getDirectory($this->config['path'])) !== null) {
  71.             $this->session_save_dir = $dir;
  72.         }
  73.         $this->session_name = $appid . $this->config['suffix'];
  74.  
  75.         // set session handler
  76.         ini_set('session.save_handler', $this->config['handler']);
  77.         session_save_path($this->session_save_dir);
  78.         session_name($this->session_name);
  79.         session_cache_limiter($this->config['cache_limiter']);
  80.         session_cache_expire($this->config['cache_expire']);
  81.  
  82.         $this->session_start = false;
  83.         if (isset($_SERVER['REQUEST_METHOD']) == false) {
  84.             return;
  85.         }
  86.  
  87.         if (strcasecmp($_SERVER['REQUEST_METHOD'], 'post') == 0) {
  88.             $http_vars = $_POST;
  89.         } else {
  90.             $http_vars = $_GET;
  91.         }
  92.         if (array_key_exists($this->session_name, $http_vars)
  93.             && $http_vars[$this->session_name] != null) {
  94.             $_COOKIE[$this->session_name] = $http_vars[$this->session_name];
  95.         }
  96.     }
  97.  
  98.  
  99.     /**
  100.      *  セッションを復帰する
  101.      *
  102.      *  @access public
  103.      */
  104.     public function restore()
  105.     {
  106.         if (!empty($_COOKIE[$this->session_name])
  107.             || (ini_get("session.use_trans_sid") == 1
  108.             && !empty($_REQUEST[$this->session_name]))
  109.         ) {
  110.             session_start();
  111.             $this->session_start = true;
  112.  
  113.             // check remote address changed
  114.             if ($this->config['check_remote_addr']) {
  115.                 if ($this->isValid() == false) {
  116.                     setcookie($this->session_name, "", 0, "/");
  117.                     $this->session_start = false;
  118.                 }
  119.             }
  120.  
  121.             // check anonymous
  122.             if ($this->get('__anonymous__')) {
  123.                 $this->anonymous = true;
  124.             }
  125.         }
  126.     }
  127.  
  128.     /**
  129.      *  セッションIDを取得する
  130.      *
  131.      *  @access public
  132.      *  @return string  session id
  133.      */
  134.     public function getId()
  135.     {
  136.         return session_id();
  137.     }
  138.  
  139.     /**
  140.      *  セッションの正当性チェック
  141.      *
  142.      *  @access public
  143.      *  @return bool    true:正当なセッション false:不当なセッション
  144.      */
  145.     public function isValid()
  146.     {
  147.         if (!$this->session_start) {
  148.             if (!empty($_COOKIE[$this->session_name]) || session_id() != null) {
  149.                 setcookie($this->session_name, "", 0, "/");
  150.             }
  151.             return false;
  152.         }
  153.  
  154.         // check remote address
  155.         if (!isset($_SESSION['REMOTE_ADDR'])
  156.             || $this->_validateRemoteAddr($_SESSION['REMOTE_ADDR'],
  157.                                           $_SERVER['REMOTE_ADDR']) == false) {
  158.             // we do not allow this
  159.             setcookie($this->session_name, "", 0, "/");
  160.             session_destroy();
  161.             $this->session_start = false;
  162.             return false;
  163.         }
  164.  
  165.         return true;
  166.     }
  167.  
  168.     /**
  169.      *  セッションを開始する
  170.      *
  171.      *  @access public
  172.      *  @param  int     $lifetime   セッション有効期間(秒単位, 0ならセッションクッキー)
  173.      *  @return bool    true:正常終了 false:エラー
  174.      */
  175.     public function start($lifetime = 0, $anonymous = false)
  176.     {
  177.         if ($this->session_start) {
  178.             // we need this?
  179.             $_SESSION['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
  180.             $_SESSION['__anonymous__'] = $anonymous;
  181.             return true;
  182.         }
  183.  
  184.         if (is_null($lifetime)) {
  185.             ini_set('session.use_cookies', 0);
  186.         } else {
  187.             ini_set('session.use_cookies', 1);
  188.         }
  189.  
  190.         session_set_cookie_params($lifetime);
  191.         session_id(Ethna_Util::getRandom());
  192.         session_start();
  193.  
  194.         $_SESSION['REMOTE_ADDR'] = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR']: false;
  195.         $_SESSION['__anonymous__'] = $anonymous;
  196.         $this->anonymous = $anonymous;
  197.         $this->session_start = true;
  198.  
  199.         $this->logger->log(LOG_INFO, 'Session started.');
  200.  
  201.         return true;
  202.     }
  203.  
  204.     /**
  205.      *  セッションを破棄する
  206.      *
  207.      *  @access public
  208.      *  @return bool    true:正常終了 false:エラー
  209.      */
  210.     public function destroy()
  211.     {
  212.         if (!$this->session_start) {
  213.             return true;
  214.         }
  215.  
  216.         session_destroy();
  217.         $this->session_start = false;
  218.         setcookie($this->session_name, "", 0, "/");
  219.  
  220.         return true;
  221.     }
  222.  
  223.     /**
  224.      *  セッションIDを再生成する
  225.      *
  226.      *  @access public
  227.      *  @return bool    true:正常終了 false:エラー
  228.      */
  229.     public function regenerateId($lifetime = 0, $anonymous = false)
  230.     {
  231.         if (! $this->session_start) {
  232.             return false;
  233.         }
  234.  
  235.         $tmp = $_SESSION;
  236.  
  237.         $this->destroy();
  238.         $this->start($lifetime, $anonymous);
  239.  
  240.         unset($tmp['REMOTE_ADDR']);
  241.         unset($tmp['__anonymous__']);
  242.         foreach ($tmp as $key => $value) {
  243.             $_SESSION[$key] = $value;
  244.         }
  245.  
  246.         return true;
  247.     }
  248.  
  249.     /**
  250.      *  セッション値へのアクセサ(R)
  251.      *
  252.      *  @access public
  253.      *  @param  string  $name   キー
  254.      *  @return mixed   取得した値(null:セッションが開始されていない)
  255.      */
  256.     public function get($name)
  257.     {
  258.         if (!$this->session_start) {
  259.             return null;
  260.         }
  261.  
  262.         if (!isset($_SESSION[$name])) {
  263.             return null;
  264.         }
  265.         return $_SESSION[$name];
  266.     }
  267.  
  268.     /**
  269.      *  セッション値へのアクセサ(W)
  270.      *
  271.      *  @access public
  272.      *  @param  string  $name   キー
  273.      *  @param  string  $value  値
  274.      *  @return bool    true:正常終了 false:エラー(セッションが開始されていない)
  275.      */
  276.     public function set($name, $value)
  277.     {
  278.         if (!$this->session_start) {
  279.             // no way
  280.             return false;
  281.         }
  282.  
  283.         $_SESSION[$name] = $value;
  284.  
  285.         return true;
  286.     }
  287.  
  288.     /**
  289.      *  セッションの値を破棄する
  290.      *
  291.      *  @access public
  292.      *  @param  string  $name   キー
  293.      *  @return bool    true:正常終了 false:エラー(セッションが開始されていない)
  294.      */
  295.     public function remove($name)
  296.     {
  297.         if (!$this->session_start) {
  298.             return false;
  299.         }
  300.  
  301.         unset($_SESSION[$name]);
  302.  
  303.         return true;
  304.     }
  305.  
  306.     /**
  307.      *  セッションが開始されているかどうかを返す
  308.      *
  309.      *  @access public
  310.      *  @param  string  $anonymous  匿名セッションを「開始」とみなすかどうか(default: false)
  311.      *  @return bool    true:開始済み false:開始されていない
  312.      */
  313.     public function isStart($anonymous = false)
  314.     {
  315.         if ($anonymous) {
  316.             return $this->session_start;
  317.         } else {
  318.             if ($this->session_start && $this->isAnonymous() != true) {
  319.                 return true;
  320.             } else {
  321.                 return false;
  322.             }
  323.         }
  324.     }
  325.  
  326.     /**
  327.      *  匿名セッションかどうかを返す
  328.      *
  329.      *  @access public
  330.      *  @return bool    true:匿名セッション false:非匿名セッション/セッション開始されていない
  331.      */
  332.     public function isAnonymous()
  333.     {
  334.         return $this->anonymous;
  335.     }
  336.  
  337.     /**
  338.      *  セッションに保存されたIPアドレスとアクセス元のIPアドレスが
  339.      *  同一ネットワーク範囲かどうかを判別する(16bit mask)
  340.      *
  341.      *  @access private
  342.      *  @param  string  $src_ip     セッション開始時のアクセス元IPアドレス
  343.      *  @param  string  $dst_ip     現在のアクセス元IPアドレス
  344.      *  @return bool    true:正常終了 false:不正なIPアドレス
  345.      */
  346.     private function _validateRemoteAddr($src_ip, $dst_ip)
  347.     {
  348.         $src = ip2long($src_ip);
  349.         $dst = ip2long($dst_ip);
  350.  
  351.         if (($src & 0xffff0000) == ($dst & 0xffff0000)) {
  352.             return true;
  353.         } else {
  354.             $this->logger->log(LOG_NOTICE, "session IP validation failed [%s] - [%s]",
  355.                                $src_ip, $dst_ip);
  356.             return false;
  357.         }
  358.     }
  359. }
  360. // }}}

Documentation generated on Fri, 11 Nov 2011 03:59:03 +0900 by phpDocumentor 1.4.3