[原创]PHP实现类似ASP里的Application对象
January/21st 2010

    以前搞过一段时间的asp,觉得application这个对象很爽。。可以很容易的写一个聊天室。。。后来逐渐转到php,就一直为这事郁闷。。因为php里面没有对应的东西。数据只能往数据库或者文件里面写才能实现共享。 今天在公司做聊天室的时候,灵机一动,居然让我发现了一神奇的方法~~哈哈:

PHP里面的$_SESSION变量可以实现类似Application的功能,但重点在它不能跨浏览器进程,或者说是跨用户。。只能是单个用户操作不同页面时候的变量传递,是一种cookie的替代方案。
众所周知,php里,调用session_start()之后,客户浏览器会收到一个大概名叫PHPSESSID的cookie,这个叫session_id。不同页面的参数共享就是靠这个变量实现的。
有时,由于客户端浏览器或者其他什么神奇的原因,导致无法正常发送 PHPSESSID的时候,我们可以手动发送,然后在php里面的session_start();之前,调用session_id("sessionid在这里");手工指定session_id ,这样,就可以让session工作正常。(比如浏览器不支持cookie,或用flash上传文件的时候)
好了,关键的东西来了。如果我们让每个用户的session_id都一样会怎么样? 哈哈。ASP的Application功能便呼之欲出~~~
实现方法非常简单: 在每个php页面的前面都写上下面的代码: session_id("xxxx"); session_start(); 然后,你就可以像用Application对象那样来使用$_SESSION了。。~~哈哈哈哈~~~爽吧~~

    PS:ASP的Application对象是存储在内存里面的,而PHP的SESSION一般默认是用文件来存的。不过也可以设置php.ini让php用mysql数据库存,甚至用memcached来存~~具体方法就不详述了。。 chy提到session本来的作用是保存用户的登录信息等,是非常有用的。我这样一弄,session就失去了它原有的功能。所以我搞了一个函数,可以实现全局session和局部session共存。互不干扰。

/*
用法:
application('key','value'); //设置 key=value
$value = application('key'); //获取 key的值
*/

function application()
{
	$args = func_get_args(); //获取输入参数
	if (count($args) >2 || count($args) < 1) return;
	$ssid = session_id(); //保存当前session_id
	session_write_close(); //结束当前session
	ob_start(); //禁止全局session发送header
	session_id("xxx"); //注册全局session_id
	session_start(); //开启全局session
	$key = $args[0];
	if (count($args) == 2) //如果有第二个参数,那么表示写入全局session
	{
		$re = ($_SESSION[$key] = $args[1]);
	}
	else // 如果只有一个参数,那么返回该参数对应的value
	{
		$re = $_SESSION[$key];
	}
	session_write_close(); //结束全局session
	session_id($ssid); //重新注册上面被中断的非全局session
	session_start(); //重新开启
	ob_end_clean(); //抛弃刚刚由于session_start产生的一些header输出
	return $re; 
}

    当然,这样操作的成本有点高。。不过在实际使用中,基本不会遇到使用全局session和局部session的频率都很高的情况。所以可以按需求封装局部session或者是全局session。 上面那个函数封装的是全局session,稍微修改就可以实现局部session。



18407 read 30 comment(s)
#1
Vilic   2010年01月22号 01:45       回复
沙发,嗯嗯,很有意思啊,大概是看懂了。
#2
chy   2010年01月22号 03:46       回复
突然想到一个问题
Session 的关键作用在于不同用户不同进程可以存储不同的数据,互不干扰。
如果按你的方法让这些用户都公用session了,那么如果还需要分别存储不同的数据,比如用户个人的登录验证信息等等,如何处理?

