大家都知道SESSION是不可以跨域的,也就是說(shuō): A.WEMVC.COM這個(gè)域的可執(zhí)行文件不可以訪問(wèn)到B.WEMVC.COM的SESSION,這個(gè)是SESSION的特性,同樣也是出于安全角度才這樣的. 在一般情況下,一個(gè)網(wǎng)站只有一個(gè)域名,但是也有些網(wǎng)站架構(gòu)是由多個(gè)子域名組建的.所以就需要SESSION可以跨子域被訪問(wèn)到,這樣才可以實(shí)現(xiàn)用戶的跨域登錄.就是說(shuō)客戶在A下登錄的,同樣B也同時(shí)登錄了,不需要用戶再次登錄,同時(shí)也實(shí)現(xiàn)了參數(shù)的跨域傳遞.當(dāng)然不可跨域的SESSION本身已經(jīng)可以幫助我們做很多事情了,那么跨域后的SESSION呢.讀到這里是否很激動(dòng)人心,當(dāng)然你也可能是正在為SESSION跨域而發(fā)愁而找到這篇文章的,同樣也祝賀你.我們長(zhǎng)話斷說(shuō)了,開(kāi)始我們今天的課程:COOKIE與SESSION聯(lián)用實(shí)現(xiàn)SESSION跨域.首先讓我們?cè)僦匦聹亓?xí)下PHP中的COOKIE和SESSION:COOKIE: 定義: cookie 常用于識(shí)別用戶。cookie 是服務(wù)器留在用戶計(jì)算機(jī)中的小文件。每當(dāng)相同的計(jì)算機(jī)通過(guò)瀏覽器請(qǐng)求頁(yè)面時(shí),它同時(shí)會(huì)發(fā)送 cookie。通過(guò) PHP,您能夠創(chuàng)建并取回 cookie 的值。PS:其中文名叫 曲奇 . 在PHP中用sethtml' target='_blank'>Cookie函數(shù)來(lái)設(shè)置COOKIE,該函數(shù)一共有7個(gè)參數(shù)(在此我要向曾經(jīng)我面試過(guò)的一位同仁道歉,當(dāng)時(shí)我把答案說(shuō)成了6個(gè),SORRY~,同時(shí)我也提醒廣大作家盡快更新自己的文章,在PHP5.2.0版本中已經(jīng)增加為7個(gè)參數(shù).),這7個(gè)參數(shù)分別為 string $name [, string $value [, int $expire [, string $path [, string $domain [, bool $secure [, bool $httponly ]]]]]] . name The name of the cookie. 規(guī)定 cookie 的名稱。 value The value of the cookie. This value is stored on the clients computer; do not store sensitive information. Assuming the name is cookiename , this value is retrieved through $_COOKIE['cookiename'] 規(guī)定 cookie 的值。 expire The time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch. In other words, you ll most likely set this with the time() function plus the number of seconds before you want it to expire. Or you might use mktime(). time()+60*60*24*30 will set the cookie to expire in 30 days. If set to 0, or omitted, the cookie will expire at the end of the session (when the browser closes).規(guī)定 cookie 的有效期。Note: You may notice the expire parameter takes on a Unix timestamp, as opposed to the date format Wdy, DD-Mon-YYYY HH:MM:SS GMT, this is because PHP does this conversion internally. expire is compared to the client s time which can differ from server s time. path The path on the server in which the cookie will be available on. If set to / , the cookie will be available within the entire domain . If set to /foo/ , the cookie will only be available within the /foo/ directory and all sub-directories such as /foo/bar/ of domain . The default value is the current directory that the cookie is being set in.規(guī)定 cookie 的服務(wù)器路徑。 domain The domain that the cookie is available. To make the cookie available on all subdomains of example.com then you d set it to .example.com . The . is not required but makes it compatible with more browsers. Setting it to www.example.com will make the cookie only available in the www subdomain. Refer to tail matching in the spec for details.規(guī)定 cookie 的域名。 secure Indicates that the cookie should only be transmitted over a secure HTTPS connection from the client. When set to TRUE, the cookie will only be set if a secure connection exists. The default is FALSE. On the server-side, it s on the programmer to send this kind of cookie only on secure connection (e.g. with respect to $_SERVER[ HTTPS ]).規(guī)定是否通過(guò)安全的 HTTPS 連接來(lái)傳輸 cookie。 httponly When TRUE the cookie will be made accessible only through the HTTP protocol. This means that the cookie won t be accessible by scripting languages, such as JavaScript. This setting can effectly help to reduce identity theft through XSS attacks (although it is not supported by all browsers). Added in PHP 5.2.0. TRUE or FALSE.規(guī)定是否必須通過(guò)HTTP協(xié)議來(lái)定義訪問(wèn)COOKIE,防止XSS攻擊. SESSION全面教程 SESSION在這里就不過(guò)多的講解了,主要是: session_cache_expire Return current cache expire session_cache_limiter Get and/or set the current cache limiter session_commit Alias of session_write_close session_decode Decodes session data from a string session_destroy Destroys all data registered to a session session_encode Encodes the current session data as a string session_get_cookie_params Get the session cookie parameters session_id Get and/or set the current session id session_is_registered Find out whether a global variable is registered in a session session_module_name Get and/or set the current session module session_name Get and/or set the current session name session_regenerate_id Update the current session id with a newly generated one session_register Register one or more global variables with the current session session_save_path Get and/or set the current session save path session_set_cookie_params Set the session cookie parameters session_set_save_handler Sets user-level session storage functions session_start Initialize session data session_unregister Unregister a global variable from the current session session_unset Free all session variables session_write_close Write session data and end session 哈哈,不是我懶噢,這里只講跨域. OK,大概溫習(xí)了下COOKIE和SESSION,開(kāi)始實(shí)現(xiàn)我們的跨域. 首先我描述下我的思路,COOKIE可以指定域名,也就是說(shuō)它可以跨域子域,例如:setcookie( name ,'joshua ,time()+3600*24, /', wemvc.com ),那么A.wemvc.com,B.wemvc.com都可以訪問(wèn)到$_COOKIE['name'],值也均為 joshua .同理,SESSION ID也可以設(shè)置成這個(gè)域名,那么A.wemvc.com和B.wemvc.com都可以得到同一個(gè)SESSION ID,那么我們的目的也就達(dá)到了.因?yàn)橹懒送粋€(gè)SESSION ID就可以訪問(wèn)到這個(gè)SESSION中的值了.SESSION有多種方式存儲(chǔ),文件/數(shù)據(jù)庫(kù)/內(nèi)存等,我們采用數(shù)據(jù)庫(kù)存儲(chǔ),因?yàn)槿绻鸄.wemvc.com,B.wemvc.com不在同一臺(tái)服務(wù)器上,那么內(nèi)存和文件的存儲(chǔ)方式就很難實(shí)現(xiàn)跨域了,至于到底又沒(méi)有方法,本人還沒(méi)有試過(guò). 首先在數(shù)據(jù)庫(kù)中創(chuàng)建一張SESSION表: CREATE TABLE `sessions` ( `sid` varchar(32) NOT NULL default '', `expiry` int(20) unsigned NOT NULL default '0', `value` text NOT NULL, PRIMARY KEY (`sid`), KEY `expiry` (`expiry`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
然后寫(xiě)一個(gè)類,這個(gè)類用于讀取/插入/更新/刪除以及垃圾回收SESSION class session{ private $db; function __construct($db){ $this- db=$db; } public function open($save_path,$session_name){ return true; } public function close(){ $this- db=null; return true; } public function read($sid){ $rs=$this- db- query( select * from sessions where sid=' .$sid. ' foreach ($rs as $row){ return $row['value']; } return null; } public function write($sid,$value){ if(is_null($oldvalue=$this- read($sid))){ //insert return $this- db- query( insert into sessions (sid,expiry,value)values( .$sid. , .time(). , .$value. ) ); }else{ //update return $this- db- query( update sessions set expiry= .time(). ,value= .$value. where sid= .$sid. ); } } public function destroy($sid){ return $this- db- query( delete from sessions where sid= .$sid. ); } public function gc($max_life_time){ return $this- db- query( delete from sessions where expiry+ .$max_life_time. .time()); } } 我來(lái)解釋下這個(gè)類: private $db; 類的DATABASE屬性. function __construct($db) 類的構(gòu)造函數(shù),在聲明類時(shí),可以直接傳遞DB屬性到類中,當(dāng)然如果還不明白可以先GOOGLE一下 PHP 類 construct 方法 public function open($save_path,$session_name) session打開(kāi),沒(méi)有什么花頭,直接返回TRUE; public function close() session關(guān)閉,同理open,但注意要關(guān)閉DB連接; public function read($sid) session讀取,傳值SID,在數(shù)據(jù)表中將這個(gè)SID的VALUE作為返回值返回; public function write($sid,$value) session的寫(xiě)入與更新,這個(gè)你會(huì)有疑問(wèn),為什么set expiry= .time(). ,稍后答案在清空過(guò)期SESSION GC方法中便會(huì)揭曉; public function destroy($sid) session的銷毀,很簡(jiǎn)單,就是把數(shù)據(jù)表中等于這個(gè)SID的數(shù)據(jù)刪除掉; public function gc($max_life_time) 清空過(guò)期session,把超過(guò)max_life_time的SESSION都銷毀掉,也就是SESSION的創(chuàng)建時(shí)間加上最大生存時(shí)間小于現(xiàn)在時(shí)間( expiry+ .$max_life_time. .time())的SESSION數(shù)據(jù)刪除掉,這下你會(huì)明白為什么在寫(xiě)入和更新SESSION的方法中為什么寫(xiě)當(dāng)前時(shí)間了吧,當(dāng)然這個(gè)寫(xiě)法不是絕對(duì)的,隨個(gè)人意愿只要你的SQL寫(xiě)正確了,也就可以了. 好我們接著來(lái)看更重要的部分: 上面的類中需要一個(gè)數(shù)據(jù)庫(kù)鏈接屬性,所以聲明對(duì)象的時(shí)候需要這樣: $session=new session(your db connect adapter); 數(shù)據(jù)庫(kù)鏈接我可以提供大家一個(gè)PDO的方法,參照使用: function connect_db($arrPDODB){ $db=new PDO($arrPDODB['db_driver']. :host= .$arrPDODB['db_host']. dbname= .$arrPDODB['db_name'],$arrPDODB['db_user'],$arrPDODB['db_password']); $db- query( set names utf8 ); return $db; }