二次开发的一些经验之谈

10次阅读

如果您想从此贴直接获得一些有用的插件、模块、或代码,请绕道~~
“ 授人以鱼 ” 还是 “ 授人以渔 ”,此贴是后者,希望对你有所帮助 ……
* 提示:如果你是 PHP 编程有比较深入经验了,请只读红字内容即可,其它跳过。
         如果你是 PHP 初学者,请仔细阅读所有文字,别嫌繁琐,对你提高有好处!

1、执行 header()前输出的空格、空行、任何字符,都会导致 header()跳转失效!
   前几天,帮一个客户做了一些修改,把代码发给对方之后,对方后来反映说 “ 后台栏目查看文章列表不行了 ”,我去查看果真如此,点击了栏目后面的 “ 内容 ” 进去,一片空白!这一点我当时百思不得其解,因为我做修改的代码,和这个功能完全没有关系!于是不得已,只好一步步做跟踪调试:
     首先 要排查的是语法错误(如果当 php.ini 里设置是不显示任何错误的话,语法错也会导致一片空白),这个文件是 dede/catalog_do.php(怎么知道是这个文件呢,很简单,在那个一片空白的页面上,点右键,看属性,就有地址 URL 和传递的参数),我把一行 die("aa"); 放在了代码第一行,这个做法就可以测试有无语法,因为语法错不单可以发生在 catalog_do.php 文件本身,还可以发生在 catalog_do.php 文件所引用的文件里(包括这些文件里再引用的任何一级文件里),所以如果这个第一行 die("aa"); 也不能执行,就必然是语法错。因为能输出 aa, 也就是说语法没有错,就必定是某种程序上的逻辑错。
      然后 进一步寻找逻辑错误发生的文件,这就需要跟踪代码的所执行到的地方,由于没有任何提示,也还是利用 die("aa");,把这一行往下挪到 catalog_do.php 文件的 include、require 等语句之后,如果不能执行,说明在 include、require 所引用的文件里,代码执行就停止了,反之说明那些文件执行是正常的。这一步,依然能显示 aa,说明错误是发生在 catalog_do.php 文件里(如果是发生在其他所引用的文件里,就用此法打开那些文件去如是调试)
      然后 再此文件里一步步寻找发生错误的具体代码段,首先要看链接此文件时候的参数(在那个一片空白的页面上,点右键,看属性,就有地址 URL 和传递的参数),而点击 “ 内容 ” 时链接此文件的 URL 为 catalog_do.php?cid=3&dopost=listArchives(它的意思,我们可以猜测它 cid 是栏目 ID,而最重要的是 dopost=listArchives 这个参数,因为我们在 catalog_do.php 文件里,可以看到接下来的代码,就是一连串的 if (dopost=="…."){  }else if(dopost=="…."){  }else….. 的判断,它就是让程序运行,根据过来的 dopost= 参数的不同,进入不同的处理),好,我们就直接找到 if (dopost=="listArchives"){这里,把 die("aa"); 放到紧接着它的第一行,看看还能否输出 aa,如果可以输出,说明程序正确进入了目标程序段,否则就说明 dopost=="listArchives" 这个判断没有达到预期的效果(如果是这个情况,你就要好好对照刚才的 URL 和这个 dopost=="listArchives",有没有写错参数名、大小写有没有弄错了,还有就是 dopost 值有没有在前面就被改变了,最常见的错就是类似写成了 dopost=="listarchives",或者在前头某个判断里写成了 dopost="…"),好,依然能输出 aa,说明程序也进来这里了。
       然后 继续寻找发生错误的代码行,继续挪动 die("aa"); 的玉步,每次挪动完,刷新那个空白页面,看看能否输出 aa(这里有技巧,想快,就不要逐行挪动,而是利用折半查找,或者在关键代码前后插入,这个就需要比较强的代码阅读能力和一定的编程经验了,不展开了),最后,我发现在 header("location:{$gurl}?channelid= {$channelid}&cid={$cid}"); 这一行之前能输出 aa,这一行之后也能输出 aa,而我是很清楚,这一行本该跳转到某个指定的页面上的,后面不应该输出 aa,同时我也知道造成这个问题,通常是因为程序执行在之前就输出过字符(如果你不清楚,就查 google 或手册)!
       接下来 的工作,就是找哪个文件有这个输出了,天啊,这太难找了!于是我换了另外一个做法 “ 修改排查法 ”,我在本地把我那些修改的代码,也换上去,发现没有出现这样的问题,也就是说,我写的文件没有问题。然后我把客户所有文件,都列出来,按修改时间排序,并询问了客户最后可以正常使用这个功能的时间,发现了一堆在此时间之后修改的 php 文件,除去我修改的那些文件,就剩下两个文件了,其中一个是 include/extend.func.php 文件,我很清楚这个文件是一个 dede 提供给客户做函数扩展的文件,它被 common.func.php 所引用,而 common.func.php 又是被全站所有文件所引用的文件!   于是我打开这个文件,赫然在最后?> 之后,有两个空格一个空行!!!!!!
       把这些空格空行删除,至此 功能就全部正常了(包括我在模块表里自定义了一个模块链接,它在这个错误的情况下,不能显示在模块列表里,现在也正常了)!
     以上文字,对于初级 PHPer,可以学习领会一点点 PHP 调试技术;对于 PHP 已经比较熟的,而对 DEDE 还有有点陌生的,这里提供的一条经验就是:修改 DEDE 的所有 PHP 文件,千万不要在头尾两行的 <?  ?> 之外,写入任何字符,包括空格和空行!!

正文完