如何调试Php?
最简单的谁都会的调试(是么?):
本来安装php是没问题 也能用了 但是又从书上抄了一些代码来发现不能用, 那就用眼睛仔细的对着书本纠正一下代码哈 肯定是你抄错了 要么是印刷错了
比如 1(yi)跟l(el) 0(ling)跟O(大写o)等
别笑哈 真的有人抄错过 还让我过去帮忙调试 过去我录入进去(他的没保存) 就全对了
言归正传
Q: "为什么要调试?"
A: 当然是因为程序错啦. 你以为我有什么别的答案?
Q: "可是我觉得我的程序应该没错啊!"
A: 不能出来期望的结果 当然是错误发生. 有这种思想的人是根本不具备调试观念 更没有调试能力.
Q: 那调试有什么用?
A: 不管是你配置的php出错 还是你的程序写错 还是你写的正确的程序跟别人配置的php(比如免费空间)犯冲, 学会调试都能找出原因来
Q: 逻辑乱了能调试好么?
A: 或许你偶尔改来改去改好了 以为是调试好了 其实那已经不是单纯的调试, 而是反复的用程序代码进行思考, 并且反复的改代码来"实践"某个idea是否可行.
可以说是"调试逻辑"而非"调试代码":
逻辑没代码或者乱代码--调试/修改逻辑-->正确的逻辑->体现在代码上,出来正确的代码.
单纯的调试代码是:
正确的逻辑--编码-->出错的代码--调试-->正确的代码
所以调试可以分为:
1.调试逻辑, 2.调试代码, 3.调试界面. 4. etc..
错误的逻辑是不可能出来正确的程序. 写程序首先得把逻辑(流程)弄清楚, 然后才开始编码.
合并在一起就是:
含糊的逻辑--调试逻辑-->正确的逻辑--编码-->出错的代码--调试代码-->正确的代阿马
其中调试逻辑你可以利用"修改代码"来辅助 免得脑子太累, 但是脑子必须动, 不能不思考乱改来改去, 而且不能跟 "调试代码" 混在一起.
改小错误 常常混在一起 就解决了, 但是要养成分开的习惯, 对于大错误才能一样轻松解决.
别慌
很初学者 一碰到错误就慌了, 脑子里只知道"不行啊 错了 惨了 找个人问问", 要冷静下来 根据所学的知识去研究, 到底什么是debug, 如何debug, 出错了到底该干什么
基本调试:
1. 打开调试功能: php.ini 里 设置error_reporting = E_ALL以及 display_errors = On 重启 web服务(apache)
2. 刷新错误的页面 查看错误提示 行号 文件名
3. 打开该文件 定位到出错行. 比如代码 echo $abc[2];
4. 理解错误:
a. 查看手册 理解错误含义 要能理解首先要理解语言 比如最简单的 Undefined index 2 意思是数组不存在该下标 也就说明你访问了某个数组不存在的元素
b. 如果已经知道如何改 就直接修改, 比如改成 echo $abc[0];
c. 不知道就显示变量内容 在同样的地方 加入 var_dump($abc); 刷新页面 看看$abc这个东西到底包含了什么元素
d. 认为本该存在 $abc[2]的, 那就寻找错误源, 往上回朔, 或者用 var_dump(debug_backtrace());
必要的时候 var_dump($_POST, $_GET, $_COOKIE, $_SERVER....)
本人未用过单步调试 (step by step) 如果使用调试器相对简单一点 可以暂停下来 看看变量的内容 到底是不是 中应该出现的值, 如果不是 又是哪里产生这个值的
注意留意什么是环境
环境:
为什么全世界那么多人没事就你的有问题? 你的问题爱上了你 还是你爱上了你的问题?
其实"一方水土养一方人", 你的"环境"养你的bug.
平时阅读书本/手册, 注意记录整理什么是"环境".
$_GET $_POST $_COOKIE $_SESSION $_SERVER 这些是程序运行的至关重要因素 当然还包括你自己搞出来的 $GLOBALS, 都可以var_dump他们 看看内容.
还有strtolower/strtoupper之类 跟setlocale()函数有关, 而默认值在linux下跟 getenv("LANG") getenv("LC_ALL") 之类有关(putenv不一定起作用)
还有其他的 比如php.ini的配置.
还有web服务器配置, 比如apache支持某些函数而在别的服务器下就不支持
btw1: 你的调试能力跟你的编码能力是相互相成的, 根据你的编码经验你觉得还有什么该注意的 可以提出来
btw2: 有些你或许觉得很简单很平常, 但是想想你自己是不是真的做到了
-------------------------------- 以下内容比较罗嗦
对于你一眼就看出来的问题, 当然可以立即解决, 但是如果没头绪那就参考:
调试的大方向:
抓!
a. 擒贼先擒王, 最大的错误就是逻辑错误, 先审查一边逻辑, 然后才是代码关键的部位(跟错误可能相关的)
b. 顺瓜摸根.., 有果必有因, 知道最终错误的"结果", 顺着摸过去 就能发生错误的"原因", 比如
if ($logined) {
$a = 100;
}
$_SESSION['a'] = $a; 提示Undefined variable $a, 显然要找产生$a变量的地方, 往上找到 if那块 发现只有if true的时候才有$a于是改成
if ($logined) {
$a = 100;
} else {
$a = 0;
}
比如mysql的函数出错 就有好多提示
提示 密码错误: 看看是参数的密码错了 还是mysql服务器设置的密码错了
提示 sql字段不存在, 打开phpmyadmin去表里看看有哪些字段 程序写错了还是忘记添加了 还是搞错表了
提示语句错误, 找mysql手册 而不是php手册
拆!
所谓万众一心 那个什么什么来着, 但是我们是一个人面对的一个"庞大"的代码, 所以要来个"反之亦然", 把错误从代码里分开, 把多个错误拆开. 如此一来, 对于你来说只不过是多个小小的错误, 一个个消灭.
忆:
回想以前是不是碰到类似的错误提示, 那个时候是怎么解决的. 如果没有回想到, 那就应该找新的方法.
对于初学者来说, 反复锻炼很重要, 回忆能加强学过的能力/方法, 直到联会贯通, 应用自如.
对比:
跟本文开头说的差不多, 就是找正确的代码来对比.
有时候是没有相应的正确代码的, 这个时候可以在脑子里重新构思一个正确代码来对比, 有点难 呵呵, 不过这样是避免又照着错误的思路去想
再就是看看手册, 根据手册说明就知道其实应该如何 不该如何.
OO 思路
要求你的程序比较OO(不一定是对象, 但是结构/思路上有oo)
OO编程简单说就是对象化, 每个类型的对象完成某个功能, 就像一只老鼠只需要吃就能活, 一个对象/或者某部分代码 只需要所期望的一些数据就能正常工作.
OO debug法就是首先要有个观念: 我的某个对象(or代码)只需要有一定的数据(环境下)就可以正常工作
如果
1. 有正常的数据也出错 则说明是这个对象设计错了
2. 传入的数据不正常, 则说明使用这个对象的代码调用错了
高手或许觉得这条很"傻", 其实对于初学者(包括以前的我) 要形成这样的观念 以及一直使用这个观念来调试, 却是要到了很久之后 接近高手了 才懂.
有点像'拆'方法 不过区别在于调试的时候:
1. 取对象出来 可以单独调试, 因为好的对象(or代码) 只需要尽量简单的数据, 复杂的数据可能在对象内部或者外部生存, 而不会跨出/入对象(也就是不会传进来 也不会传出去)
2. 对于web要快速调试, 并不一定要把对象的代码全部掏出来, 只需要再调用对象的部分 添加一些用来查看对象语句, 比如var_dump($obj) var_dump($obj->myabc);
或者类似 echo $http->download(); 这样的调用之前 手工设置一些自己熟悉的数据 比如:
$http->setUrl("http://localhost/abc.html");
直到确保这个对象工作正常了, 就可以暂时撇开这个对象的代码了, 看看别的东西有没有错误