2017年6月

[教程] 某 php 程序的 bug 定位及修复

前言:

已知程序采用 MVC 架构, 分别为 controllers/views/models 文件夹.

bug 描述及复现:

comment
无论怎么刷新网站的浏览次数在访问后并不进行自增. 数据库中对应字段也没反应. 手动修改字段为 10. 刷新页面
comment
可以看到浏览次数的确改变了. bug 复现完毕.

解决方案分析:

通过复现 bug, 初步认定程序在执行过程中对浏览次数的操作并没有成功执行.

分析:

造成自增操作不成功的因素可能有: 数据库连接失败/SQL语句编写错误/流程控制判定异常/没有编写对应代码.

结论:

首先排除了数据库连接失败, 因为可以从数据库中拿到数据. 那么接下来从源码分析, 判断余下三个可能.

bug 定位及修复:

comment
程序采用 MVC 架构, 分析 URL, 其中 c 指代 controller, a 指代 action. 定位源文件 controllers/contentController.php
comment
为了确定这个 showAction 就是对应的控制器, 添加调试语句打印页面信息.
comment
刷新页面查看
comment
调试语句成功执行, 并打印出了我们需要的信息, 其中 hits 就是浏览次数.
接着分析源码. 一般对浏览次数统计的思路是: 拿到 paper id, 获取 id 对应的 content, 接着对 hits 进行 +1 操作. 所以先从 id 入手.
comment
查找 id 引用, 结合注释及代码分析, 唯一可能会对 hits 进行 +1 操作的可能是 $data = $this->content-find($id); 语句.
按 F12 跟进(此功能为 SBT3 自带). 只要代码风格不是很差劲第一个跳过去的就是目标代码, 如果不是, 多分析几个就是了.
comment
很幸运, 第一此跳过来就找到了. 但是很不幸, 这不是我们要的, 结合注释和源码, 这只是一个 SELECT 操作.
通过 ID 分析这条路不通, 接着走, 分析 $data, 因为除了 id 之外, 唯一会跟 hits 打交道的就是这个 $data 了, 查找引用.
comment
引用很多. 接着分析, 虽然引用很多, 但是可疑的地方只有个别几处, 分别是 87/121/122 这三行.
87 行对 $data 进行了赋值操作, 121 及 122 进行了内容替换操作. 接着 F12 跟进对应的函数. 
comment
comment
并没有我们要的内容. 接着分析, 可能是思路不多, 也可能是跟进的深度不够. 换个思路, 直接搜对 hits 操作的函数. 然后逆推调用的源码.
comment
在网站根目录下执行 cmd 指令, 分析反馈的数据. 排除额外的如 CSS 代码, 注释. 拿到以下内容.
comment
分析得到的数据. APIController.php 下的 hitsAction 嫌疑很大. Comoon.php 和 Image_lib.php 则是来打酱油的.
排除掉之后剩下 ApiController.php / sphinxapi.php / ContentModel.php, 我们知道 sphinxapi 这玩意是个搜索引擎, 所以也可以排除了.
那么就剩下了 ApiController.php 和 ContentModel.php. 而 ContentModel 的语句相似性太高, 而且只有一句. 所以可以排除.
最后剩下了嫌疑最高的 APIController.php, 我们也看到了类似于 update 的语句. 跟进.
comment
看来这就是我们要找的函数了. 接着继续分析, 逆推调用流程. 通过源代码得知.
这个函数是不能通过内部调用进行 update 的, 需要通过 GET 方式传递 id 值. 然后对 hits 进行 update, 测试一下.
comment
返回正常, 接着进数据库查看.
comment
对应条目也变成了 11. 进新闻浏览页刷新.
comment
浏览次数也成功更新, Bug 定位到此完成.

结论:

页面加载时没有调用对应的 hits 更新操作, 所以浏览次数并不会进行自增. 修复也很简单. 使用 AJAX 调用此接口即可.