php 获取其他页面的cookie_互联网系统(APP、网站等)通信基石——会话(PHP版)...

一、会话概述

1.1、技术背景

互联网通信中采用的Http协议(建立TCP连接->Http请求->Http应答->断开TCP连接)本身是无状态的,即Http各请求之间是相互独立、互不相关的,而大量应用需要将各请求关联起来(如:用户登录系统购物、多次购买行为需要与该用户绑定),因此需要有一种机制实现Http各请求之间的关联

1.2、会话定义

用户端与服务端进行网络通信,用户从登录进入系统到注销退出系统,这一完整过程称为会话(Session);会话中,用户端与服务端进行的一序列通信处理(Http请求与应答)将始终与登录的具体用户相关联

1.3、实现原理

服务端收到用户端Http请求后,先从Http请求包中获取会话ID(如果没有,将自动生成一个会话ID),根据会话ID在内存中生成对应的散列表(如:PHP中的$_SESSION[])、检索上次保存的会话记录(如果检索不到,将自动生成一条与该会话ID绑定的空会话记录),将会话记录中的数据加载到散列表,通过散列表读写当前会话数据,最后请求处理结束时将散列表中的会话数据保存为会话记录、脚本结束时将当前的会话ID放入Http应答包发送给用户端(供下次Http请求使用)

二、会话ID的传递

从上述会话实现原理可知,会话ID将一序列Http数据包(请求/应答)关联起来,从而构成一个完整的会话,整个会话过程中需要在用户端与服务端通过Http数据包传递会话ID,具体传递方式有:Cookie方式传递、URL参数方式传递、数据内容方式传递,具体如下

2.1、Cookie方式传递

2.1.1、传递原理

Http请求过程:

用户端(如:浏览器)先从本地(内存或磁盘)读取保存的对应Cookie数据(名称、值、域名等),再将读取到的相应数据填写到Http请求数据包头的Cookie字段(首次请求时,由于本地无Cookie数据,该字段为空),而后将Http请求数据包发送到服务端;服务端收到Http请求数据包后解析时,将根据当前的会话名称匹配对应的Cookie名称,如果匹配到了、则读取对应的值(会话ID)作为当前的会话ID,如果匹配不到、将自动生成一个当前的会话ID;该过程中,用户端从本地读取保存的Cookie原则为:Cookie所声明的作用范围(由其路径与域共同决定)大于等于将要请求的资源所在的位置

Http应答过程:

服务端先将当前的会话名称、会话ID等数据分别填入Http应答数据包头的Cookie字段,而后将Http应答数据包发送到用户端;用户端收到Http应答数据包进行解析,再将解析得到的Cookie数据(名称、值、域名等)进行保存(至于保存到内存还是磁盘,由具体的程序设计决定,一般原则为:如果Cookie设置了有效时间,就保存到磁盘,否则将保存到内存)

2.1.2、环境配置

用户端配置:

使用Cookie方式传递时,用户端必须开启Cookie的接受与发送功能,否则将不能实现该传递功能;不同用户端开启的方法不一样,以下为IE浏览器开启Cookie接受与发送功能的相关步骤:

菜单栏“工具”->“Internet选项”->“隐私”->“选择Internet区域设置”->选择“接受所有Cookie”->点“确定”关闭

服务端配置:

使用Cookie方式传递时,服务端必须开启Cookie的接受与发送功能(一般默认为开启状态),否则将不能实现该传递功能;开启方法如下:

方法1:配置文件“php.ini”中的“session.use_cookies”配置项设置为“1”->重新启动服务器(如:Apache)

方法2:用ini_set()函数直接在PHP脚本中将“session.use_cookies”配置项设置为“1”

2.1.3、案例演示

创建如下PHP脚本文件(ByCookie.php):

/*

* ByCookie.php

*/

//打开错误及告警提示(不打开E_NOTICE,否则下面使用$_SESSION会有告警)

