>백엔드 개발 >PHP 튜토리얼 >프론트엔드 학습 PHP 세션

프론트엔드 학습 PHP 세션

迷茫
迷茫원래의
2017-03-26 09:44:291754검색

이전 단어

세션 기술은 쿠키와 유사하며 둘 다 사용자 관련 정보를 저장하는 데 사용됩니다. 그러나 가장 큰 차이점은 쿠키는 클라이언트의 컴퓨터에 데이터를 저장하는 반면 세션은 서버 시스템에 데이터를 저장한다는 것입니다. 세션(Session)은 중국어로 세션을 의미하며, 일반적으로 웹 시스템에서 사용자와 웹 시스템 간의 대화 과정을 의미합니다. 이번 글에서는 Session의 내용을 자세히 소개하겠습니다.

Session ID

웹 기술 발전의 역사에서 쿠키 기술의 출현은 큰 변화이지만 쿠키는 클라이언트의 컴퓨터에 데이터를 저장합니다. , 그래서 논란을 일으켰습니다. 이용자는 웹서버가 쿠키를 통해 이용자의 정보를 추적하지 못하도록 쿠키의 사용을 거부할 권리가 있습니다. 세션 기술은 사용자 관련 정보를 서버 시스템에 저장하므로 사용자가 세션 사용을 중단할 수 없습니다.

세션은 클라이언트 측에서 사용자를 위해 서버에서 생성한 세션 식별자만 저장하면 되는데, 이를 세션 ID라고 합니다. 세션 변수의 값은 서버 측(파일, 데이터베이스 또는 MemCache)에 저장됩니다. 세션 ID는 반복되지도 않고 쉽게 찾을 수 없는 32자리 16진수 문자열입니다.

세션 ID는 다음과 같은 경우 클라이언트에 저장됩니다. 이용자가 쿠키 사용을 차단한 경우, 이용자 브라우저의 주소 표시줄에 있는 URL에 세션 ID가 저장될 수 있습니다. 사용자가 웹 서버에 요청하면 세션 ID가 서버로 전송되고, 세션 ID를 통해 서버에 저장된 세션 변수가 추출됩니다. Session에 저장된 변수는 해당 사용자의 전역 변수로 간주할 수 있습니다. 각 스크립트에 대한 동일한 사용자의 액세스는 이러한 변수를 공유합니다.

사용자가 웹 서버에 요청하면 서버가 먼저 확인합니다. 클라이언트의 요청에 이미 세션 ID가 포함되어 있는지 여부입니다. 포함되어 있으면 이전에 이 사용자에 대한 세션이 생성되었으며 서버는 세션 ID에 따라 세션을 검색하여 사용한다는 의미입니다. 클라이언트 요청에 세션 ID가 포함되어 있지 않으면 사용자에 대한 세션이 생성되고 이 세션과 연결된 세션 ID가 생성되어 이 응답에 저장하기 위해 클라이언트에 전송됩니다.

사용자가 전송합니다. 웹 서버에 요청 요청 시 먼저 session_start() 함수를 사용하여 새 세션을 시작하거나 기존 세션을 재사용해야 합니다. 세션이 성공적으로 시작되면 TRUE를 반환하고, 그렇지 않으면 FALSE를 반환합니다

bool session_start ([ array $options = [] ] )

쿠키 ​​기반 세션이 열릴 때 호출되기 때문에 () 함수는 set쿠키처럼 클라이언트 컴퓨터의 쿠키에 저장되어야 하는 고유한 SessionID를 생성합니다. () 함수를 호출하기 전에는 어떤 출력도 할 수 없으며 공백이나 빈 줄도 할 수 없습니다

Session이 이미 열려 있는 경우 Session_start() 함수를 다시 호출할 때 새 세션 ID가 생성되지 않습니다. 사용자가 다시 서버에 접속하면 이 함수는 클라이언트가 전달한 세션 ID를 통해 기존 세션을 반환하기 때문입니다. 따라서 세션 중에 동일한 사용자가 서버의 모든 페이지에 액세스할 때 동일한 세션 ID를 사용하게 됩니다.

