由 if 想到的些问题March 12, 2008

在编写一段并不复杂的脚本的时候,发现了一个问题。先说说代码,它的主要功能是用 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 在客户端执行的。

总结下,本人从这段代码想到的些废话:

  1. 代码越长,不见得效率就越高
  2. 在不影响逻辑和流程的情况下,尽量将多个判断写在一起
  3. 尽量将低复杂度的函数放前判断
  4. 过多的判断容易造成程序效率降低,在判断中使用高时间复杂度的函数时尤其要注意
  5. 如果发现 if 嵌套得太多,就得重新考虑流程和算法
  6. 健壮的代码不是靠过分的判断保证而成的
  7. 将代码简化后,会发现很多还未发现的问题
  8. 过多的判断另个角度理解,是缺乏对代码的信心

最后,再次感谢 小马 同志。

诡异的 Session 丢失问题March 4, 2008

由于服务器损坏,所以不得不重新发布网站。当 Anakin 兄弟全部将环境搞定,并且 Gracecode.com 也能正常浏览的时候,我发现我的网站竟然不能登录了。

起初,我怀疑是环境问题,于是我联系 Anakin 兄,他说一切正常。于是,我就开始检查起我的代码,几段 DEBUG 代码下来,我发现竟然连 POST 数据都收不到(var_dump($_POST);),而 GET 是正常的!非常地让人匪夷所思。

继续 DEBUG 发现,我输错了用户名和密码是能 var_dump 出 POST 与 SESSION 的,一切正常。唯独就是我输入正确的用户名与密码以后,老问题就出现了。

经过充分的调试与徘徊以后,我开始静下心来思索 Session 的流程:Session 由客户端的 Cookie(或者是其他验证方式)提供验证值,然后服务器端根据这个值,从文件系统(或者数据库、或者内存文件系统、任何你想得到的媒介)获得对应的值。

http://files.gracecode.com/2009_11_05/4945852f554a.jpg

那么先从客户端入手,看看是否存在异常。首先,查看客户端是否有保存的 Cookie,的确是有的 -- 这就证明客户端是没有问题的。继续推断,既然客户端方面问题不大,那么问题到底是出在哪里呢?

登录不进去,那么我将判断是否登录的函数修改成始终返回 true(请未成年的小朋友在家长的陪同下操作)。发现登录后台与操作一切都没有问题的,这就说明 POST 过去的数据服务器也是能够接收的。

那么,单从这点上说明,肯定是服务器端的 Session 出了问题。我打印出 Session 的配置,如下图。

http://files.gracecode.com/2009_11_05/3985052f554a.jpg

根据我的经验,并没有发现配置上有什么异常的地方。此时,我突然有种“邪恶”的想法,于是乎就 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 重定向带到了新的页面。

看来,忙乱中,总是会出现不大不小的问题,共勉之。

Smarty Cheat SheetJanuary 16, 2008

本人很喜欢偷懒,所以很喜欢 Cheat Sheet 快速查找一些东西。现在,网络上找到份 Smarty 的 Cheat Sheet。Smarty 一直我都认为是一个好东西,所以这份 Cheat Cheet 对于我来说会很重要。

另外还有 jQuery 和 Prototype 的 Cheat Sheet 以及 MySQL 的 Cheat Sheet 提供下载(实在是居家旅行,开发糊口的必备利器)。

废话不多说,在这里提供 ZIP 格式打包下载。此文档为 PDF 格式,出处在这里

另外,还有一位更牛的家伙收集了大量的 Cheat Sheet ,看来还有比我更懒的。

  1. 1
  2. ...
  3. 5
  4. 6
  5. 7
  6. 8
  7. 9
  8. 10
Yahoo 统计