>백엔드 개발 >PHP 튜토리얼 >PHP 세션에 대한 심층적인 설명과 expiring_php 기술을 방지하는 방법

PHP 세션에 대한 심층적인 설명과 expiring_php 기술을 방지하는 방법

WBOY
WBOY원래의
2016-05-16 20:08:211042검색

COOKIE 기술은 SESSION 구현에 사용됩니다. SESSION은 클라이언트 측에 session_id(SESSION 번호)를 포함하는 COOKIE를 저장하고, session_name 등과 같은 다른 세션 변수는 서버 측에 저장됩니다. 사용자가 서버에 요청하면 session_id도 서버로 전송됩니다. session_id를 통해 서버측에 저장된 변수를 추출하면 사용자가 누구인지 식별할 수 있습니다. 동시에 SESSION이 때때로 실패하는 이유를 이해하는 것은 어렵지 않습니다.

클라이언트가 COOKIE를 비활성화한 경우(IE에서 "도구" - "인터넷 옵션" 클릭, 팝업 대화 상자에서 "보안" - "사용자 정의 수준" 항목 클릭, "각 대화 COOKIE 허용" 설정(비활성화)) , session_id가 전달되지 않고 SESSION이 무효화됩니다. 그러나 php5는 Linux/Unix 플랫폼에서 쿠키 상태를 자동으로 확인할 수 있습니다. 클라이언트가 비활성화된 경우 시스템은 자동으로 session_id를 URL에 추가하고 이를 전달합니다. Windows 호스트에는 이 기능이 없습니다.

Session의 공통 기능과 사용법은?
Session_start(): 세션을 시작하거나 기존 세션을 반환합니다.
참고: 이 함수에는 매개변수가 없으며 반환 값은 true입니다. 쿠키 기반 세션을 사용하는 경우 브라우저는 Session_start()를 사용하기 전에 어떤 출력도 생성해서는 안 됩니다. 그렇지 않으면 다음 오류가 발생합니다.
경고: 세션 캐시 제한기를 보낼 수 없습니다. 헤더가 이미 전송되었습니다(/usr/local/apache/htdocs/cga/member/1.php:2에서 출력이 시작됨)…………


php.ini에서 session.auto_start=1을 활성화하면 세션을 사용하기 전에 매번 session_start()를 호출할 필요가 없습니다. 하지만 이 옵션을 활성화하는 데에는 몇 가지 제한 사항이 있습니다. session.auto_start가 실제로 활성화된 경우 세션에서 객체를 다시 생성하려면 세션을 시작하기 전에 클래스 정의를 로드해야 하기 때문에 객체를 세션에 넣을 수 없습니다.
등록된 모든 변수는 요청이 완료된 후 직렬화됩니다. 등록되었으나 정의되지 않은 변수는 정의되지 않음으로 표시됩니다. 이러한 변수는 사용자가 나중에 정의하지 않는 한 후속 액세스 시 세션 모듈에 의해 정의되지 않습니다.

경고: 일부 데이터 유형은 직렬화할 수 없으므로 세션에 저장할 수 없습니다. 순환 참조가 있는 리소스 변수 또는 개체를 포함합니다(즉, 한 개체가 자신에 대한 참조를 다른 개체에 전달함).

SESSION 변수 등록:
PHP5는 $_SESSION['xxx']=xxx를 사용하여 SESSION 전역 변수를 등록합니다. GET, POST, COOKIE의 사용 방법은 유사합니다.
참고: session_register(), session_unregister, session_is_registered는 php.ini에서 Register_globle이 on으로 설정되어 있지 않는 한 php5에서 더 이상 사용되지 않습니다. 그러나 보안상의 이유로 Register_globle을 끄는 것이 좋습니다. HTTP_SESSION_VARS 사용은 더 이상 권장되지 않으며 대신 $_SESSION을 사용하는 것이 공식적인 권장 사항입니다. 예:

Page1.php

  <&#63;php
  Session_start(); //使用SESSION前必须调用该函数。

  $_SESSION[‘name']=”我是黑旋风李逵!”; //注册一个SESSION变量

  $_SESSION[‘passwd']=”mynameislikui”;
  $_SESSION[‘time']=time();
  echo '
  通过COOKIE传递SESSION'; //如果客户端支持cookie,可通过该链接传递session到下一页。

  echo '
  . SID . '">通过URL传递SESSION';//客户端不支持cookie时,使用该办法传递session.

  &#63;>

Page2.php

  <&#63;php
  session_start();
  echo $_SESSION['name']; //

  echo $_SESSION['passwd']; //

  echo date('Y m d H:i:s', $_SESSION['time']);
  echo '
  返回山一页';
  &#63;>

세션 ID를 전달하는 방법에는 두 가지가 있습니다.

  1. 쿠키
  2. URL 매개변수

세션 모듈은 두 가지 방법을 모두 지원합니다. 쿠키는 더욱 최적화되어 있지만 항상 사용할 수 있는 것은 아니기 때문에 대안도 제공됩니다. 두 번째 방법은 세션 ID를 URL 중간에 직접 삽입하는 것입니다.

PHP는 연결을 투명하게 변환할 수 있습니다. PHP 4.2 이상을 사용하지 않는 한, PHP를 컴파일할 때 수동으로 활성화해야 합니다. Unix에서는 --enable-trans-sid 구성 옵션을 사용합니다. 이 구성 옵션과 런타임 옵션 session.use_trans_sid가 모두 활성화된 경우(php.ini 수정), 상대 URI는 세션 ID를 포함하도록 자동으로 수정됩니다.

세션_ID
session_id()는 현재 session_id를 설정하거나 가져오는 데 사용됩니다. php5에서는 session_id()를 사용하거나 URL에 첨부된 SID를 통해 현재 세션의 session_id 및 session_name을 얻을 수 있습니다.
session_id()에 특정 값이 있는 경우 현재 session_id 값을 대체합니다. 이 함수를 사용하기 전에 세션을 시작해야 합니다: session_start();
세션 쿠키를 사용할 때 session_id() 값이 지정되면 session_start()가 시작될 때마다 쿠키 값이 클라이언트로 전송됩니다. 현재 session_id가 지정된 값과 같은지 여부에 관계없이.
session_id()가 값을 지정하지 않으면 현재 session_id()를 반환하고, 현재 세션이 시작되지 않으면 빈 문자열을 반환합니다.

세션이 존재하는지 확인하세요.
이전 PHP 버전에서는 세션이 존재하는지 확인하기 위해 일반적으로 session_is_register()를 사용했습니다. $_SESSION['XXX']=XXX를 사용하여 세션 변수를 등록하면 session_is_register() 함수가 더 이상 작동하지 않습니다.
을 사용할 수 있습니다. isset($_SESSION['xxx']) 대신.

session_id 변경 session_regenerate_id()는 변경이 성공하면 true를 반환하고, 실패하면 false를 반환합니다.
이 함수를 사용하면 현재 세션의 session_id를 변경할 수 있지만, 현재 세션의 다른 정보는 변경되지 않습니다. 예:

  <&#63;php
  session_start();
  $old_sessionid = session_id();
  session_regenerate_id();
  $new_sessionid = session_id();
  echo "原始 SessionID: $old_sessionid
  ";
  echo "新的 SessionID: $new_sessionid
  ";
  echo"

  ";

  print_r($_SESSION);
  echo"";
  &#63;>

session_name()은 현재 세션의 이름을 반환하거나 현재 세션의 이름을 변경합니다. 현재 세션의 이름을 변경하려면 session_start() 이전에 이 함수를 호출해야 합니다. 참고: session_name은 숫자로만 구성될 수 없으며 최소한 하나의 문자를 포함해야 합니다. 그렇지 않으면 매번 새로운 세션 ID가 생성됩니다.
세션 이름 변경의 예:

$previous_name = session_name("WebsiteID");
echo "新的session名为: $previous_name
";
&#63;>

如何删除session?
1、unset ($_SESSION['xxx']) 删除单个session,unset($_SESSION['xxx']) 用来unregister一个已注册的session变量。其作用和session_unregister()相同。 session_unregister()在PHP5中不再使用,可将之打入冷宫。
unset($_SESSION) 此函数千万不可使用,它会将全局变量$_SESSION销毁,而且还没有可行的办法将其恢复。用户也不再可以注册$_SESSION变量。
2、$_SESSION=array() 删除多个session
3、 session_destroy()结束当前的会话,并清空会话中的所有资源。。该函数不会unset(释放)和当前session相关的全局变量 (globalvariables),也不会删除客户端的session cookie.PHP默认的session是基于cookie的,如果要删除cookie的话,必须借助setcookie()函数。
返回值:布尔值。
功能说明:这个函数结束当前的session,此函数没有参数,且返回值均为true

session_unset() 如果使用了$_SESSION,则该函数不再起作用。由于PHP5必定要使用$_SESSION,所以此函数可以打入冷宫了。

下面是PHP官方关于删除session的案例:

  <&#63;php
  // 初始化session.

  session_start();
  /*** 删除所有的session变量..也可用unset($_SESSION[xxx])逐个删除。****/
  $_SESSION = array();
  /***删除sessin id.由于session默认是基于cookie的,所以使用setcookie删除包含session id的cookie.***/
  if (isset($_COOKIE[session_name()])) {
  setcookie(session_name(), '', time()-42000, '/');
  }

// 最后彻底销毁session.

  session_destroy();
  &#63;>

由此我们可以得出删除Session的步骤:

  1. session_start()
  2. $_SESSION=array()/unset($_SESSION['xxx'])
  3. session_destroy()

解决PHP Session不过期以及SessionId保持不变的问题

session 回收机制:
 
PHP采用Garbage Collection process对过期session进行回收,然而并不是每次session建立时,都能够唤起 ‘garbage collection' process ,gc是按照一定概率启动的。这主要是出于对服务器性能方面的考虑,每个session都触发gc,浏览量大的话,服务器吃不消,然而按照一定概率开启gc,当流览量大的时候,session过期机制能够正常运行,而且服务器效率得到节省。细节应该都是多年的经验积累得出的。
 
三个与PHP session过期相关的参数(php.ini中):
 

  1. session.gc_probability = 1
  2. session.gc_divisor = 1000
  3. session.gc_maxlifetime = 1440

gc启动概率 = gc_probability / gc_divisor = 0.1%
 
session过期时间 gc_maxlifetime 单位:秒
 
当web服务正式提供时,session过期概率就需要根据web服务的浏览量和服务器的性能来综合考虑session过期概率。为每个session都开启gc,显然是不明智的,感觉有点“碰运气”的感觉,要是访问量小命中几率就小。我在本机测试过程中,几乎都没有被命中过,sessionid几天都不变,哪怕机器重启。测试过程中,这个过期概率值要设置大一点命中几率才高点。
 
通过修改php配置文件的过期概率值,可以“碰运气”式的设置session过期,那有没有更好的办法呢?
 

下面写的这个session类可以彻底解决session不过期以及sessionid不变的问题。
 

<&#63;php
 /**
 * 扩展Session类(简单封装)
 * 
 * @author slimboy
 *
 */
class Session { 
 
   /**
   * 初始化
   */
  static function _init(){ 
    ini_set('session.auto_start', 0); 
    //Session::start(); 
   } 
   
   /**
   * 启动Session
   */
  static function start() { 
    session_start(); 
  } 
 
   /**
   * 设置Session
   * 
   * @param $name Session名称
   * @param $value 值
   * @param $time 超时时间(秒)
   */
  public static function set($name,$value,$time){ 
    if(empty($time)){ 
      $time = 1800; //默认值 
     } 
    $_SESSION[$name] = $value; 
    $_SESSION[$name.'_Expires'] = time() + $time; 
  } 
   
   /**
   * 获取Session值
   * 
   * @param $name Session名称
   */
  public static function get($name){ 
    //检查Session是否已过期 
     if(isset($_SESSION[$name.'_Expires']) && $_SESSION[$name.'_E
 xpires']>time()){ 
      return $_SESSION[$name]; 
    }else{ 
      Session::clear($name); 
      return null; 
    } 
  } 
   
    
   /**
   * 设置Session Domain
   * 
   * @param $sessionDomain 域
   * @return string
   */
  static function setDomain($sessionDomain = null) { 
    $return = ini_get('session.cookie_domain'); 
    if(!empty($sessionDomain)) { 
      ini_set('session.cookie_domain', $sessionDomain);//跨
 域访问Session 
     } 
    return $return; 
  } 
   
    
   /**
   * 清除某一Session值
   * 
   * @param $name Session名称
   */
  static function clear($name){ 
    unset($_SESSION[$name]); 
    unset($_SESSION[$name.'_Expires']); 
  } 
   
    
   /**
   * 重置销毁Session
   */
  static function destroy(){ 
    unset($_SESSION); 
    session_destroy(); 
  } 
   
    
   /**
   * 获取或设置Session id
   */
  static function sessionid($id=null){ 
    return session_id($id); 
  } 
 
}
&#63;>
简单调用:
 
<&#63;php
  //设置session 
  Session::set('UserId', $userid, 3600); 
  //读取session
  $userId = Session::get('UserId');
&#63;>

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.