동일한 이름의 세션 파일(텍스트 파일)을 생성합니다.

Session_start() 함수를 사용하여 모든 스크립트에서 세션을 열지 않으려면 php.ini session.auto_start=1"에서 설정하면 session_start() 함수를 호출할 필요가 없습니다. 세션을 사용하기 전에 매번. 그러나 이 옵션을 활성화하는 데는 몇 가지 제한 사항이 있습니다. 세션을 시작하기 전에 클래스 정의를 로드해야 하기 때문입니다. 따라서 php.ini의 session.auto_start 속성을 사용하여 세션 열기

세션 읽기 및 쓰기

를 사용하는 것은 권장되지 않습니다. session_start() 메서드를 사용하여 세션을 시작한 후에는 세션을 읽고 쓰려면

$_SESSION

어레이에 액세스해야 합니다.

$_POST

,

$_GET$_COOKIE와 마찬가지로 $_SESSION도 슈퍼 전역 배열입니다 $_SESSION배열은 동일한 이름의 세션 파일에 데이터를 저장합니다.

session_start();

동일한 이름의 세션 파일은 텍스트 편집기로 직접 열 수 있습니다. 파일의 내용 구조.

<?php
session_start();
$_SESSION[&#39;username&#39;] = &#39;huochai&#39;;
$_SESSION[&#39;age&#39;] = 28;
?>

变量名|类型:长度:值;

세션 변수는 서버 측 파일에 저장됩니다. 파일 위치는 php.ini 파일을 통해 구성됩니다. session.save_path 속성에 지정된 디렉터리의 세션

PHP 구성 파일 php.ini에는 Session과 관련된 구성 옵션 세트가 있습니다. 일부 옵션에 대해 새 값을 재설정하면 세션을 구성할 수 있습니다. 그렇지 않으면 기본 세션 구성이 사용됩니다.

<?php
session_start();
print_r ($_SESSION);
//Array ( [username] => huochai [age] => 28 )
?>

session.auto_start=0;在请求启动时初始化session
session.cache_expire=180;设置缓存中的会话文档在n分钟后过时
session.cookie_lifetime=0;设置cookie保存时间(s),相当于设置Session过期时间,为0时表示直到浏览器被重启
session.cookie_path=/;cookie的有效路径
session.cookie_domain=;cookie的有效域
session.name=PHPSESSID;用在cookie里的session的名字
session.save_handler=files;用于保存/取回数据的控制方式
session.save_path=/tmp;在save_handler设为文件时传给控制器的参数,这是数据文件将保存的路径.session.use_cookies=1;是否使用cookies

销毁Session

  当使用完一个Session变量后,可以将其删除,当完成一个会话后,也可以将其销毁。如果用户想退出Web系统,就需要提供一个注销的功能,把所有信息在服务器中销毁。销毁和当前Session有关的所有的资料,可以调用session_destroy()函数结束当前的会话,并清空会话中的所有资源

【session_destroy()】

bool session_destroy ( void )

session_destroy()销毁当前会话中的全部数据,删除同名Session文件,但是不会重置当前会话所关联的全局变量,也不会重置会话cookie。如果需要再次使用会话变量,必须重新调用session_start()函数

<?php
session_start();
session_destroy();
?>

可以使用unset()函数来释放在Session中注册的单个变量

print_r ($_SESSION);
//&#39;Array ( [username] => huochai [age] => 28 )&#39;unset($_SESSION[&#39;username&#39;]);
unset($_SESSION[&#39;age&#39;]);
print_r ($_SESSION);//&#39;Array()&#39;

  [注意]不要使用unset($_SESSION)删除整个$_SESSION数组,这样将不能再通过$_SESSION超全局数组注册变量了

  如果想把某个用户在Session中注册的所有变量都删除,可以直接将数组变量$_SESSION赋值为一个空数组

$_SESSION=array();

PHP默认的Session是基于Cookie的,Session ID被服务器存储在客户端的Cookie中,所以在注销Session时也需要清除Cookie中保存的SessionID,而这就必须借助setCookie()函数完成。在Cookie中,保存Session ID的Cookie标识名称就是Session的名称,这个名称是在php.ini中,通过session.name属性指定的值。在PHP脚本中,可以通过调用session_name()函数获取Session名称。删除保存在客户端Cookie中的Session ID

if(isset($_COOKIE[session_name()])) {    
    setCookie(session_name(),&#39;&#39;,time()-3600);
}

通过前面的介绍可以总结出来,Session的注销过程共需要四个步骤

<?php
//第一步:开启Session并初始化
session_start();
//第二步:删除所有Session的变量,也可用unset($_SESSION[xxx])逐个删除
$_SESSION = array();
//第三步:如果使用基于Cookie的Session,使用setCooike()删除包含Session Id的Cookie
if (isset($_COOKIE[session_name()])) {    setcookie(session_name(),&#39;&#39;, time()-42000);
}//第四步:最后彻底销毁Session,删除服务器端保留session信息的文件
session_destroy();?>

自动回收

  如果没有通过上述步骤销毁Session,而是直接关闭浏览器,或断网等情况,在服务器端保存的Session文件是不会被删除的。因为在php.ini配置文件中,默认的session.cookie_lifetime=0,表示Session ID在客户端Cookie的有效期限为直到关闭浏览器。Session ID消失了,但服务器端保存的Session文件并没有被删除。所以,没有被Session ID关联的服务器端Session文件成为了垃圾,而系统则提供了自动清理的机制

  服务器保存的Session文件是普通文本文件,都有文件修改时间。通过在php.ini配置文件中设置session.gc_maxlifetime选项来设置一个到期时间(默认为1440秒,即24分钟)。垃圾回收程序在所有Session文件中排查出大于24分钟的文件。如果用户还在使用该文件,那么这个Session文件的修改时间就会被更新,将不会被排查到

  排除出来后,并不会立刻清理垃圾,而是根据配置文件php.info中session.gc_probability/session.gc_pisor这两个值的比例来决定何时清理,默认值是1/100。表示排查100次,才有一次可能会启动垃圾回收机制,来自动回收垃圾。当然,这个值是可以修改的,但还是要兼顾服务器的运行性能和存储空间

传递session

  使用Session跟踪一个用户,是通过在各个页面之间传递唯一的Session ID,并通过Session ID提取这个用户在服务器中保存的Session变量。常见的Session ID传送方法有以下两种

  1、基于Cookie的方式传递Session ID。这种方法更优化,但由于不总是可用,因为用户在客户端可以屏蔽Cookie

  2、通过URL参数进行传递,直接将会话ID嵌入到URL中去

  在Session的实现中通常都是采用基于Cookie的方式,客户端保存的Session ID就是一个Cookie。当客户禁用Cookie时,Session ID就不能再在Cookie中保存,也就不能在页面之间传递,此时Session失效。不过PHP5在Linux平台可以自动检查Cookie状态,如果客户端将它禁用,则系统自动把Session ID附加到URL上传送。而使用Windows系统作为Web服务器则无此功能

【通过Cookie传递Session ID】

  如果客户端没有禁用Cookie,则在PHP脚本中通过session_start()函数进行初始化后,服务器会自动发送HTTP标头将Session ID保存到客户端电脑的Cookie中
类似于下面的设置方式

//虚拟向Cookie中设置Session ID的过程setCookie(session_name(),session_id(),0,&#39;/&#39;)

  第一个参数中调用session_name()函数,返回当前Session的名称作为Cookie的标识名称。Session名称的默认值为PHPSESSID,是在php.ini文件中由session.name选项指定的值。也可以在调用session_name()函数时提供参数改变当前Session的名称

echo session_name();//PHPSESSID

  第二个参数中调用session_id()函数,返回当前Session ID作为Cookie的值。也可以通过调用session_id()函数时提供参数设定当前Session ID

echo session_id();//kstvdmae177qqk6jgvg6td12l1

  第三个参数的值0,是通过在php.ini文件中由session.cookiejifetime选项设置的值。默认值为0,表示SessIon ID将在客户机的Cookie中延续到浏览器关闭

  最后一个参数'/',也是通过PHP配置文件指定的值,在php.ini中由session.cookie.path选项设置的值。默认值为'/',表示在Cookie中要设置的路径在整个域内都有效

  如果服务器成功将Session ID保存在客户端的Cookie中,当用户再次请求服务器时,就会把Session ID发送回来。所以当在脚本中再次使用session_start()函数时,就会根据Cookie中的Session ID返回已经存在的Session

【通过URL传递Session ID】

  如果客户浏览器支持Cookie,就把Session ID作为Cookie保存在浏览器中。但如果客户端禁止Cookie的使用,浏览器中就不存在作为Cookie的Session ID,因此在客户请求中不包含Cookie信息。如果调用session_start()函数时,无法从客户端浏览器中取得作为Cookie的Session ID,则又创建了一个新的Session ID,也就无法跟踪客户状态。因此,每次客户请求支持Session的PHP脚本,session_start()函数在开启Session时都会创建一个新的Session,这样就失去了跟踪用户状态的功能

  如果客户浏览器不支持Cookie,PHP则可以重写客户请求的URL,把Session ID添加到URL信息中。可以手动地在每个超链接的URL中都添加一个Session ID,但工作量比较大,不建议使用这种方式。如下所示:

<?php    
session_start();    
echo &#39;<a href="demo.php?&#39;.session_name().&#39;=&#39;.session_id() .&#39;">链接演示</a>&#39;;
?>

  在使用Linux系统做服务器时,并且选用PHP4.2以后的版本,则在编辑PHP时如果使用了-enable-trans-sid配置选项,和运行时选项session.use_trans_sid都被激活,在客户端禁用Cookie时,相对URL将被自动修改为包含会话ID。如果没有这么配置,或者使用Windows系统作为服务器时,可以使用常量SID。该常量在会话启动时被定义,如果客户端没有发送适当的会话Cookie,则SID的格式为session_name=session_id,否则就为一个空字符串。因此可以无条件地将其嵌入到URL中去。如下所示

//当阻止cookie时,SID返回'PHPSESSID=p2qouo8hjarul0a0ii5jmocmc0',否则返回一个空字符串echo SID;
<?php   
 session_start();    
 $_SESSION["usemame"]="admin";    
 echo "Session ID:".session_id()."<br>";?>
<a href="test2.php?<?php echo SID ?>">通过URL传递Session ID</a>

  如果使用Linux系统作为服务器,并配置好相应的选项,就不用手动在每个URL后面附加SID,相对URL将被自动修改为包含Session ID。但要注意,非相对的URL被假定为指向外部站点,因此不能附加SID。因为这可能是个安全隐患,会将SID泄露给不同的服务器 

自定义Session

  在系统中使用Session技术跟踪用户时,Session默认的处理方式是使用Web服务器中的文件来记录每个用户的会话信息,通过php.ini中的session_save_path创建会话数据文件的路径。这种默认的处理方式虽然很方便,但也有一些缺陷。例如,登录用户如果非常大,文件操作的I/O开销就会很大,会严重影响系统的执行效率。另外,最主要的是本身的session机制不能跨机,因为对于访问量比较大的系统,通常都是采用多台web服务器进行并发处理,如果每台web服务器都各自独立地处理Session,就不可能达到跟踪用户的目的。这时就需要改变session的处理方式,常见的跨机方法就是通过自定义session的存储方式,可以将session信息使用NFS或SAMBA等共享技术保存到其他服务器中,或使用数据库来保存session信息,最优的方式是使用memcached来进行session存储

  无论是用memcached、数据库、还是通过NFS或SAMBA共享session信息,其原理是一样的,都是通过PHP中的session_set_save_handler()函数来改变默认的处理方式,指定回调函数来自定义处理

Session_set_save_hander(callback open,callback close,call read,callback write,callback destro,callback gc);

该函数共需要6个回调函数作为必选参数,分别代表了Session生命周期中的6个过程,用户通过自定义每个函数,来设置Session生命周期中每个环节的信息处理

回调函数的执行时机如下所示

回调函数        描述 
open          运行session_start()时执行,该函数需要声明两个参数,系统自动将php.ini中的session_save_path选项值传递给该函数的第一个参数,将Session名自动传递给第二个参数中,返回true则可以继续向下执行
close         该函数不需要参数,在脚本执行完成或调用session_write_close()、session_destroy()时被执行,即在所有session操作完成后被执行。如果不需要处理,则直接返回true即可 
read          在运行session_start()时执行,因为在开启会话时,会read当前session数据并写入$_SESSION变量。需要声明一个参数,系统会自动将Session ID传递给该函数,用于通过Session ID获取对应的用户数据,返回当前用户的会话信息写入$_SESSION变量write         该函数在脚本结束和对$_SESSION变量赋值数据时执行。需要声明两个参数,分别是Session ID和串行化后Session信息字符串。在对$_SESSION变量赋值时,就可以通过Session ID找到存储的位置,并将信息写入。存储成功可以返回true继续向下执行
destroy       在运行session_destroy()时执行,需要声明一个参数,系统会自动将Session ID传递给该函数,去删除对应的会话信息
gc            垃圾回收程序启动时执行。需要声明一个参数,系统自动将php.ini中的session_gc_maxlifetime选项值传给该函数,用于删除超过这个时间的Session信息,返回true则可以继续向下执行

在运行session_start()时分别执行了open(启动会话)、read(读取session数据至$_SESSION)和gc(清理垃圾),脚本中所有对$_SESSION的操作均不会调用这些回调函数。在调用session_destroy()函数时,执行destroy销毁当前session(一般是删除相应的记录或文件),但此回调函数销毁的只是Session的数据,此时如果输出$_SESSION变量,仍然有值,但此值不会再close后被写回去。在调用session_write_close()函数时执行write和close,保存$_SESSION至存储,如果不手工使用此方法,则会在脚本结束时被自动执行

  [注意]session_set_save_hander()函数必须在php.ini中设置session_save_hander选项的值为”user”时(用户自定义处理器),才会被系统调用

<?php    
$sess_save_path ="";    
function open($save_path,$session_name){        
                global $sess_save_path; 
        $sess_save_path = $save_path;        
        return true; 
    }  
function close(){        
return true; 
    }    function read($id){        
            global $sess_save_path;  
        $sess_file ="{$sess_save_path}/sess_{$id}"; 
        return (string) @file_get_contents($sess_file); 
    }    function write($id,$sess_data){        global $sess_save_path;  
        $sess_file ="{$sess_save_path}/sess_{$id}"; 
        if($fp=@fopen($sess_file,"w")){   
            $return = fwrite($fp,$sess_data);            
            fclose($fp); 
            return $return; 
        }else{  
            return false; 
        } 
    }  
    function destroy($id){ 
        global $sess_save_path;  
        $sess_file ="{$sess_save_path}/sess_{$id}"; 
        return (@unlink($sess_file)); 
    }   
    function gc($maxlifetime){  
        global $sess_save_path;     
        foreach(glob("{$sess_save_path}/sess_*") as $filename){ 
            if(filemtime($filename) + $maxlifetime <time() ){ 
                @unlink($filename); 
            } 
        }   
        return true; 
    } 
    session_set_save_hander(“open","close","read","write","destroy","gc");
    session_start();
?>

 

数据库处理

  如果网站访问量非常大,需要采用负载均衡技术搭载多台Web服务器协同工作,就需要进行Session同步处理。使用数据库处理Session会比使用NFS及SAMBA更占优势,可以专门建立一个数据库服务器存放Web服务器的Session信息,当用户不管访问集群中的哪个Web服务器,都会去这个专门的数据库,访问自己在服务器端保存的Session信息,以达到Session同步的目的。另外,使用数据库处理Session还可以给我们带来很多好处,比如统计在线人数等。如果mysql也做了集群,每个mysql节点都要有这张表,并且这张Session表的数据要实时同步

  在使用默认的文件方式处理Session时,有3个比较重要的属性,分别是文件名称、文件内容及文件的修改时间:通过文件名称中包含的Session ID,用户可以找到自己在服务器端的Session文件;通过文件内容用户可以在各个脚本中存取$_session变量;通过文件的修改时间则可以清除所有过期的Session文件。所以使用数据表处理Session信息,也最少要有这三个字段(Session ID、修改时间、Session内容信息),当然如果考虑更多的情况,例如,用户改变了IP地址,用户切换了浏览器等,还可以再自定义一些其他字段。下面为Session设计的数据表结构包含5个字段,创建保存Session信息表session的SQL语句如下所示:

CREATE TABLE session(
    sid CHAR(32) NOT NULL DEFAULT &#39;&#39;,
    update INT NOT NULL DEFAULT 0,
    client_ip CHAR(15) NOT NULL DEFAULT &#39;&#39;,
    user_agent CHAR(200) NOT NULL DEFAULT &#39;&#39;,
    data TEXT,
    PRIMARY KEY(sid)
);

数据表session创建成功后,再通过自定义的处理方式,将Session信息写入到数据库中

<?php
class DBSession {    public static $pdo;             //pdo的对象
    public static $ctime;           //当前时间
    public static $maxlifetime;     //最大的生存时间
    public static $uip;             //用户正在用的ip
    public static $uagent;          //用户正在用的浏览器

    //开启和初使化使用的, 参数需要一个路
    public static function start(PDO $pdo) {
        
        self::$pdo = $pdo;
        self::$ctime = time();
        self::$maxlifetime = ini_get("session.gc_maxlifetime");
        self::$uip = !empty($_SERVER[&#39;HTTP_CLIENT_IP&#39;]) ? $_SERVER[&#39;HTTP_CLIENT_IP&#39;] : (!empty($_SERVER[&#39;HTTP_X_FORWARDED_FOR&#39;]) ? $_SERVER[&#39;HTTP_X_FORWARDED_FOR&#39;] : (!empty($_SERVER[&#39;REMOTE_ADDR&#39;]) ? $_SERVER[&#39;REMOTE_ADDR&#39;] : "") );

        filter_var(self::$uip, FILTER_VALIDATE_IP) && self::$uip = &#39;&#39;;
        self::$uagent = !empty($_SERVER[&#39;HTTP_USER_AGENT&#39;]) ? $_SERVER[&#39;HTTP_USER_AGENT&#39;] : "" ;        //注册过程, 让PHP自己处理session时,找这个函数指定的几个周期来完成
        session_set_save_handler(            array(CLASS, "open"), 
            array(CLASS,"close"),            array(CLASS, "read"), 
            array(CLASS, "write"),            array(CLASS, "destroy"), 
            array(CLASS,"gc"));        session_start();  //开启会话    }    // 开启时, session_start()
    public static function open($path, $name) {        return true;
    }    //关闭
    public static  function close() {        return true;
    }    //读取 echo $_SESSION[&#39;username&#39;] 
    public static  function read($sid) {        $sql = "select * from session where sid = ?";        $stmt = self::$pdo -> prepare($sql);        $stmt -> execute(array($sid));        $result = $stmt -> fetch(PDO::FETCH_ASSOC);        //如果还没有会话信息,返回空字符串
        if(!$result) {            return &#39;&#39;;
        }        //如果超出时间,销毁session
        if($result[&#39;utime&#39;] + self::$maxlifetime < self::$ctime) {
            self::destroy($sid);            return &#39;&#39;;
        }        //如果用户换了ip或换了浏览器
        if($result[&#39;uip&#39;] != self::$uip || $result[&#39;uagent&#39;] != self::$uagent) {
            self::destroy($sid);            return &#39;&#39;;
        }        return $result[&#39;sdata&#39;];

    }    //写入 $_SESSION[&#39;username&#39;] = "meizi";
    public static  function write($sid, $data) {        //通过sid获取已经有的数据
        $sql = "select * from session where sid = ?";        $stmt = self::$pdo->prepare($sql);        $stmt -> execute(array($sid));        $result = $stmt -> fetch(PDO::FETCH_ASSOC);        
        //如果已经获取到了数据,就不插入而更新
        if($result) {            //如果数据和原来的不同才更新
            if($result[&#39;sdata&#39;] != $data || $result[&#39;utime&#39;]+10 < self::$ctime) {                $sql = "update session set sdata = ?, utime = ? where sid=?";                $stmt = self::$pdo->prepare($sql);                $stmt -> execute(array($data, self::$ctime, $sid));
            }        //如果没有数据,就新插入一条数据
        } else {        
            if(!empty($data)) {                $sql = "insert into session(sid, sdata, utime, uip, uagent) values(?, ?, ?, ?, ?)";                $stmt = self::$pdo -> prepare($sql);                $stmt -> execute(array($sid, $data, self::$ctime, self::$uip, self::$uagent));
            }
        }

    }    //销毁 session_destroy() 
    public static  function destroy($sid) {        $sql = "delete from session where sid=?";        $stmt = self::$pdo->prepare($sql);        return $stmt -> execute(array($sid)); 
    }    //回收垃圾
    public static  function gc($maxlifetime) {        //    utime < ctime - self::$maxlifetime
        $sql = "delete from session where utime < ?";        $stmt = self::$pdo->prepare($sql);        return $stmt -> execute(array(self::$ctime - self::$maxlifetime));     
    }
}    //开启
    DBSession::start($pdo);

memcached处理

  用数据库来同步Session会加大数据库的负担,因为数据库本来就是容易产生瓶颈的地方,但如果采用MemCache来处理Session是非常合适的,因为MemCache的缓存机制和Session非常相似。另外,MemCach可以做分布式,能够把Web服务器中的内存组合起来,成为一个”内存池”,不管是哪个服务器产生的Session,都可以放到这个“内存池”中,其他的Web服务器都可以使用。以这种方式来同步Session,不会加大数据库的负担,并且安全性也要比使用Cookie高。把session放到内存里面,读取也要比其他处理方式快很多

  自定义使用memcached处理session信息,和自定义数据库的处理方式相同,但要简单得多,因为MemCache的工作机制和Session技术很相似

<?phpclass MemSession {    public static $mem;             //pdo的对象
    public static $maxlifetime;     //最大的生存时间

    public static function start(Memcache $mem) {    
        self::$mem = $mem;    
        self::$maxlifetime = ini_get("session.gc_maxlifetime");    
        //注册过程, 让PHP自己处理session时,按照这个函数指定的几个周期来完成
        session_set_save_handler(            array(CLASS, "open"), 
            array(CLASS,"close"),            array(CLASS, "read"), 
            array(CLASS, "write"),            array(CLASS, "destroy"), 
            array(CLASS,"gc"));        session_start();  //开启会话    }    // 开启时,session_start()
    public static function open($path, $name) {        return true;
    }    //关闭
    public static  function close() {        return true;
    }    //读取 echo $_SESSION[&#39;username&#39;] 
    public static  function read($sid) {        $data = self::$mem -> get($sid);        if(empty($data)) {            return &#39;&#39;;
        }        return $data;
    }    //写入
    public static  function write($sid, $data) {
        self::$mem -> set($sid, $data, MEMCACHE_COMPRESSED, self::$maxlifetime);
    }    //销毁 session_destroy() 
    public static  function destroy($sid) {
        self::$mem -> delete($sid, 0);

    }    //回收垃圾
    public static  function gc($maxlifetime) {        return true;    
    }
}    //创建对象
    $mem = new Memcache();    //添加两台memcache服务器
    $mem -> addServer("localhost", 11211);    $mem -> addServer("192.168.1.3", 11211);    //开启
    MemSession::start($mem);?>

 

위 내용은 프론트엔드 학습 PHP 세션의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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