网站迁移时的一个小问题
因为公司外部网服务器硬件全面升级(换了一台专门的2U机架式服务器),所以要將原来的网站和邮件服务都迁移到新的服务器上。邮件服务的迁移已经实验是没有问题了(参见从sendmail迁移到postfix),但是在迁移网站的时候出现了一个小问题。
除了迁移网站,还需要增加一些服务,这次要增加的是一个在线演示系统,用于演示利用公司的产品完成网上登录身份认证的功能,其中一段代码是这样的:
- session_start();
- // 取得通过SSL认证的客户端数字证书中email信息
- $email = $_SERVER['SSL_CLIENT_S_DN_Email'];
- // 如果登录的用户的email和数字证书中的email一致,说明这是一个授权用户
- // 否则拒绝访问
- // 在此前的登录步骤中,用户注册的email地址已经从数据库中取出并放入session变量中了。
- if($email != $_SESSION['email'])
- {
- die('凭证不一致,您确定使用的是自己的数字证书?');
- }
- // ... 其他代码...
令人郁闷的是,这里的判断语句条件表达式总是为真,也就是说,无论登录的用户的email地址是什么,$email的值和session中存储的email地址总是是一样的。还真是见鬼了~~~不但如此,这个页面执行完后,session中保存的email地址就变成了客户端数字证书中的email地址了。
到底什么地方出问题了呢?
经过半小时的调试,最后发现,罪魁祸首就是原来的旧网站代码。旧网站的代码是我在五六年前写的,那个时候PHP的设置中,register_globals缺省是On的,所以在原来的代码中依赖了这个特性。而在高版本的PHP中(从PHP 4.2版开始),这个特性是被关闭了的,为了能让老代码继续工作,所以我修改了php.ini中的register_globals的设置,将其从缺省的Off改为了On,这样虽然老代码工作起来没有问题了,但是新代码却不能正常工作了。
如上述代码片段中,变量$_SESSION['email']被PHP的register_globals特性自动映射到变量$email上了,所以在给$email赋值时,其实就是给$_SESSION['email']赋值,这样,后续的判断语句当然就总是返回true,因为它们本就是同一个变量嘛。
问题确定后,修改就很容易了,將$email变量名改为$srv_email即可,测试通过。 :)
更进一步
对于追求完美的我来说,虽然这个问题可以这样解决,但总是感觉不爽,理想的情况是php.ini中register_globals特性是关闭的,对于新的代码使用更安全的方式进行处理(即对一切从客户端传递来的数据持怀疑态度,而不是自动將_POST/_GET/_ENV/_SESSION等注册成全局变量,除了安全性外,也可避免变量的冲突带来的隐蔽错误),而老代码仍然能够享受register_globals开启的特性,在新网站上线前的过渡期,老网站能够继续提供服务。
于是上PHP的网站寻找信息。在php.net上我发现了这篇文章,其开篇就提出了register_globals特性將会在PHP 6.0中移除(而不是像PHP 5.0这样为了保持兼容而保留),嘿嘿,毕竟register_globals已经被标记为”DEPRECATED”有好几年了,看来PHP社区认为用户都已经做好准备了。在这篇文章的回复中,有人提到了一个解决方案,即在需要register_globals特性的目录下,设置.htaccess文件,内容为
php_flag register_globals On
不过又有人提出这种做法在Apache2以上的环境中会导致Apache产生内部错误。当然这也有解决的办法:
… adding php_flag in .htaccess under apache 2 will cause internal server error. According to apache 2 manual, php_flag should goes to <virtual> or <directory> section.
嗯,明天到公司试一试。对了,对于新代码,要重新规范一下变量命名规则了,呵呵~~~
[2008-06-22 更新]
实践证明,在<directory>小节中加入php_flag是可行的。我没有采用设置.htaccess的方式,因为那种方式会导致每次客户端发出的HTTP请求时,Apache都需要重新读取指定目录及其父目录中的.htaccess文件(而且会逐层向上,直到站点的根目录),即使在某个层级中.htaccess根本不存在,这多少会影响一点性能。
现在,php.ini中的register_globals特性被关闭了,但是新旧代码仍然可以共存在同一台服务器上,完美解决~~~
目前有 3 个评论!
![Apex[有所思,有所志]](http://apex.ncksoft.com/wp-content/themes/deepwater/images/dw_site_logo.png)
人见人爱,花见花开 说:
没想到你换了部门还那么专研技术,可贵呀!
向刘老师学习!
北山 说:
用了你的皮肤,因为习惯打每段前的二个全角空格,就有问题了。
第一段字会自动加上2个全角空格,后面的不会有。
这样看起来第一段是空了四个,下面的是2个。怎么修改?
还有希望在评论右边加上头像。
onlyhot.cn 说:
博客做得挺好的.想和你做的链接.
Onlyhot Blog
http://www.onlyhot.cn/blog/
你的链接我已加好.