- 浏览: 78853 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
memoryisking:
关于更多ConcurrentModificationExcep ...
java.util.ConcurrentModificationException原因 -
memoryisking:
关于更多TimeUnit的内容可以去看这里: 发生Concu ...
java.util.ConcurrentModificationException原因 -
yzzshmily:
yzzshmily 写道我今天也遇到这种情况了, checkC ...
谷歌浏览器中的 name 变量 -
yzzshmily:
我今天也遇到这种情况了, checkClientName(ne ...
谷歌浏览器中的 name 变量
PHP5 Session 浅析II
我们在<<PHP5 Session 浅析I>>中探讨了session存储,session同步数据以及session数据编码 。我们将在这里继续探讨一下session id传递与session回收。
Session ID传递
session终究是因为管理用户状态信息才存在的。我们曾探讨过session id的意义:每个来访问用户都会被分配一个唯一的session id,用于区分其它用户的session数据。换句话说,session id是用户表明身份的一种标识,就像入场券一样。用户一旦从被分配了session id之后的每次访问(http请求)都会携带这个session id给服务端,用于加载该用户的session数据。那么,通过什么方式传给服务端?这是我们这节探讨的内容。
用户端与服务端的web通信协议是http。而PHP通过http取得用户数据惯用的三种方法分别是:POST方法、GET方法还有Cookie。 而PHP默认传递方法正是Cookie,也是最佳方法。只有在客户端不支持Cookie的时候(浏览器禁用了Cookie功能)才会通过GET方法来传递 session_id,即通过在URL的query_string部分传递session id。
确定了传递方法,我们还有必要清楚一下session id的传递过程。用户通过浏览器访问网页,将URL输入地址栏回车,浏览器发出请求,在调用sockect send之前浏览器引擎会搜索有效的Cookies记录封装在http请求头的Cookie字段,一同发送出去。服务端器接收到请求后,交给PHP处理。 这时,session初始化函数如果在$_COOKIE中没有找到以session_name()作为键值存储的生素(值为session id),则会以为用户是第一次访问web。作为第一次访问的用户,session初始化函数总会随机生成一个session_id并且通过 setcookie()函数调用将新生成的session_id以”sesseson_name = session_id”的格式填入http响应头Set-Cookie字段,发送给客户端(这样接下来的请求,http请求头Cookie字段都会携带该 Cookie记录给web服务器)。如果初始化函数发现用户端Cookies中已定义了存在$_COOKIE[‘sess_name’],则会加载 与$_COOKIE[‘sess_name’]相对应的session文件($_COOKIE[‘sess_name’]就是session ID)。如果用户Cookie记录过期,则会被浏览器删除。之后的下一次请求,服务器会以为用户又是第一次访问,如此循环。
让我们通过测与来验证以上的陈述
<?php //@file p1.php session_start(); ?>
通过截取到的http数据包如下
#
T 192.168.0.98:2290 -< 192.168.0.8:8080 [AP]
GET /a.php HTTP/1.1..Host: 192.168.0.8:8080..Connection: keep-alive..User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1
; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.3 Safari/533.2..Accept: application/xml,application/xhtml+
xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5..Accept-Encoding: gzip,deflate,sdch..Accept-Language: zh-CN,zh;
q=0.8..Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3….
##
T 192.168.0.8:8080 -< 192.168.0.98:2290 [AP]
HTTP/1.1 200 OK..Date: Mon, 12 Apr 2010 08:25:11 GMT..Server: Apache/2.2.3 (CentOS)..X-Powered-By: PHP/5.1.6..Set-Cookie
: PHPSESSID=bk7655dqrm5m884c9nitfi7j00;
path=/..Expires: Thu, 19 Nov 1981 08:52:00 GMT..Cache-Control: no-store, no-cach
e, must-revalidate, post-check=0, pre-check=0..Pragma: no-cache..Content-Length: 0..Connection: close..Content-Type: tex
t/html; charset=UTF-8….
##
第一次访问/a.php的时候,请求包里面没有设置任何Cookie,所以这里的Cookie字段为空。当然服务器php也就得不到 的$_COOKIE[‘PHPSESSID’](即session id为空)。如此,服务器会以为用户是第一次访问web。所以session初始化的时候,会给用户分配一个唯一的session_id并且以 Cookie的方法传回给了用户端。
我们再来观察第二次请求与响应,会有哪些变化:
#
T 192.168.0.98:2314 -< 192.168.0.8:8080 [AP]
GET /a.php HTTP/1.1..Host: 192.168.0.8:8080..Connection: keep-alive..User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1
; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.3 Safari/533.2..Cache-Control: max-age=0..Accept: applicat
ion/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5..Accept-Encoding: gzip,deflate,sdch..
Accept-Language: zh-CN,zh;q=0.8..Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3..Cookie: PHPSESSID=bk7655dqrm5m884c9nitfi7j00
..
..
##
T 192.168.0.8:8080 -< 192.168.0.98:2314 [AP]
HTTP/1.1 200 OK..Date: Mon, 12 Apr 2010 08:32:13 GMT..Server: Apache/2.2.3 (CentOS)..X-Powered-By: PHP/5.1.6..Expires: T
hu, 19 Nov 1981 08:52:00 GMT..Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0..Pragma: no-
cache..Content-Length: 0..Connection: close..Content-Type: text/html; charset=UTF-8….
##
首先,我们观察http请求,加红色部分是第一次http请求头没有出现的内容。我们可以看到,该Cookie正是第一次访问,服务端通过Set-
Cookie要求浏览器设置的Cookie。它们是一样的,即session_id为bk7655dqrm5m884c9nitfi7j00。然后,我们
再观察这次的http响应,明显没有再要求用户端设置键为session_name()的Cookie了。
我们再来测试伪造一个session_id发送给服务,观察服务端响应。我们写一个测试脚本,如下:
<?php $host = '192.168.0.8'; $port = 8080; $path = '/p1.php'; $sid = "PHPSESSID=dk7655dqrm5m884c9nitfi7j00"; $fp = fsockopen($host, $port, $error_no, $error_desc, 30); if ($fp) { fputs($fp, "GET {$path} HTTTP/1.1\r\n"); fputs($fp, "Host: {$host}\r\n"); fputs($fp, "Cookie: {$sid}\r\n"); fputs($fp, "Connection: close\r\n\r\n"); while (!feof($fp)) { $d .= fgets($fp, 4096); } fclose(); echo $d; } ?>
抓到的http请求、响应数据包如下:
#
T 192.168.0.98:2400 -< 192.168.0.8:8080 [AP]
GET /p1.php HTTTP/1.1..
Host: 192.168.0.8..Cookie: PHPSESSID=dk7655dqrm5m884c9nitfi7j00..
Connection: close….
##
T 192.168.0.8:8080 -< 192.168.0.98:2400 [AP]
HTTP/1.1 200 OK..Date: Mon, 12 Apr 2010 09:03:09 GMT..Server: Apache/2.2.3 (CentOS)..X-Powered-By: PHP/5.1.6..Expires: T
hu, 19 Nov 1981 08:52:00 GMT..Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0..Pragma: no-
cache..Content-Length: 11..Connection: close..Content-Type: text/html; charset=UTF-8….hello world
##
上面的session_id是用户端伪造的一个值,它并不实际存在。收到这样的请求,服务端并没有检查,而是以这个session_id创建了相应的
session文件。并且,从httpd响应头部信息来看,并没给用户端分配session
id(没有Set-Cookie)。由此,我们可以推断:只要http请求头部包含了以session_name()作为键值的Cookie,那么服务端
就不认为用户是第一次访问web,亦不会给客户端分配session_id。否则,分配新的session_id,并通过Set-Cookie要求浏览器
创建该Cookie.
我们再来观察一下,通过session_regenerate_id()函数给用户分配一个新的session_id的情况
<?php //@file: p2.php session_start(); session_regenerate_id(); ?>
抓取到的http数据包如下
####
T 192.168.0.98:2763 -< 192.168.0.8:8080 [AP]
GET /p2.php HTTP/1.1..Host: 192.168.0.8:8080..Connection: keep-alive..User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.
1; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.3 Safari/533.2..Cache-Control: max-age=0..Accept: applica
tion/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5..Accept-Encoding: gzip,deflate,sdch.
.Accept-Language: zh-CN,zh;q=0.8..Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3..Cookie: PHPSESSID=bk7655dqrm5m884c9nitfi7j00
.
… ##
T 192.168.0.8:8080 -< 192.168.0.98:2763 [AP]
HTTP/1.1 200 OK..Date: Mon, 12 Apr 2010 11:39:10 GMT..Server: Apache/2.2.3 (CentOS)..X-Powered-By: PHP/5.1.6..Expires: T
hu, 19 Nov 1981 08:52:00 GMT..Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0..Pragma: no-
cache..Set-Cookie: PHPSESSID=f7q6jfdug4ekfsjhop6jftgna7; path=/
..Content-Length: 0..Connection: close..Content-Type: tex
t/html; charset=UTF-8…. ##
上面可以观察得到,http请求头Cookie部分带了session
id,并且这个session_id还是用户第一次访问web时被分配得到的。这一次,http响应头跟第二次示例http响应有些不一样,而是像第一次
访问那样通过Set-Cookie去要求用户端浏览器更新用户的session
id。这意味着:session_genrate_id()给用户端重新生成的session id也是通过Cookie的方法传递。
上图正好说明了这个过程:
1,User01和User02第一次去访问/p1.php,分别被分配了一个session id。
2,User01和User02第二次访问web,都会使用由/p1.php分配的session_id
3,User01因为访问了/p2.php,脚本/p2.php中的session_regenerate_id()给用户User01重新分配了一个新
session_id,从用户User01第4次访问的session_id就可以看得出来,与前面几几次的session_id不同了。
4,User02因为没有访问/p2.php,也就没有被服务端重新分配session id,一下沿用着上一次分配的session_id
与session id传递的有关的php.ini设置
1,session.use_cookie = 1
是否采用Cookie方法传递session id值。默认是1,表示启用。
2,session.name = PHPSESSID
不管是Cookie传递sessioin_id,还是GET方法传递session_id,都需要使用键值。他们的格式分别是Cookie:
sess_name=session_id;和/path.php?sess_name=session_id,其中sess_name就是由这里指定
的。
3,session.use_only_cookies = 0
表示只使用Cookie 的方法传递session
id。我们说过,传递cookie的方法,除了cookie,还有GET方法,GET方法是不安全的方法。在用户端禁用了cookie的时候,会采用
GET方法传递session_id,可以通过这个设置尽用GET方法传递session_id。
4,session.cookie_lifetime = 0, session.cookie_path = / 以及session.cookie_domain =
如果使用Cookie方法传递session_id的话,这里分别指定了cookie有效域、目录和时间。分别对应setcookie()函数的形
参$expire、$path和$domain。其中cookie_lifetime=0表示直到关闭浏览器才删除Cookie。还可以使用
session_set_cookie_params()函数修改这些值。
5,session_name([string $name])
获取或更新session_name。如果传了name,则表示不使用默认的名称PHPSESSID(由session.name)指定,否则获取当前
session_name。注意:如果设置session_name,则必须在session_start()之前调用才生效。
6,session_id([string $id])
与session_name()类似,但它是读取或者设置session_id的方法。同样,设置session_id的话,必须在session_start()之前调用才有效。
7,session_set_cookie_params()和session_get_cookie_params()
通过session_set_cookie_params()可以重新设定session.cookie_lifetime,
session.cookie_path以及session.cookie_domain这三个php.ini设置。而
session_get_cookie_params()则是获取这些设定的值。
Session回收
通过上文几节介绍,我们知道session数据存放在服务端指定的session.save_path目录中,同时会在用户端存放一条Cookie用以记录分配给用户的session id。所以,session数据失效分服务端和客户端,要删除(回收)的对象也很清楚:
1,服务端:删除过期的session文件,启动PHP GC回收。
2,用户端:使存储了过期session_id的用户端Cookie记录过期。通过将Cookie的Expire设置为负值,要求客户端删除Cookie。
服务端:删除过期的session文件
PHP
GC进程被启动以后,则会扫描session.save_path,找出过期的session,并删除该session文件。所谓,过期的
session,是指操作系统当前时间与session文件最后访问时间之差大于session.gc_maxlifetime的话,该session认
为是过期了。注意:有时候,你会发现,即便是文件过期了,有可能也没有被及时地删除掉。这是因为,每次session初始化的时候,并不会都启动PHP
GC进程的,启动GC进程会大大降低php的运行效率。所有一个启动概率,这个概率由php.ini设定session.gc_probability /
session.gc_divisor二个设置决定,默认概率是1%(1/1000)。这意味着,每1000次用户请求中,会启动1次PHP
GC回收session文件。比如,我们下面看到的,过期的session文件依然存在:
# date;find /var/lib/php/session -type f -atime -1440 -print |xargs ls -lt Tue Apr 13 10:10:37 CST 2010 -rw------- 1 apache apache 0 Apr 12 20:01 /var/lib/php/session/sess_5tlaq5a8im3ob1bikn62motpv7 -rw------- 1 apache apache 0 Apr 12 19:39 /var/lib/php/session/sess_f7q6jfdug4ekfsjhop6jftgna7 -rw------- 1 apache apache 0 Apr 12 17:03 /var/lib/php/session/sess_dk7655dqrm5m884c9nitfi7j00
我们可以通过编辑设置,来验证启动php session的GC机制
<?php //@file session_gc.php ini_set("session.gc_probability", 100); ini_set("session.gc_divisor", 100); ini_set("session.gc_maxlifetime", 1440); session_start(); ?>
[root@localhost ~]# strace -p `cat /var/run/httpd.pid`
open("/var/www/html/session_gc.php", O_RDONLY) = 17
fstat64(17, {st_mode=S_IFREG|0644, st_size=144, ...}) = 0
lseek(17, 0, SEEK_CUR) = 0
brk(0x8d35000) = 0x8d35000
read(17, "<?php\nini_set(\"session.gc_probab"..., 8192) = 144
read(17, "", 8192) = 0
read(17, "", 8192) = 0
close(17) = 0
open("/var/lib/php/session/sess_5tlaq5a8im3ob1bikn62motpv7", O_RDWR|O_CREAT, 0600) = 17
flock(17, LOCK_EX) = 0
fcntl64(17, F_SETFD, FD_CLOEXEC) = 0
fstat64(17, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
open("/var/lib/php/session", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY) = 18
fcntl64(18, F_SETFD, FD_CLOEXEC) = 0
time(NULL) = 1271125492
getdents(18, /* 13 entries */, 32768) = 516
stat64("/var/lib/php/session/sess_bk7655dqrm5m884c9nitfi7j00", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
unlink("/var/lib/php/session/sess_bk7655dqrm5m884c9nitfi7j00") = 0
stat64("/var/lib/php/session/sess_4j38nv7l1fq1bj6n80l6g9cum5", {st_mode=S_IFREG|0600, st_size=11, ...}) = 0
unlink("/var/lib/php/session/sess_4j38nv7l1fq1bj6n80l6g9cum5") = 0
stat64("/var/lib/php/session/sess_n660qmcl38solbmp7vkhafqg17", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
unlink("/var/lib/php/session/sess_n660qmcl38solbmp7vkhafqg17") = 0
stat64("/var/lib/php/session/sess_5tlaq5a8im3ob1bikn62motpv7", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
unlink("/var/lib/php/session/sess_5tlaq5a8im3ob1bikn62motpv7") = 0
stat64("/var/lib/php/session/sess_qoa6knu9fg77un8le99o1vk1c7", {st_mode=S_IFREG|0600, st_size=31, ...}) = 0
unlink("/var/lib/php/session/sess_qoa6knu9fg77un8le99o1vk1c7") = 0
stat64("/var/lib/php/session/sess_dutbc682k3h4cgho2sgugc0id4", {st_mode=S_IFREG|0600, st_size=23, ...}) = 0
unlink("/var/lib/php/session/sess_dutbc682k3h4cgho2sgugc0id4") = 0
stat64("/var/lib/php/session/sess_vp8lfqnskjvsiilcp1c4l484d3", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
unlink("/var/lib/php/session/sess_vp8lfqnskjvsiilcp1c4l484d3") = 0
stat64("/var/lib/php/session/sess_dk7655dqrm5m884c9nitfi7j00", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
unlink("/var/lib/php/session/sess_dk7655dqrm5m884c9nitfi7j00") = 0
stat64("/var/lib/php/session/sess_f7q6jfdug4ekfsjhop6jftgna7", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
unlink("/var/lib/php/session/sess_f7q6jfdug4ekfsjhop6jftgna7") = 0
getdents(18, /* 0 entries */, 32768) = 0
close(18) = 0
chdir("/var/lib/php/session") = 0
pwrite64(17, "", 0, 0) = 0
close(17) = 0
setitimer(ITIMER_PROF, {it_interval={0, 0}, itvalue={0, 0}}, NULL) = 0
writev(16, [{"HTTP/1.1 200 OK\r\nDate: Tue, 13 A"..., 327}], 1) = 327
write(12, "192.168.0.98 - - [13/Apr/2010:10"..., 205) = 205
shutdown(16, 1 /* send */) = 0
从上面蓝色部分可以看出,通过用stat64检查session文件的状态,如果发现过期了,则会通过调用系统内核函数ulink()删除过期的 session文件。可见,session初始化的时候会启动GC, GC会扫描session.save_path中的所有session文件,查看他们状态并且将过期的文件删除。正因为如此,所以默认设置启动的概率是 1/1000。
客户端:删除过期session id的cookie记录
如果用户发现session已经过期,但是服务端的GC还没有启动,服务端可以手通过手工代码setcookie的方式要求用户端浏览器删除键值为
session_name()的Cookie记录。这样,下回访问的时候,浏览器以为用户是第一次访问,并且重新给访问用户分配一个新的
session_id。较好的做法类似这样:
<?php //@file session_destroy.php session_start(); $sess_name = session_name(); $sess_id = session_id(); list(, $path, $domain, ,) = session_get_cookie_params(); if ($sess_name && isset($_COOKIE[$sess_name])) { setcookie($sess_name, '', -1, $path, $domain); if ($sess_id) { session_destroy(); } } ?>
抓取的http数据包如下:
#
T 192.168.0.98:2638 -< 192.168.0.8:8080 [AP]
GET /session_destroy.php HTTP/1.1..Host: 192.168.0.8:8080..Connection: keep-alive..User-Agent: Mozilla/5.0 (Windows; U;
Windows NT 5.1; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.3 Safari/533.2..Accept: application/xml,appl
ication/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5..Accept-Encoding: gzip,deflate,sdch..Accept-Langu
age: zh-CN,zh;q=0.8..Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3..Cookie: PHPSESSID=rjdtgvmueggplgqno66qlfket1....
##
T 192.168.0.8:8080 -< 192.168.0.98:2638 [AP]
HTTP/1.1 200 OK..Date: Tue, 13 Apr 2010 07:08:24 GMT..Server: Apache/2.2.3 (CentOS)..X-Powered-By: PHP/5.1.6..Expires: T
hu, 19 Nov 1981 08:52:00 GMT..Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0..Pragma: no-
cache..Set-Cookie: PHPSESSID=deleted; expires=Mon, 13-Apr-2009 07:08:23 GMT..
Content-Length: 222..Connection: close..Con
tent-Type: text/html; charset=UTF-8....
##
T 192.168.0.98:2642 -< 192.168.0.8:8080 [AP]
GET /p1.php HTTP/1.1..Host: 192.168.0.8:8080..Connection: keep-alive..User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.
1; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.3 Safari/533.2..Accept: application/xml,application/xhtml
+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5..Accept-Encoding: gzip,deflate,sdch..Accept-Language: zh-CN,zh
;q=0.8..Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3....
##
T 192.168.0.8:8080 -< 192.168.0.98:2642 [AP]
HTTP/1.1 200 OK..Date: Tue, 13 Apr 2010 07:09:15 GMT..Server: Apache/2.2.3 (CentOS)..X-Powered-By: PHP/5.1.6..Set-Cookie
: PHPSESSID=lbmk3sc5a88e9cjuekr0aa9pc3; path=/..Expires: Thu, 19 Nov 1981 08:52:00 GMT..Cache-Control: no-store, no-cach
e, must-revalidate, post-check=0, pre-check=0..Pragma: no-cache..Content-Length: 11..Connection: close..Content-Type: te
xt/html; charset=UTF-8....hello world
##
上面观察可以知道,通过访问/session_destroy.php,它要求客户端将session_id的Cookie记录删除。而接下来访问
/p1.php的时候,http请求头没有通过Cookie将用户的session
id带给服务器(因为刚被要求删除)。而第二次请求/p1.php的http响应里头可以看到,服务端又给用户重新分配了一个新的session
id,而且不会继续使用过去的session数据。
与session回收相关的php.ini设置:
1, session.gc_probability和session.gc_divisor
由这二个函数决定了启用GC的概率,默认是1/1000。也就是说,每一千次用户请求中有一次会启动GC回收session。启动GC进程不宜过于频繁。
上面的例子,我们可以看到,它会每次检查session.save_path目录下每个文件的状态。这样会降低php的执行效率。
2, session.gc_maxlifetime = 1440
设置session存活时间,单位是秒。每次GC启动后, 会通过stat得到session文件最后访问的unix时间,通过现在时间减去文件最后访问时间之间大于session.gc_maxlifetime,则会删除该文件。
总结
1,PHP使用Cookie的方法传递session id。尽量不要使用GET方法传递session id,因为这样很不安全。
2,可以通过setcookie()的方法,将客户端的session id的Cookie记录删除。
3,PHP GC进程由session初始化启动。但不是每一次用户请求都会被启动,它的启动概率默认是1/1000。过于频繁访问的网站,并发量大的网站,可减小PHP GC的启动频率。PHP GC回收session会降低php的执行效率。
4,通过下面代码,优化session回收
<?php session_start(); if (isset($_SESSION['SESS_TIMEOUT'])) { if ($_SERVER['REQUEST_TIME'] > $_SESSION['SESS_TIMEOUT']) { setcookie(session_name(), session_id(), -1, '/'); session_unset(); session_destroy(); } } else { $_SESSION['SESS_TIMEOUT'] = $_SERVER['REQUEST_TIME'] + 3600; } ?>
发表评论
-
PHP实现双向链表
2013-10-21 10:12 679<?php /** * **双向链表 ... -
php=操作符的优先级问题
2013-09-06 16:07 735$a = '1'; $b = '2'; $c = ... -
php-gtk to exe
2013-07-15 15:48 680以前PHP被认为只能用来编写服务器端的CGI程序,如果说PHP ... -
PHP 类型及比较符表
2013-02-22 18:13 644<!--[if gte mso 9]><x ... -
xhprof安装&&使用
2013-01-04 11:24 760编译安装 wget http://pecl.php ... -
PHP变量的存储方式
2012-11-16 18:18 1277当用户在PHP中调用一个 ... -
【转】PHP通过接口实现多重继承
2012-11-06 11:41 707PHP类虽然是单继承的,但是可以通过其它特殊的方式实现多重 ... -
【社区开学季】Php提升效率优化技巧
2012-10-16 10:29 652确实很有用的,大家平常开发中应该注意下 0、用单引号代替双引 ... -
为什么$row[’id’] 的速度是$row[id]的7倍
2012-10-16 10:06 1296$row[’id’] 的速度是$row[id]的7倍 ... -
PHP true
2012-08-08 17:35 1$arr = true; if ($arr == -1) { ... -
[转]PHP5 Session 浅析I
2012-05-10 11:21 992http协议是WEB服务器与客户端(浏览器)相互通信的协议,它 ... -
PHP的__FUNCTION__与__METHOD__的不同
2012-03-02 10:54 688使用__FUNCTION__仅传回函数名称 使用__METH ...
相关推荐
本文在PHP中利用MD5()函数对Session值以及SessionID值进行Hash处理,确切地说,是在SessionID值的储存机制上添加了MD5算法,作了一些浅析,相信在Session安全防范方面会起到一定的作用。 MD5算法与Session Hash ...
PHP的Session反序列化漏洞问题,主要是因为不当的Session使用和不安全的反序列化操作,可能造成未授权访问、数据泄露甚至远程代码执行等安全风险。 首先,了解PHP的Session管理机制是非常重要的。在php.ini配置文件...
在PHP分布式环境中,Session管理是不可或缺的一环,它涉及到用户状态的保持和跨服务器的数据共享。Redis作为一种高性能的键值数据库,常被用于分布式环境下的Session存储,以解决传统文件或数据库Session管理的问题...
在进行Web应用程序开发的时候,人们经常会用Session存储数据。但可能有人不知道,在PHP中,Session使用不当可能会引起并发问题。印度医疗行业软件解决方案提供商Plus91 Technologies高级工程师Kishan Gor在个人博客...
PHP 中 i++ 和 ++i 的区分及效率浅析 PHP 中的 i++ 和 ++i 都是递增运算符,但它们的执行顺序和返回值不同。 i++ 运算符 i++ 运算符是后缀递增运算符,它的执行顺序如下: 1. 返回当前变量的值 2. 将变量的值加 ...
PHP开发者在实际应用中,可以通过设置HTTP头来控制Cookies和Session的行为,比如使用`setcookie()`函数创建Cookies,使用`session_start()`启动Session,`$_SESSION`数组存储Session数据。同时,通过`header()`函数...
5. **使用最新版本的PHP**:定期更新PHP版本以获取最新的安全补丁。 6. **代码审计**:定期审查代码,查找和修复安全漏洞。 总的来说,提高PHP程序的安全性需要开发者对每个环节都保持警惕,从代码编写到部署维护,...
"浅析 PHP 博客管理系统的设计与实现" 本文主要介绍了基于 PHP 的博客管理系统的设计与实现。该系统采用 PHP+MySQL+Apache 技术架构,实现了博客管理系统的开发。系统分为三个模块:游客、普通用户和超级用户。每个...
4. **超全局(Superglobal)变量**:这些变量在整个脚本中始终可用,无论当前作用域如何,如`$_GET`、`$_POST`、`$_SESSION`等。它们在PHP 4.1.0版本后引入,不需要`global`关键字即可在函数内部使用。 了解这些...
- **XSS防护**:使用HTTP头部的Content-Security-Policy(CSP)来限制浏览器执行的脚本源,对输出内容进行HTML实体编码,启用HTTP-only cookies以保护session信息不被JavaScript访问。 3. 其他安全实践 - **使用...
### JSP安全编程实例浅析 #### 一、引言 在现代Web开发中,JavaServer Pages (JSP)作为一种动态网页技术被广泛应用于构建复杂的企业级应用。然而,随着互联网的发展,各种针对Web应用程序的安全威胁也日益增多。...
5. **局部变量**:函数内部定义的变量是局部的,只在函数执行期间存在,函数执行结束后,变量会被销毁。 理解变量和常量的作用域至关重要,因为这决定了它们在代码中的可见性和生命周期。在函数内部定义的变量仅在...
```php $model = M('MyTable'); $result = $model->execute('update MyTable set name=aaa where id=11'); // 将返回更新的行数 ``` 在这个例子中,`execute()` 返回的是被更新的记录数,即 `UPDATE` 语句影响的...
**浅析AJAX乱码及错误解决方案** 在当前的网络环境中,JavaScript被广泛应用于网页交互,而AJAX技术更是让动态加载数据变得无处不在。然而,由于编码规范的不一致,尤其是在各种浏览器环境中,经常会出现乱码和...
3. **核心类库加载**:引入必要的系统类库,如session、url、cache等。 4. **路由分发**:根据URL解析用户请求,分发到相应的控制器和方法处理。 5. **模板渲染**:渲染并输出最终的HTML页面。 四、模块开发目录...