可以有两个session吗? 一个公用,一个私有?
#3
longbill   2010年01月22号 05:03       回复
回复 chy: 的确可以有几个session!我按照你的思路写了一个函数,可以实现全局session的封装,而且不影响普通session的使用。/*用法:application('key','value'); //设置 key=value$value = application('key'); //获取 key的值*/function application(){    $args = func_get_args(); //获取输入参数    if (count($args) >2 || count($args) < 1) return;    $ssid = session_id(); //保存当前session_id    session_write_close(); //结束当前session    ob_start(); //禁止全局session发送header    session_id("xxx"); //注册全局session_id    session_start(); //开启全局session    $key = $args[0];    if (count($args) == 2) //如果有第二个参数,那么表示写入全局session    {        $re = ($_SESSION[$key] = $args[1]);    }    else // 如果只有一个参数,那么返回该参数对应的value    {        $re = $_SESSION[$key];    }    session_write_close(); //结束全局session    session_id($ssid); //重新注册上面被中断的非全局session    session_start(); //重新开启    ob_end_clean(); //抛弃刚刚由于session_start产生的一些header输出    return $re; }当然,这样操作的成本有点高。。不过在实际使用中,基本不会遇到使用全局session和局部session的频率都很高的情况。所以可以按需求封装局部session或者是全局session。  上面那个函数封装的是全局session,稍微修改就可以实现局部session。
#4
Longbill   2010年01月22号 05:14       回复
回复 Vilic: 
呵呵。。我又更新了哦。。
#5
zx68555   2010年01月22号 06:33       回复
这么强!踩了!
#6
Vilic   2010年01月22号 14:33       回复
回复 Longbill: 
嗯.话说以后一定要学习PHP,不过现在还得找.NET空间.
#7
宇博   2010年01月28号 04:31       回复
自从从ASP转向PHP,我也一直使用MYSQL建立并存储...
#8
士大夫VSxiaokaizi   2010年02月01号 08:32       回复
哈哈学习了。
#9
msxcms   2010年02月25号 08:19       回复
session即文本存储,此法应该是毫无意义
#10
Longbill   2010年02月25号 08:21       回复
回复 msxcms: 
谁说session是文本存储? session可以存到文件,可以存到数据库,可以存到内存,可以存到memcahed等等
#11
msxcms   2010年02月25号 08:54       回复
回复 Longbill: 
既然这样,何必要Session中转一下呢?
#12
Longbill   2010年02月25号 08:57       回复
回复 msxcms: 
仅仅是为了方便使用。直接操作$_SESSION变量,而不用管文件读取存储或者数据库连接等问题。
#13
msxcms   2010年02月25号 08:59       回复
回复 Longbill: 
但是此法我个人极不推荐,让php走Session会大幅降低性能。设计起初应该就要想好架构,比如你想好用mysql,那就写几个简单的读写类或函数,memcached也雷同。
#14
Longbill   2010年02月25号 09:01       回复
回复 msxcms: 
这个东西当然不实用,仅仅是一个实现方式探讨,在某些情况下能派上用场。比如可以做临时计数器。。。等
#15
qshp   2010年03月05号 14:36       回复
首页顶部那个是用cookie实现的哇????
#16
selvin   2010年03月12号 13:20       回复
有用,学习啦。
#17
石家庄律师事务所   2010年03月20号 12:59       回复
PHP安全性存疑
#18
小赵   2010年05月15号 13:47       回复
php操作session前,好像是要锁定对应的session文件的.如果所有用户都共用session,php岂不是变成单进程工作了
#19
刘春龙   2010年05月15号 14:51       回复
@小赵 session_write_close(); 之后就解除锁定了。
#20
小赵   2010年05月15号 16:07       回复
受教了
#21
fengyqf   2010年07月19号 14:11       回复
不错,很有想法,这个函数不错,用一下
#22
fengyqf   2010年07月19号 14:29       回复
对极小的应用很实用,但对大规模应用,还是要用“专业”一点的实现方案了
#23
bsd   2010年09月12号 21:40       回复
那C写个简单的扩展就可以实现,何必这么麻烦。
如果web服务器只有一台机,apc扩展其实就是Application
参见以下三个函数就可以
apc_fetch
apc_store
apc_delete
如果是集群应用,那更应该由专门的C或java的daemon来做后台的事情,php仅在前台
#24
Longbill   2010年09月12号 22:02       回复
@bsd 有自己的server当然是另外说。  这个仅仅是玩而已,远远没达到实用的程度。
#25
洽汇网   2017年03月16号 19:40       回复
很早之前的文章了,有新的解决方案没,好像 shmop_open 可以实现共享内存,无须读写文件,不知道虚拟空间能不能用
#26
洽汇网   2017年03月16号 19:40       回复
很早之前的文章了,有新的解决方案没,好像 shmop_open 可以实现共享内存,无须读写文件,不知道虚拟空间能不能用
#27
洽汇网   2017年03月16号 19:40       回复
很早之前的文章了,有新的解决方案没,好像 shmop_open 可以实现共享内存,无须读写文件,不知道虚拟空间能不能用
#28
洽汇网   2017年03月16号 19:42       回复
很早之前的文章了,有新的解决方案没,好像 shmop_open 可以实现共享内存,无须读写文件,不知道虚拟空间能不能用
#29
洽汇网   2017年03月16号 19:43       回复
很早之前的文章了,有新的解决方案没,好像 shmop_open 可以实现共享内存,无须读写文件,不知道虚拟空间能不能用
#30
洽汇网   2017年03月16号 19:46       回复
手机留言报smtp错误,我还以为没发表成功
添加新的评论
称呼:*
邮件:*
网站:
内容:

Copyright © Longbill 2008-2024 , Designed by EndTo , Powered by EndCMS