这两天又折腾了一下以前豆子自己修改的一个 Whois 小程序。
算起来,这个程序已经陪伴豆子十多年了。最初是从国外找来的一个 PHP 脚本,后来根据豆子自己的需要不断修改和扩展,逐渐加入了 WHOIS、DNS Lookup、Trace 路由追踪以及 DIG DNS Root 分级解析查询等功能。
这些年一直使用 PHP 7.x,程序也就这么运行了下来。
不过,随着 PHP 版本不断迭代,PHP 8.x 已经成为主流,很多旧函数和语法也发生了变化。豆子为了让这个老程序能够继续运行下去,还是决定给它做一次升级。
一、PHP 8.0~8.5 兼容性升级
这次升级主要是将原来的 PHP 代码调整为适应 PHP 8.x 的写法。
升级完成后,没有只在一个 PHP 版本上测试,而是分别进行了实际环境验证。
测试版本:
- PHP 8.0.30
- PHP 8.1.34
- PHP 8.2.35
- PHP 8.3.36
- PHP 8.4.27
- PHP 8.5.12
六个版本全部测试通过,页面显示正常,原有功能运行正常。
目前服务器已经正式切换到 PHP 8.5.12。
至于以前使用的 PHP 7.4 版本,则单独保留在 Git 仓库的 PHP 7.4 目录中,作为历史版本留档,不再部署到服务器。
二、XREA K2 的 DIG 功能适配
PHP 升级完成后,又顺便处理了一下 XREA K2 主机上的 DIG 功能。
之前发现,XREA K2 环境下,DIG 的 Trace 查询存在一些限制。
经过实际测试,最终只需要调整 functions.php 中的 app_run_dig() 函数:
修改后,在 PHP 7.4 和 PHP 8.x 环境下都进行了实际网页测试,功能正常。
依旧是熟悉的原则:能少改就少改,没有必要动其他代码。
三、XREA 的 Trace 路由追踪问题
这次真正花时间的,其实是 Trace。
原来的程序使用系统自带的 traceroute 命令进行路由追踪,但在 XREA K2 上遇到了一些限制。
最初以为只是普通的程序兼容性问题,后来经过几轮测试才发现,问题并不完全出在 PHP 代码上,而是主机本身的网络权限和运行环境限制。
于是尝试了几种不同的方式:
- 传统 UDP Traceroute。
- PHP Socket 与 ICMP 相关测试。
- TCP 方式进行路由探测。
- Python 直接运行测试。
- PHP 调用 Python 进行网页测试。
其中,纯 PHP Socket 方案遇到了一些障碍,继续折腾下去意义不大。
后来发现,Python 3 可以利用普通 TCP Socket,配合 Linux 的 IP_RECVERR 和 MSG_ERRQUEUE,通过 TCP 443 端口完成逐跳探测。
既然 Python 可以做到,那么就尝试让 PHP 调用 Python。
最终确定了一个比较简单的方案:
PHP 负责页面输入、调用和结果显示,Python 负责底层 TCP 路由探测。
Python 将探测结果通过 stdout 输出为 JSON,PHP 使用 json_decode() 解析后,再按照原来的页面格式显示。
整个过程不需要 Raw Socket 权限,也不需要第三方 Python 包。
四、最终实现效果
最终采用 TCP 443 方式,最大追踪跳数设置为 30。
不过 30 只是最大限制,并不是每次都固定输出 30 跳。只要提前到达目标,就会自动结束。
另外,中间节点如果没有响应,也不会直接终止追踪,而是继续探测后面的节点。
这几天在 XREA K2 的实际网页环境中测试了几个目标:
成功取得多跳路由节点,验证了 PHP 调用 Python 以及 JSON 解析流程。
kefu.free.fr
这个目标比较有意思,第 6 跳没有响应,显示 *,但第 7、8 跳仍然成功取得结果。
chatgpt.com
第 7 跳就已经到达目标 IP,程序自动结束,没有继续输出后面的跳数。
最终页面输出也做了简化,只保留目标域名、目标 IP、每一跳的 IP 地址和响应时间。
例如:
Tracing chatgpt.com (172.64.155.209)
1 160.251.150.2 0.24 ms
2 150.95.7.158 9.33 ms
3 150.95.7.138 0.70 ms
4 150.95.7.205 0.59 ms
5 218.100.9.25 19.23 ms
6 162.158.4.47 17.56 ms
7 172.64.155.209 17.14 ms
看起来简单多了。
五、清理测试文件,提交 Git
为了完成这次测试,网站根目录下临时创建了不少 PHP 和 Python 测试脚本。
从 UDP、ICMP、Socket 到 PHP 调用 Python,基本上每一种尝试都留下了测试文件。
测试完成后,将这些临时测试及诊断脚本保存到本地,并从服务器上全部删除。
正式运行只保留需要的文件,其中 py_tcp_trace_json.py 是 PHP 调用的正式运行依赖,当然不能删除。
最后,将这次修改提交到了 Git 仓库。
目前仓库也有了比较清晰的结构:
- 根目录:PHP 8.x 主版本。
- PHP 7.4:旧版本留档。
- Git 提交记录:分别记录 PHP 兼容性升级、DIG 适配和 TCP Traceroute 适配。
六、最后
其实这次折腾下来,最大的感受就是:
没有必要强迫主机支持自己想要的运行方式,看看它本身支持什么,然后利用现有条件达到目标就好了。
原本以为 XREA 的 Trace 功能可能要继续折腾很久,甚至考虑过是否有必要放弃。
后来换了一个思路,让 PHP 调用 Python,问题就解决了。
整个过程中,尽量保留原有程序结构,没有为了实现一个功能而大范围重写代码,也没有引入数据库、临时查询文件或者额外的第三方依赖。
算起来,从当年修改这个国外脚本,到现在已经十多年了。
这次 PHP 8.0~8.5 升级,加上 XREA K2 的 DIG 和 Trace 适配,总算让这个老程序又可以继续运行下去了。
十多年的一个小心愿,总算完成了一桩。
接下来就让它继续服役吧。
折腾可以,但没必要为了折腾而折腾。能解决问题,少改代码,就足够了。



