在cakephp中用第三方程序读写session
cakephp无疑在很多方面限制都很多,无法用常规来理解其中的问题。关于session也是如此,在cakephp中,不但启用了session_id(和cookie的作用域功用很类似的东东),还设置了每10次页面请求,就从新生成新的session_id这一BT行为,让第三方程序读写cakephp的session有了非常大的障碍。感谢yoophi老师对本文的指点。
1、一点被忽略的php常识
php的session是默认生成一个session_id的,每次session_start都有一个新的id,一个session标示着一个session记录。而常规的程序中,一般只需要一个session_start()就行了,而cakephp中利用session_id()设置了id值,并动态改变。这使得我们在第三方程序中的session_start()之前就必须用session_id(CAKEPHP_SESSIONID)来进行加载。而这个cakephp_sessionid由于时刻在发生变化,也是无法用一个不变的常值来进行处理了。
2、cakephp中处理机制
cakephp中的session是由id区分的,而每次从新生成id后,他将这个值写入到了cookie中的cakephp值中,这就使得我们获得查看修改其中的变量成为可能。思路是,先用cookie取得id,然后在start,然后在进行修改。本文中的核心代码就2句话,懒得读文章的看这里就行了:
session_id($_COOKIE["CAKEPHP"]);
session_start();
3、一段我写的代码
<?
$task=trim($_GET["task"]);
$next_flag=intval($_GET["next"]);
$auth_config_file="auth.session";
$auto_vrl="/blog_front";
$login_vrl="/users/login";
switch($task){
case "init":
do_init($next_flag);
break;
default:
do_auto($next_flag);
break;
}
function do_auto($next_flag){
global $auth_config_file,$auto_vrl;
if ($next_flag<=0){
echo "
<iframe src='".$auto_vrl."' style='display:none;' onload='javascript:go();'></iframe>
<script>function go(){document.location='?next=1';}</script>";
}
else{
if($_COOKIE["CAKEPHP"]==""){echo "sorry,error!"; exit;}
session_id($_COOKIE["CAKEPHP"]);
session_start();
$_SESSION["Setting"]["language"]="chi";
$_SESSION["Setting"]["theme"]="Design";
if (file_exists($auth_config_file)){
$_SESSION["Auth"]["User"]=@unserialize(file_get_contents($auth_config_file));
}
header("Location:".$auto_vrl);
}
}
function do_init($next_flag){
global $auth_config_file,$auto_vrl,$login_vrl;
if ($next_flag<=0){
echo "
<iframe src='".$login_vrl."' style='width:100%;height:500px;' onload='javascript:go1();'></iframe>
<br/>
<input type='button' onclick='javascript:go2()' value='完成登录了!' />
<script>
function go1(){alert('请完成登陆操作后,按下完成按钮!');}
function go2(){document.location='?next=1&task=init';}</script>";
}
else{
if($_COOKIE["CAKEPHP"]==""){echo "sorry,error!"; exit;}
session_id($_COOKIE["CAKEPHP"]);
session_start();
file_put_contents($auth_config_file,serialize($_SESSION["Auth"]["User"]));
echo "<script>alert('done,下面对自动登录进行检验!');window.location='?next=0'</script>";
}
}
?>
4、一点点解释说明
4.1、这段代码一共实现了两个功能,一个是修改当前session信息,一个是自动保存auth组建的session信息,这样就可以对应频繁更换代码的情况了。代码体本身和cakephp绝缘,没有牵制。
4.2、当然这个代码要想获得cookie,必须放置到项目文件夹中,以期待cakephp中cookie能顺利读出,同时使用.htaccess来关掉rewrite功能。
4.3、在修改session信息功能中,对于开始的时候,加载个iframe的主要目的在于获取cookie中的cakephp值,否则将无法使用session_id,因为cakephp的cookie中Cakephp信息必须运行一次之后才能生成。
4.4、使用serialize和unserialize来保存数组信息,很方便使用。感谢rohu.com教我使用这2个很好用的函数。
4.5、本文中使用了file_put_contents和file_get_contents是php5中特有的函数,php4的用户要修改这2个地方的程序哦~,反正php4中的这2个函数写起来挺繁琐的。哈哈。
5、部分截图
自动登录完成的结果:
获取当前用户登陆信息并进行保存:
项目结构图:
本文来自苏南的博客, 转载请注明网址:http://newsn.net, 谢谢!
我的淘宝小店:http://68zz.com
我的Sina圈子:http://q.blog.sina.com.cn/pctalk

谢谢,苏苏同学的解释,我看到了,我找到了一点资料
CakeSession的__regenerateId方法的源码
http://thinkly.cn/docs/cnapi/session_8php-source.html#l00589