在代码实现的过程中,我们会遇到这样那样的错误,这无疑是不可避免的。有的时候,错误是人为疏忽造成,比如输入代码时,漏录了一个字母或一个符号;有的时候,错误是逻辑上的,即程序编译和执行都没有问题,但是输出的结果与程序设计人员的预期背道而驰。在作者成书的过程中,由于疏忽和时间原因,都有可能打错字,何况在动辄成千上万行的代码编写过程中呢?
那么,有没有什么途径能够让程序设计者和开发者能够定位出错的地方,找到出错的原因,从而及时更正错误呢?答案是肯定的,那就是通过调试程序。
这是一个系统的工程,事实上,有些时候,调试程序的时间可能比编写程序的时间还要长,所付出的精力更多,因此,我们可以看到,实际上有很多企业是以调试和测试程序为生的,专业上讲,测试程序可以分为“黑盒”和“白盒”测试两种,使用专门的测试工具,可以对代码的任意分支进行全面测试,当然了,我们做不到这么专业,我们所追求的是,在发现问题时能够及时更正。
我们这里简单介绍一下本文中所使用的调试方法:
1.实际观察法
我们通过直接给后台传递参数的方式,观察后台返回结果的情况,来验证我们的程序是否正确。例如,
我们在VUE端查询课程时,使用了如下代码:
uni.request({
url:'https://www.shuiliuyunzai.cn/LX001/interface.php',
data:{
type : 2,
op:'getCourse'
},
header: {
'content-type': 'application/x-www-form-urlencoded',
},
method: 'POST',
dataType: 'json',
success : (res) => {
this.list = res.data;
}
});
其中,https://www.shuiliuyunzai.cn/LX001/interface.php是接口地址,我们想看一下,这个接口地址在VUE当前条件下调用时,到底输入的是什么,是否与我们的预期相符。按照代码中的data的条件,我们可以在浏览器中构造如下链接:
https://www.shuiliuyunzai.cn/LX001/interface.php?type=2&op=getCourse
此时,浏览器显示情况如下:
访问后,浏览器返回一个json数据包,具体内容如下:
[{"c_name":"\u79bb\u6563\u6570\u5b66","c_id":"7",
"c_credit":"4","type":"2",
"c_image":"\/static\/course-7.png","t_name":""},
{"c_name":"\u6982\u7387\u8bba\u548c\u6570\u7406\u7edf\u8ba1",
"c_id":"8","c_credit":"5","type":"2",
"c_image":"\/static\/course-8.png","t_name":""}]
我们可以看出,这个json数据,共返回2条数据,每条数据中含有“c_name”、“c_id”、“c_credit”、“type”、“c_image”、“t_name”6个属性。
我们分析我们的参数“type=2”、“op=getCourse”,我们的接口应该执行的下面代码:
也就是说,此处执行了$front->LoadCourse(2)。我们在front.class.php中看一下LoadCourse方法在参数为2的时候,具体执行的代码:
也即是说,其应该执行sql语句为“SELECT * FROM course WHERE id not in (SELECT c_id FROM teaching)”,我们在mysql控制台中执行该语句,看一看结果与json数据包是否一致。
我们看到,执行该sql语句后,同样是返回2条数据,从json数据包的“c_id”属性上看(两条数据的ID分别为7和8)数据应该是一致的,证明整个过程涉及的服务器端代码(接口、业务、数据库和sql)都是没有问题的,此时如果前端显示还有问题的话,只能说明是VUE端的问题。
2.日志法
我们通过写日志的方法进行调试,这在前台和后台都适用(即VUE端和PHP端适用)。因在很多实际情况下,我们无法通过实际验证的方式进行观察,但是,却可以在程序的关键地方(我们认为可能出现错误的或者影响主要逻辑的地方)加入日志,然后观察日志的输出情况,判定程序是否正常运行。这基于这样的思路,如果我们想让我们程序的最终输出是正确的,必须要保证程序的每个阶段输出都是正确的,因为,这个阶段的输出,往往是下一个阶段的输入,一个环节出现问题,很可能导致满盘皆输。例如,
针对服务器端的php代码,我们在mysql.class.php中写入如下日志函数,以便业务层和接口部分可以调用:
public function info_log($msg = '') {
MySQLLog::INFO(json_encode($msg));
…………
// MySQLLog类定义请读者在随书代码中自行查看
}
在需要日志的地方,例如,前面我们的接口文件中,对于参数“type=2”、“op=getCourse”的返回值写入日志,可以在调用相应的接口部分写入日志文件的方法调用,如
在前端(VUE端),我们往往也是通过日志法来查看后端接口返回前端的返回值,例如,在调用接口成功后,我们可以加入下面代码,以便在控制台中能够看到日志输出:
console.log(res.data);
此时代码为:
我们在模拟运行时,可以看到,当选择“教师”,选择某一位教师,打开课程页面时,此处会执行,控制台输出如下:
我们看到,前端返回值与服务器端查询的结果也是一致,如果此时还有问题,则说明是在template部分书写或者接收该json数据时逻辑不正确导致的。
小提示===
如何看HBuilder中的控制台?
如下图所示,我们可以看到,Hbuilder有程序执行控制台,此处会显示程序代码的编译情况、输出情况和错误情况,内置的页面预览的控制台与在chrome下运行的控制台一致,是页面在实时状态的输出情况。对于我们的console.log的输出可以通过页面预览控制台来查看。
小提示===
我怎么知道哪个地方(代码段)“容易出现问题”?
这个就真的是靠“经验”了,也是熟练程序员和新手程序的最大区别。一般而言,在算法较为复杂,尤其是分支(if、switch)和循环语句(while、for)嵌套使用、数组变量遍历、复杂SQL语句等较为容易出现错误,当然,调用其他人写的接口时,几乎是必须要经历一个调试的过程的。
有时候,我们通过程序运行的表象来判断出错点,比如程序一直运行迟迟没有输出,如果不是有较大的时间消耗代码的话,我们就应考虑循环代码部分,比如是不是出现了“死循环”(即没有出口条件或出口条件永远无法满足的循环语句,程序始终运行在循环内部)。
有关算法、时间和空间复杂度的内容在本书的第8章会再次深入探讨。
本章小结
终于写完了第一章,感觉写一本书确实不是件很容易的事情,尤其像我这样自娱自乐、几乎在没有几个读者的欢呼支持的情况下。
乍一看这一章,似乎和微信、和服务号开发没有什么关系,如果这么看就大错特错了,本章的内容是微信服务号开发的基础内容,只要把本章的内容与微信服务号开发的特殊内容结合起来,就可以完成服务号的开发,事实上,微信服务号的开发,只不过是利用微信服务号的接口进行网页开发罢了,实质上还是网页的开发,所以,学好用好php、mysql和VUE,不但为微信服务号开发打下基础,也是其他开发(微信小程序、游戏、app、网站等等)的基础。工欲善其事必先利其器,了解开发工具永远是开始开发前的第一步!
本章涉及的例子,选课系统(比较“俗”,哈,只要涉及数据库开发的,选课系统几乎都是例子),在接下来的4章里面会继续用,请读者做好心理准备,我们会用到恶心为止,希望读者朋友们能跟着作者一同部署这些代码。我们在后续章节,会对这个程序进行持续改进,本章撰写过程所形成的代码,作者整理后留在本文下面的链接处,欢迎读者朋友们免费下载。需要提醒各位的是,别人的代码永远是别人的,只有自己着手写,才能进步。作者的代码也仅供参考,因为是初起的代码,各方面还没有改进的,好在注释还比较详尽。
再次感谢读者朋友的支持!欢迎大家多关注转发,让更多有这方面需要的朋友看到本文,也欢迎大家在评论区留言,作者会知无不言言无不尽的。