1. 程式人生 > 實用技巧 >PHP的會話保持Session的總結

PHP的會話保持Session的總結

1、基礎知識

1.1、概念

session是伺服器保持會話資料的一種方法,對應cookie是在客戶端保持使用者資料。

1.2、出現理由

HTTP協議的無狀態

1.3、PHP的Session設計構造

Session分以下幾部分:

1)Session id

使用者Session的唯一標識(隨機生成,具有唯一性,隨機性)

2)Session data

儲存使用者狀態資訊(使用者資料)

3)Session file

Session的儲存方式,檔案儲存方式以"sess_"字首+"Session_id"字尾的方式儲存

格式如下:

sess_d3eom13a9r9p5i5nj923voqaf7

4)Session lifetime

Session生存時間(從Session的產生到生命週期的結束)

1.4、工作原理

1)客戶端與伺服器建立聯絡

2)客戶端將session id傳遞給伺服器

3)伺服器根據session id建立相應的session id檔案(session id序列化儲存,讀取時反序列化)

唯一標識的方法有兩種:cookie或者通過GET方式指定

1.5、Session的缺點

1)使用Session會影響系統性能(受檔案系統設計影響,目錄定義超過10000個檔案非常耗時)

2)Session檔案大小1~2K,數量龐大的小檔案影響硬碟IO效能

1.6、Session配置檔案

1.6.1、預設配置檔案的路徑

/etc/php.ini

1.6.2、查詢配置檔案

find/-namephp.ini

顯示如下:

/etc/php.ini

1.6.3、配置檔案的引數

vim編輯/etc/php.ini

[Session]
session.save_handler=files#session的儲存方式
session.use_cookies=1#使用cookies在客戶端儲存會話
session.use_only_cookies=1#去保護URL中傳送sessionid的使用者
session.name=PHPSESSID#session名稱(預設PHPSESSID)
session.auto_start=0#不啟用請求自動初始化session
session.cookie_lifetime=0#cookie存活時間(0為直至瀏覽器重啟,單位秒)
session.cookie_path=/#cookie的有效路徑
session.cookie_domain=#cookie的有效域名
session.cookie_httponly=#httponly標記增加到cookie上(指令碼語言無法抓取)
session.serialize_handler=php#PHP標準序列化

session.gc_probability=1
session.gc_divisor=1000#建議設定1000-5000
#概率=session.gc_probability/session.gc_divisor(1/1000)
#頁面訪問越頻繁概率越小
session.gc_maxlifetime=1440#過期時間(預設24分鐘,單位秒)

session.bug_compat_42=off#全域性初始化session變數
session.bug_compat_warn=off
session.referer_check=#防止帶有ID的外部URL
session.entopy_length=0#讀取的位元組
session.cache_limiter={nocache,private,pblic}#HTTP緩衝型別
session.cache_expire=180#文件過期時間(分鐘)
session.use_trans_sid=1#trans_sid支援(預設0)
session.hash_function=0#hash方法{0:md5(128bits),1:SHA-1(160bits)}
session.hash_bits_per_character=5#當轉換二進位制hash資料奧可讀形式是,每個字元保留位數
session.save_path="/var/lib/php/session"#sessionid存放路徑

1.6.4、session的儲存目錄

1)預設路徑:

ls-l/var/lib/php/session

顯示如下:

total20
-rw-------.1apacheapache31Jan1308:41sess_0bl5a7anlurcguu1t8qbmjkus5
-rw-------.1apacheapache1320Nov2416:40sess_brv2cvkbhiqehpqu7tgabuvo81
-rw-------.1apacheapache31Jan1308:39sess_d3eom13a9r9p5i5nj923voqaf7
-rw-------.1apacheapache31Jan1308:47sess_j04uc0jaia0sr4qjdrull99hh0
-rw-------.1apacheapache31Jan1307:03sess_me2vo12m5vnlpk1s0oj60mgqv1
-rw-------.1apacheapache0Jan1308:41sess_s4q1ivktojrm8ruv54ob12tol1
-rw-------.1apacheapache0Jan1308:41sess_u3mcdh4cs329131eo6tk7hts22

2)路徑查詢方法:

find/-namesession

