1.7 调试

在代码实现的过程中,我们会遇到这样那样的错误,这无疑是不可避免的。有的时候,错误是人为疏忽造成,比如输入代码时,漏录了一个字母或一个符号;有的时候,错误是逻辑上的,即程序编译和执行都没有问题,但是输出的结果与程序设计人员的预期背道而驰。在作者成书的过程中,由于疏忽和时间原因,都有可能打错字,何况在动辄成千上万行的代码编写过程中呢?

那么,有没有什么途径能够让程序设计者和开发者能够定位出错的地方,找到出错的原因,从而及时更正错误呢?答案是肯定的,那就是通过调试程序。

这是一个系统的工程,事实上,有些时候,调试程序的时间可能比编写程序的时间还要长,所付出的精力更多,因此,我们可以看到,实际上有很多企业是以调试和测试程序为生的,专业上讲,测试程序可以分为“黑盒”和“白盒”测试两种,使用专门的测试工具,可以对代码的任意分支进行全面测试,当然了,我们做不到这么专业,我们所追求的是,在发现问题时能够及时更正。

我们这里简单介绍一下本文中所使用的调试方法:

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章里面会继续用,请读者做好心理准备,我们会用到恶心为止,希望读者朋友们能跟着作者一同部署这些代码。我们在后续章节,会对这个程序进行持续改进,本章撰写过程所形成的代码,作者整理后留在本文下面的链接处,欢迎读者朋友们免费下载。需要提醒各位的是,别人的代码永远是别人的,只有自己着手写,才能进步。作者的代码也仅供参考,因为是初起的代码,各方面还没有改进的,好在注释还比较详尽。

再次感谢读者朋友的支持!欢迎大家多关注转发,让更多有这方面需要的朋友看到本文,也欢迎大家在评论区留言,作者会知无不言言无不尽的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值