error_reporting((E_ALL | E_STRICT) & (~E_NOTICE));

//error_reporting(E_ALL | E_STRICT);

//设置会话名称

session_name('TransID');

//启动新会话或者重用现有会话

$startRst = session_start();

if (!$startRst)

{

echo 'Session start fail!'.'
';

return ;

}

//获取当前会话名称

$sessName = session_name();

echo 'session name:'.$sessName.'
';

//获取当前会话ID

$sessId = session_id();

echo 'session id:'.$sessId.'
';

//读写当前会话数据

echo 'Last request,session data:'.$_SESSION['count'].'
';

if (empty($_SESSION['count']))

{

$_SESSION['count'] = 1;

}

else

{

$_SESSION['count']++;

}

echo 'This request,session data:'.$_SESSION['count'].'
';

?>

在浏览器中用多个页面顺序打开上述“ByCookie.php”文件多次,便可以看到被多次传递的同一个会话ID及相关数据,结果如下:

9903ff4db9ecdb6fa5788162cc0c40dc.png
473c7ae45855befcf0220ad70d86629b.png

2.2、URL参数方式传递

2.2.1、传递原理

首次请求时,服务端将当前的会话名称及会话ID放入Http应答数据包响应正文(作为参数附加到URL后)中发送到用户端;用户端通过URL触发连接请求(如:点击链接或提交表单)时,会话名称及会话ID被填写到Http请求数据包头的URL字段(作为参数附加到URL后),而后将Http请求数据包发送到服务端;服务端收到Http请求数据包后,通过$_GET[]全局变量即可得到请求数据包头URL字段中的参数(会话名称及会话ID);如果还有需要,服务端再将会话名称及会话ID放入Http应答数据包响应正文(作为参数附加到URL后)中发送到用户端、供用户端再次通过URL触发连接请求

2.2.2、案例演示

在同一目录下创建如下2个PHP脚本文件(ByURLSend.php及ByURLRcve.php):

文件1(ByURLSend.php):

/*

* ByURLSend.php

*/

//打开错误及告警提示(不打开E_NOTICE,否则下面使用$_SESSION会有告警)

error_reporting((E_ALL | E_STRICT) & (~E_NOTICE));

//error_reporting(E_ALL | E_STRICT);

//设置会话名称

session_name('TransID');

//启动新会话或者重用现有会话

$startRst = session_start();

if (!$startRst)

{

echo 'Session start fail!'.'
';

return ;

}

//获取当前会话名称

$sessName = session_name();

echo 'session name:'.$sessName.'
';

//获取当前会话ID

$sessId = session_id();

echo 'session id:'.$sessId.'
';

//读写当前会话数据

echo 'Last request,session data:'.$_SESSION['count'].'
';

if (empty($_SESSION['count']))

{

$_SESSION['count'] = 1;

}

else

{

$_SESSION['count']++;

}

echo 'This request,session data:'.$_SESSION['count'].'
';

?>

==session_id();?>">URL参数方式传递(方法1)

">URL参数方式传递(方法3)

文件2(ByURLRcve.php):

/*

* ByURLRcve.php

*/

//打开错误及告警提示(不打开E_NOTICE,否则下面使用$_SESSION会有告警)

error_reporting((E_ALL | E_STRICT) & (~E_NOTICE));

//error_reporting(E_ALL | E_STRICT);

//设置会话名称

session_name('TransID');

//获取当前会话名称

$sessName = session_name();

//获取当前会话ID

$sessId = $_GET[$sessName];

if ('' == $sessId)

{

echo 'Session id transmits fail!'.'
';

return ;

}

//设置当前会话ID

session_id($sessId);

//启动新会话或者重用现有会话

$startRst = session_start();

if (!$startRst)

{

echo 'Session start fail!'.'
';

return ;

}

//获取当前会话名称

$sessName = session_name();

echo 'session name:'.$sessName.'
';

//获取当前会话ID