顯示如下:

/var/lib/php/session

3)配置檔案自定路徑

grepsession.save_path/etc/php.ini

會發現如下行:

session.save_path="/var/lib/php/session"

注:session.save_path定義的路徑需手動建立並賦予apache使用者讀寫許可權。

4)分層子目錄定義

session.save_path="N;[MODE;]/path"

注:

-- N定義目錄層數(例如2,目錄需手動建立)

-- MODE定義單目錄最大會話檔案數量(預設8進位制600)

5)分層子目錄的生成指令碼

原始碼tar包含名稱為“mod_files.sh”的分層子目錄生成指令碼,程式碼如下:

#!/usr/bin/envbash

if[["$2"=""]]||[["$3"=""]];then
echo"Usage:$0BASE_DIRECTORYDEPTHHASH_BITS"
echo"BASE_DIRECTORYwillbecreatedifitdoesn'texist"
echo"DEPTHmustbeanintegernumber>0"
echo"HASH_BITS(session.hash_bits_per_charactor)shouldbeoneof4,5,or6"
exit1
fi

if[["$2"="0"]]&&[[!"$4"="recurse"]];then
echo"Can'tcreateadirectorytreewithdepthof0,exiting."
fi

if[["$2"="0"]];then
exit0
fi

directory="$1"
depth="$2"
hashbits="$3"

hash_chars="0123456789abcdef"

if[["$hashbits"-ge"5"]];then
hash_chars="$hash_charsghijklmnopqrstuv"
fi

if[["$hashbits"-ge"6"]];then
hash_chars="$hash_charswxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,"
fi

while[[-d$directory]]&&[[$(ls$directory)]];do
echo"Directory$directoryisnotempty!Whatwouldyouliketodo?"

options="\"Deletedirectorycontents\"\"Chooseanotherdirectory\"\"Quit\""
evalset$options
selectoptin"[email protected]";do

