PHP session 与 cookie 自己的研究成果

理清了cookie与session之间的调用逻辑。

session_start()

在a.php加入:

$_SESSION['a']=”a”;
echo $_SESSION['a'];

在游览器里运行a.php,查看头信息:

请求:

GET /a.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: Hm_lvt_2ce2628c9a3dcbc8164433b1cc152d3e=1433243616
Connection: keep-alive
Cache-Control: max-age=0

返回:

HTTP/1.1 200 OK
Date: Wed, 22 Jul 2015 03:18:52 GMT
Server: Apache/2.4.10 (Ubuntu)
Content-Length: 1
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

可以看到,第一次访问该页面时,如果没有使用 session_start(),则什么都不会发生,游览器给服务器的请求中的 Cookie: Hm_lvt_2ce2628c9a3dcbc8164433b1cc152d3e=1433243616 与我们的服务器没有任何关系。

现在在a.php中加入 sesion_start() 后查看头信息:

请求:

GET /a.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: Hm_lvt_2ce2628c9a3dcbc8164433b1cc152d3e=1433243616
Connection: keep-alive
Cache-Control: max-age=0

返回:

HTTP/1.1 200 OK
Date: Wed, 22 Jul 2015 03:29:45 GMT
Server: Apache/2.4.10 (Ubuntu)
Set-Cookie: PHPSESSID=pp0j7k2mbst4ejtdnt1vrilt70; path=/
Expires: Thu, 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
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

可以看到,当我们使用了 session_start() 后,服务器会先检查是否在这次回话之前有用过session,如果没有,就会在返回的头信息中加入 Set-Cookie: PHPSESSID=pp0j7k2mbst4ejtdnt1vrilt70; path=/ 来告诉游览器,我需要用到cookie

并且如果使用php默认的session设置的话,就会在默认的路径穿件一个以 PHPSESSID 为名称的文件:

Picture1.png

我们查看一下文件内容,会发现此时没有任何内容:

Picture2.png

session_encode() 和 session_decode()

现在我们已经开启了session,接下来就是往session里放点数据:

<?php
session_start();
$_SESSION['ss']="a";
echo $_SESSION['ss'];
?>

执行一下a.php,查看头部信息:

请求:

GET /a.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: Hm_lvt_2ce2628c9a3dcbc8164433b1cc152d3e=1433243616; PHPSESSID=pp0j7k2mbst4ejtdnt1vrilt70
Connection: keep-alive
Cache-Control: max-age=0

返回:

HTTP/1.1 200 OK
Date: Wed, 22 Jul 2015 03:33:18 GMT
Server: Apache/2.4.10 (Ubuntu)
Expires: Thu, 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: 1
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

这次我们看到游览器的请求中给 Cookie 参数加上了刚才服务器返回的 Set-Cookie 参数 :

Cookie: Hm_lvt_2ce2628c9a3dcbc8164433b1cc152d3e=1433243616; PHPSESSID=pp0j7k2mbst4ejtdnt1vrilt70

当服务器收到请求中发现头部的 Cookie 参数里有对应的 session_id 就会去去读改文件,这时候我们看下这个sesion文件的内容:

Picture3.png

其实文件的内容就是 session_encode() 的结果,该函数会将$_SESSION变量进行 serialize() 操作。而 session_decode() 就是对session文件内容进行 unserialize() 操作。

让我们再试一次,修改a.php:

<?php
session_start();
$_SESSION['ss']="a";
$_SESSION['ss1']=100;
$_SESSION['aa3']=array("a1"=>1,"a2"=>"fds");
$_SESSION['o1']=new A();

class A{
  public $b1="1";
  public function aa(){
    return "11";
  }
}
?>

运行后查看session文件内容:

Picture4.png

$_SESSION['ss']="a";                                                 ss|s:1:”a”;
$_SESSION['ss1']=100;                                                ss1|i:100;
$_SESSION['aa3']=array("a1"=>1,"a2"=>"fds");     aa3|a:2{s:2:"a1";i:1;s:2:"a2";s:3:"fds";}
$_SESSION['o1']=new A();                o1|O:1:"A":1:{s:2:"b1";s:1:"1";}

session_id()

修改a.php:

<?php
echo session_id("11111");
session_start();
$_SESSION['ss']="a11";
?>

执行后查看头信息:

请求:

GET /a.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: Hm_lvt_2ce2628c9a3dcbc8164433b1cc152d3e=1433243616; PHPSESSID=11111
Connection: keep-alive
Cache-Control: max-age=0

返回:

HTTP/1.1 200 OK
Date: Wed, 22 Jul 2015 03:55:15 GMT
Server: Apache/2.4.10 (Ubuntu)
Set-Cookie: PHPSESSID=11111; path=/
Expires: Thu, 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
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

注意 Set-Cookie: PHPSESSID=11111; path=/ , 可以看到 session_id() 的作用就是设置 CookiePHPSESSID的值

session_name()

修改a.php:

<?php
session_name("好人");
session_start();
?>

返回:

HTTP/1.1 200 OK
Date: Wed, 22 Jul 2015 04:02:24 GMT
Server: Apache/2.4.10 (Ubuntu)
Set-Cookie: %E5%A5%BD%E4%BA%BA=mpggc83j5v5ctek870r7f6kql6; path=/
Expires: Thu, 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
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

注意 Set-Cookie: %E5%A5%BD%E4%BA%BA=mpggc83j5v5ctek870r7f6kql6; path=/ ,可以看到 session_name()就是替换前面 PHPSESSID 这个的名称。

查看下这个session文件:

Picture5.png

session_unset() 和 session_destroy()

修改a.php,调用一下 session_unset() 函数:

<?php
session_name("好人");
session_start();
$_SESSION['ss']="a11";
$_SESSION['ss1']=100;
$_SESSION['aa3']=array("a1"=>1,"a2"=>"fds");
$_SESSION['o1']=new A();
session_unset();
class A{
  public $b1="1";
  public function aa(){
    return "11";
  }
}
?>

查看下session文件:

Picture6.png

发现文件还在,但是内容没有了

修改a.php,调用一下 session_destroy() 函数:

<?php
session_name("好人");
session_start();
$_SESSION['ss']="a11";
$_SESSION['ss1']=100;
$_SESSION['aa3']=array("a1"=>1,"a2"=>"fds");
$_SESSION['o1']=new A();
echo $_SESSION['ss'];
session_destroy();
echo $_SESSION['ss'];
class A{
  public $b1="1";
  public function aa(){
    return "11";
  }
}
?>

执行后发现文件没有了:

Picture7.png

但是$_SESSION变量的内容还存在:

Picture8.png

这就是为什么我们如果要正真销毁session时,必须执行 session_unset()session_destroy() 的原因,一个将session删掉,一个将内存中的内容删掉,只执行其中一个并不能彻底删除session

PHP session流程

QQ20170210-173934.png

其他文献:

PHP session锁:如何避免session阻塞PHP请求

标签: php