$sessId = session_id();

echo 'session id:'.$sessId.'
';

//读写当前会话数据

echo 'Last request,session data:'.$_SESSION['count'].'
';

if (empty($_SESSION['count']))

{

$_SESSION['count'] = 1;

}

else

{

$_SESSION['count']++;

}

echo 'This request,session data:'.$_SESSION['count'].'
';

?>

在浏览器中打开“ByURLSend.php”,便能看到如下结果:

c1a58698fbe3bdc62d81af07f7153e8e.png

点击不同的链接,便可以看到在不同页面间传递的同一个会话ID及相关数据

6800c04e8cea346d3f0fd675d6693d6e.png

2.3、数据内容方式传递

2.3.1、传递原理

首次请求时,服务端将当前的会话名称及会话ID放入Http应答数据包响应正文(通常以字段值的方式放置)中发送到用户端;用户端通过POST方法触发Http请求时,会话名称及会话ID作为Http请求数据包的请求数据发送到服务端;服务端收到Http请求数据包后,直接解析Http请求数据包的请求数据即可得到会话名称及会话ID;如果还有需要,服务端再将会话名称及会话ID放入Http应答数据包响应正文(通常以字段值的方式放置)中发送到用户端、供用户端再次POST方法触发Http请求

2.3.2、案例演示

在同一目录下创建如下2个PHP脚本文件(ByDataSend.php及ByDataRcve.php):

文件1(ByDataSend.php):

/*

* ByDataSend.php

*/

//打开错误及告警提示(不打开E_NOTICE,否则下面使用$_SESSION会有告警)

error_reporting((E_ALL | E_STRICT) & (~E_NOTICE));

//error_reporting(E_ALL | E_STRICT);

//设置会话名称

session_name('TransID');

//重用现有会话;

$startRst = session_start();

if (!$startRst)

{

echo 'Session start fail!'.'
';

return ;

}

//获取当前会话名称

$sessName = session_name();

echo 'session name:'.$sessName.'
';

//获取当前会话ID

$sessId = session_id();

echo 'session id:'.$sessId.'
';

//读写当前会话数据

echo 'Last request,session data:'.$_SESSION['count'].'
';

if (empty($_SESSION['count']))

{

$_SESSION['count'] = 1;

}

else

{

$_SESSION['count']++;

}

echo 'This request,session data:'.$_SESSION['count'].'
';

?>

文件2(ByDataRcve.php):

/*

* ByDataRcve.php

*/

//打开错误及告警提示(不打开E_NOTICE,否则下面使用$_SESSION会有告警)

error_reporting((E_ALL | E_STRICT) & (~E_NOTICE));

//error_reporting(E_ALL | E_STRICT);

//设置会话名称

session_name('TransID');

//获取当前会话名称

$sessName = session_name();

//获取当前会话ID

$sessId = $_POST[$sessName];

if ('' == $sessId)

{

echo 'Session id transmits fail!'.'
';

return ;

}

//设置当前会话ID

session_id($sessId);

//重用现有会话;

$startRst = session_start();

if (!$startRst)

{

echo 'Session start fail!'.'
';

return ;

}

//获取当前会话名称

$sessName = session_name();

echo 'session name:'.$sessName.'
';

//获取当前会话ID

$sessId = session_id();

echo 'session id:'.$sessId.'
';

//读写当前会话数据

echo 'Last request,session data:'.$_SESSION['count'].'
';

if (empty($_SESSION['count']))

{

$_SESSION['count'] = 1;

}

else

{

$_SESSION['count']++;

}

echo 'This request,session data:'.$_SESSION['count'].'
';

?>

在浏览器中打开“ByDataSend.php”,便能看到如下结果:

63ab7e52892dbb9b4bde58bdc65563c3.png

点击“数据内容方式传递”按钮,便可以看到在不同页面间传递的同一个会话ID

d57fa961b3bf77b759ea0d798295ffbb.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值