在编写一段并不复杂的脚本的时候,发现了一个问题。先说说代码,它的主要功能是用 PHP 判断是否生成一段 Javascript,并使用 Cookie 记录状态。
<?php
/* PHP code */
header("Content-type: text/javascript");
if (!haveCookie('cookieName')) {
// ... do something
?>
/* Javascript code */
if ('undefined' == typeof document.cookie['cookieName']) {
setCookie('cookieName', 3600);
}
// ... do something with Javascript
<?php
}
?>粗看起来代码已经无懈可击,我们亲爱的 小马 还是发现了问题的存在。就是在 Javascript 中的那个判断是永远为 true
if ('undefined' == typeof document.cookie['cookieName']) {
// ...
}因为这段代码是在 PHP 端有个前提,就是
if (!haveCookie('cookieName'))的时候,才会在客户端显示。那么,当不满足这一条件,这段代码自然就不会扔给客户端。这样说似乎有点笼统,那么先撇开 Javascript 代码,我们就单纯使用 PHP 代码表述一下
<?php
header("Content-type: text/javascript");
if (!haveCookie('cookieName')) {
if (!haveCookie('cookieName')) {
setCookie('cookieName');
}
}
?>这样就显得清晰了很多,并很容易就能发现问题所在 -- 我们在不经意间就多做了一次判断,虽然这是 Javascript 在客户端执行的。
总结下,本人从这段代码想到的些废话:
- 代码越长,不见得效率就越高
- 在不影响逻辑和流程的情况下,尽量将多个判断写在一起
- 尽量将低复杂度的函数放前判断
- 过多的判断容易造成程序效率降低,在判断中使用高时间复杂度的函数时尤其要注意
- 如果发现 if 嵌套得太多,就得重新考虑流程和算法
- 健壮的代码不是靠过分的判断保证而成的
- 将代码简化后,会发现很多还未发现的问题
- 过多的判断另个角度理解,是缺乏对代码的信心
最后,再次感谢 小马 同志。
由于服务器损坏,所以不得不重新发布网站。当 Anakin 兄弟全部将环境搞定,并且 Gracecode.com 也能正常浏览的时候,我发现我的网站竟然不能登录了。
起初,我怀疑是环境问题,于是我联系 Anakin 兄,他说一切正常。于是,我就开始检查起我的代码,几段 DEBUG 代码下来,我发现竟然连 POST 数据都收不到(var_dump($_POST);),而 GET 是正常的!非常地让人匪夷所思。
继续 DEBUG 发现,我输错了用户名和密码是能 var_dump 出 POST 与 SESSION 的,一切正常。唯独就是我输入正确的用户名与密码以后,老问题就出现了。
经过充分的调试与徘徊以后,我开始静下心来思索 Session 的流程:Session 由客户端的 Cookie(或者是其他验证方式)提供验证值,然后服务器端根据这个值,从文件系统(或者数据库、或者内存文件系统、任何你想得到的媒介)获得对应的值。

那么先从客户端入手,看看是否存在异常。首先,查看客户端是否有保存的 Cookie,的确是有的 -- 这就证明客户端是没有问题的。继续推断,既然客户端方面问题不大,那么问题到底是出在哪里呢?
登录不进去,那么我将判断是否登录的函数修改成始终返回 true(请未成年的小朋友在家长的陪同下操作)。发现登录后台与操作一切都没有问题的,这就说明 POST 过去的数据服务器也是能够接收的。
那么,单从这点上说明,肯定是服务器端的 Session 出了问题。我打印出 Session 的配置,如下图。

根据我的经验,并没有发现配置上有什么异常的地方。此时,我突然有种“邪恶”的想法,于是乎就 DEBUG 了下述的代码
var_dump(is_writeable(ini_get("session.save_path")));噢,“卖蛋糕、牙膏、×膏药”的!竟然返回的是 false,看来 Anakin 这小子又要被我“诅咒”了。问题终于有了个水落石出的结果,原来新安装好的系统,忘记把 session.save_path 设置成可写的了。这样导致登录成功以后,需要写入的 Session 无法保存在文件系统中,而此时 Session 的的确确有又是 start 的。
绕过这一问题很简单,只需要在 session_start 之前用 session_save_path 设置成自己的某个可读的目录就可以了。
马上联系 Anakin 兄那小子,并将相应的目录修改了回来。证明我的推断是正确的,现在又可以登录进去了。至于 POST 为何无法接收到,在事后也找到了原因,是因为 301 重定向带到了新的页面。
看来,忙乱中,总是会出现不大不小的问题,共勉之。
本人很喜欢偷懒,所以很喜欢 Cheat Sheet 快速查找一些东西。现在,网络上找到份 Smarty 的 Cheat Sheet。Smarty 一直我都认为是一个好东西,所以这份 Cheat Cheet 对于我来说会很重要。
另外还有 jQuery 和 Prototype 的 Cheat Sheet 以及 MySQL 的 Cheat Sheet 提供下载(实在是居家旅行,开发糊口的必备利器)。
废话不多说,在这里提供 ZIP 格式打包下载。此文档为 PDF 格式,出处在这里。
另外,还有一位更牛的家伙收集了大量的 Cheat Sheet ,看来还有比我更懒的。