if[[$opt="Deletedirectorycontents"]];then
echo"Deleting$directorycontents..."
rm-rf$directory/*
elif[[$opt="Chooseanotherdirectory"]];then
echo"Whichdirectorywouldyouliketochoose?"
readdirectory
elif[[$opt="Quit"]];then
exit0
fi

break;
done
done

if[[!-d$directory]];then
mkdir-p$directory
fi


echo"Creatingsessionpathin$directorywithadepthof$depthforsession.hash_bits_per_character=$hashbits"

foriin$hash_chars;do
newpath="$directory/$i"
mkdir$newpath||exit1
bash$0$newpath`expr$depth-1`$hashbitsrecurse
done

使用格式如下:

bashmod_files.sh<directory><depth><hashbits>
directory--Session目錄存放的根目錄
depth--目錄的深度
hashbits--雜湊值(雜湊值)

使用範例(N=2):

bashmod_files.sh/var/lib/php/session25

生成的目錄名稱大致如下:

-- 有傳參下子目錄名稱一般以16進位制"0 1 2 3 4 5 6 7 8 9 a b c d e f"字母命名

-- 傳參設定hashbits=5 以上加字母"g h i j k l m n o p q r s t u v"

-- 傳參設定hashbits=6 以上加字母"w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - ,"

1.6.5、session的儲存方式

1)檔案方式儲存

session.save_handler=files

2)處理器方式(如mysql)

session.save_handler=user

1.6.6、開啟客戶端會話儲存

session.use_cookies=1

1.7、Session的同步

場景:應用程式層有多臺伺服器,伺服器之間做負載均衡,可通過如下方式解決:

1)Session儲存於資料庫

2)儲存於共享儲存(NFS)

3)負載均衡器保持會話

1.8、Session的管理指令碼

刪除24分鐘內沒有被改變的Session檔案

cd/var/lib/php/session;find-cmin+24|xargsrm

1.9、記憶體直存Session的方法

記憶體直接儲存Session可以改善Session儲存的效能(重啟丟失),設定方法如下:

vim編輯/etc/php.ini

修改如下引數

session.save_path="/dev/shm"

注:"/dev/shm"相當於記憶體入口

2、實踐部分

2.1、基礎環境配置

請參閱如下文件配置PHP環境:

http://cmdschool.blog.51cto.com/2420395/1708325

2.2、yum源安裝

yum-yinstallwgettree

2.3、配置部分

2.3.1、step1

官方下載源安裝包

http://php.net/downloads.php

cd~
wgethttp://cn2.php.net/distributions/php-7.0.2.tar.bz2

2.3.2、step2

解壓原始碼包

tar-xfphp-7.0.2.tar.bz2

2.3.3、step3

執行設定指令碼

cdphp-7.0.2/ext/session
bashmod_files.sh/var/lib/php/session/25
chown-Rapache:apache/var/lib/php/session/
chmod700-R/var/lib/php/session/

2.3.4、step4

檢查目錄結構

tree/var/lib/php/session/

顯示如下:

/var/lib/php/session/
├──0
│├──0
│├──1
│├──2
│├──3
│├──4
│├──5
│├──6
│├──7
│├──8
│├──9
│├──a
│├──b
│├──c
│├──d
│├──e
│├──f
│├──g
│├──h
│├──i
│├──j
│├──k
│├──l
│├──m
│├──n
│├──o
│├──p
│├──q
│├──r
│├──s
│├──t
│├──u
│└──v
├──1
│├──0
│├──1
│├──2
#中間有節刪
1056directories,0files

2.3.5、step5

檢查目錄許可權

ls-l/var/lib/php/session/

2.3.6、step6

重啟httpd服務使PHP的Session相關設定生效

/etc/init.d/httpdrestart

2.3.7、step7

增加測試程式碼:

vim編輯/var/www/www.cmdschool.org/test.php

建立如下程式碼:

<?php
session_start();
$_SESSION["user_name"]="cmdschool.org";
echo$_SESSION["user_name"];
echo"&nbsp;<ahref=\"test2.php\">test2</a>"
?>

vim編輯/var/www/www.cmdschool.org/test2.php

建立如下程式碼:

<?php
session_start();
echo$_SESSION["user_name"];
?>

2.3.8、step8

模擬DNS解析:

notepad%SystemRoot%\System32\drivers\etc\hosts

建立如下對映:

10.168.0.170www.cmdschool.org

2.3.9、step9

測試與檢查:

1)瀏覽器測試

http://www.cmdschool.org/test.php

wKiom1aXb7ThVNMNAABhHU8Ym3k361.png

如上圖所示:

本頁生成Session變數"user_name"並賦值"cmdschool.org"

單擊【test2】跳轉頁面

wKioL1aXb-fQv7fRAABZ-5emcX4069.png

如上圖所示:

本頁輸出Session變數"user_name"的值"cmdschool.org"

2)日誌檢查

tail/var/log/httpd/error_log

3)檢查生成的Session檔案

tree/var/lib/php/session

顯示如下:

#前有節刪
├──n
│├──0
│├──1
│├──2
│├──3
│├──4
│├──5
│├──6
│├──7
│├──8
│├──9
│├──a
│├──b
│├──c
│├──d
│├──e
│├──f
│├──g
│├──h
│├──i
│├──j
│├──k
│├──l
│├──m
│├──n
│├──o
││└──sess_no8luf5jctfd2igrqikpc6mji2
#後有節刪

檔案查閱

cat/var/lib/php/session/n/o/sess_no8luf5jctfd2igrqikpc6mji2

顯示如下:

user_name|s:13:"cmdschool.org";

----------------------------------------------------------------------

參考檔案:

PHP Session的工作原理:

http://www.nowamagic.net/librarys/veda/detail/358

http://www.cnblogs.com/acpp/archive/2011/06/10/2077592.html

http://blog.163.com/lgh_2002/blog/static/4401752620105246517509/

PHP使用Session:

http://www.jb51.net/article/42500.htm

CentOS Session配置:

http://www.centoscn.com/CentOS/Intermediate/2013/1126/2147.html

http://www.2cto.com/os/201202/120886.html

MySQL儲存Session的程式碼:

http://www.jb51.net/article/54226.htm

http://www.oschina.net/code/snippet_59519_2940

PHP多級目錄設定方法:

http://www.tuicool.com/articles/Rfa6rii

轉載於:https://blog.51cto.com/cmdschool/1714757