前言

在看代码的时候遇到了PHP的一些函数,有些函数的特性很魔性,并不好理解。

于是尝试搭建环境对PHP源码进行调试,希望更加深入的一些理解PHP的特性。

必备安装

目标:在Windows环境下,构建PHP7.2的源代码编译和调试环境

安装VisualStudio

首先需要安装最强IDEVisual Studio,这个软件的版本有很多,我选择的是Visual Studio Professional 2017 (version 15.7)。 下载链接:

ed2k://|file|mu_visual_studio_professional_2017_version_15.3_x86_x64_11100064.exe|1069960|900673A59F0798822207F72FAA0DA6A9|/

需要其他版本(VS2015等),可以到MSDN上的开发人员工具栏目自行选择下载即可。

安装过程非常简单,注意两个调试必备勾选,其他的选项根据自己需求选择

php-sdk

PHP SDK是用于Windows PHP构建的工具包,也是必不可少的工具。 下载地址:

https://github.com/Microsoft/php-sdk-binary-tools

我选择的版本为最新版php-sdk-2.1.7。

PHP

本文主角,我选择的版本为PHP 7.2.1。 下载地址:

https://github.com/php/php-src

下载完成后使用Git Bash切换分支

cd php-src

git checkout PHP-7.2.1

编译PHP

进入php-sdk的目录,可以看到目录下面有4个Windows批处理文件

前面安装的是Visual Studio 2017,操作系统也是64位的,因此这里选择phpsdk-vc15-x64.bat,打算编译64位的。

在php-sdk目录打开CMD窗口,运行phpsdk-vc15-x64.bat。 可以发现有了新的Shell提示符$。

继续在新的shell下运行命令

phpsdk_buildtree phpdev

这时候我们会发现php-sdk这个目录下面会多一个名为phpdev的文件夹。

注意Shell的运行路径也发生了变化php-sdk\phpdev\vc15\x64\。

再将php-src整个文件夹移动至php-sdk\phpdev\vc15\x64\下面。

然后shell中进入php-src目录,执行命令,下载依赖关系组件。

phpsdk_deps --update --branch maste

成功信息如下:

运行buildconf.bat生成的configure文件,配置好参数,执行命令如下

configure --disable-all --enable-cli --enable-debug

成功信息如下:

执行编译命令nmake

编译成功信息为:

SAPI sapi\cli build complete

可执行的二进制文件路径为

php-sdk\phpdev\vc15\x64\php-src\x64\Debug_TS\php.exe

观察是否输出php信息,编译成功则输出

php.exe -v

调试配置

断点调试的需要一个趁手的工具,可以使用之前安装的Visual Studio 2017,但我个人选择的是轻量级的Vs code。

安装Vs code,然后这里需要安装C/C++的拓展,调试的方式为启动调试。

点击调试 --> 打开配置,设置配置文件launch.json的参数如下

program,二进制可执行文件路径。

args,同目录下运行的PHP文件,也就是我们要调试的文件

cwd,二进制可执行文件目录

点击调试按钮,即可开始调试。

调试getimagesize函数

这里选择getimagesize这个函数进行断点调试。 探究为何这个函数如何加载网络图片资源;为何这个函数在Windows下

修改调试的1.php内容如下

getimagesize("http://www.rai4over.cn/images/avatar.jpg");

#getimagesize("./avatar.jpg");

?>

在php-sdk\phpdev\vc15\x64\php-src\ext\standard\image.c中设置getimagesize的断点

点击调试后程序会停在这里则表示断点成功。 通常会使用F10,F11进行调试。 - F10,单步跳过,调试时不进入函数内部。 - F11,单步调试,调试时进入函数内部。

比较麻烦的,单纯的F11调试耗费时间,而F10又可能跳过函数关键函数,难以定位。

于是我便采F10为主,提升调试效率,一边F10,一边打开Wireshark观察HTTP请求流量。

当过某个函数产生流量后,再F11进入函数内部进行调试。

最终得到函数调用栈(由下至上):

send

php_sockop_write

_php_stream_write_buffer

_php_stream_write

php_stream_url_wrap_http_ex

php_stream_url_wrap_http

_php_stream_open_wrapper_ex

php_getimagesize_from_any

PHP_FUNCTION

send()是Windows Api,能够通过已经建立的连接发送数据。

在phpdev\vc15\x64\php-src\main\streams\xp_socket.c第77行被调用。

didwrite = send(sock->socket, buf, XP_SOCK_BUF_SIZE(count), (sock->is_blocked && ptimeout) ? MSG_DONTWAIT : 0);

这也是这个函数加载网络图片资源的原因,之前印象中一直以为只能获取本地资源,踩过大坑。

修改为获取本地图片资源

#getimagesize("http://www.rai4over.cn/images/avatar.jpg");

getimagesize("./avatar.jpg");

?>

函数栈调用

在php-sdk\phpdev\vc15\x64\php-src\Zend\zend_virtual_cwd.c第841行,发现调用了FindFirstFileExW()函数。

hFind = FindFirstFileExW(pathw, FindExInfoBasic, &dataw, FindExSearchNameMatch, NULL, 0);

这个函数就是

ed2k解析源码php,PHP源码调试分析相关推荐

  1. 【转】Android事件分发机制完全解析,带你从源码的角度彻底理解(下)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9153761 记得在前面的文章中,我带大家一起从源码的角度分析了Android中Vi ...

  2. [学习总结]7、Android AsyncTask完全解析,带你从源码的角度彻底理解

    我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制.之前我也写过了一篇文章从源码层面分析了Android的异步消息处理机制,感兴 ...

  3. 接码平台源码_你的票被服务器上的爬虫“吃”了,本文解析爬虫抢票的源码!...

    过年啦!黄牛们又开始猖獗了,我们为什么总是抢不到票?实际上票都被黄牛们部署在云服务器上的脚本不断刷着!我们手再快能快过爬虫吗?成都七中chengqigou清华大学shu20200124888.8张铁柱 ...

  4. BAT高级架构师合力熬夜15天,肝出了这份PDF版《Android百大框架源码解析》,还不快快码住。。。

    前言 为什么要阅读源码? 现在中高级Android岗位面试中,对于各种框架的源码都会刨根问底,从而来判断应试者的业务能力边际所在.但是很多开发者习惯直接搬运,对各种框架的源码都没有过深入研究,在面试时 ...

  5. ConcurrentHashMap源码解析_01 成员属性、内部类、构造方法分析

    文章参考:小刘源码 ConcurrentHashMap源码解析_01 成员属性.内部类.构造方法分析 1.简介 ConcurrentHashMap是HashMap的线程安全版本,内部也是使用(数组 + ...

  6. 你的票被服务器上的爬虫“吃”了,本文解析爬虫抢票的源码!

    过年啦!黄牛们又开始猖獗了,我们为什么总是抢不到票?实际上票都被黄牛们部署在云服务器上的脚本不断刷着!我们手再快能快过爬虫吗? 成都七中 chengqigou 清华大学 shu 2020 01 24 ...

  7. Android事件分发机制完全解析,带你从源码的角度彻底理解(上)

    <div id="container">         <div id="header">     <div class=&qu ...

  8. 万字长文+图文并茂+全面解析微前端框架 qiankun 源码 - qiankun 篇

    写在开头 微前端系列文章: 基于 qiankun 的微前端最佳实践(万字长文) - 从 0 到 1 篇 基于 qiankun 的微前端最佳实践(图文并茂) - 应用间通信篇 基于 qiankun 的微 ...

  9. 线程池解析(三)——Worker源码解析

    相关文章 线程池解析(一)--概念总结 线程池解析(二)--execute.addWorker源码解析 线程池解析(三)--Worker源码解析 线程池解析(四)--submit源码解析(Runnab ...

  10. AnchorFree算法-CenterNet论文解析(附论文与源码)

    AnchorFree算法-CenterNet论文解析(附论文与源码)https://mp.weixin.qq.com/s/S4d5EBci_-2FFHE_itKU2A

最新文章

  1. 不藏私分享五個線上自學平台
  2. 希捷硬盘固件修复工具_电脑升级高速硬盘后的差异竟如此大!酷鱼510性能实测...
  3. python怎么换行继续写脚本_用Python实现换行符转换的脚本的教程
  4. 瑞幸:不会死,也没有稳
  5. godaddy 管理mysql_在godaddy上使用MySQL和Entity Framework的安全例...
  6. OpenCASCADE:使用扩展数据交换 XDE之特性
  7. 面向对象设计原则之5-接口隔离原则
  8. Clojure 1.8提升了性能和开发体验
  9. OpenLayers geojson 进行展示矢量标签展示
  10. 北京各区优质高中排名
  11. 深入理解Nginx负载均衡和反向代理_学习笔记
  12. IEEE 802.11标准协议下载
  13. selenium 使用带密码的socks5代理方法
  14. 一招秒杀常见网页基本排版布局
  15. 传奇地图文件MapInfo参数大全
  16. Python如何进行中文注释
  17. python画三角函数--cosx
  18. 联想微型计算机如何设置u盘启动,联想bios设置u盘启动图文教程
  19. 【数据库】四(1)、数据查询之单表查询
  20. matlab信号的能量谱代码,信号的频谱 频谱密度 功率谱密度 能量谱密度

热门文章

  1. Python遍历文件夹下的word文档并写入内容
  2. 尝试自动批量翻译方舟编译器源码中的标识符
  3. 解决echarts canvas绘图字体不清晰的问题
  4. web端通过企业微信进行登录(获取员工信息)
  5. 读《Optimally Tuned Iterative Reconstruction Algorithms for Compressive Sensing》有感……
  6. SPOJ 25000 BOKAM143SOU - Checking cubes(dp)
  7. 从移动端爬取-贝壳数据
  8. 【CV 向】OpenCV 图形绘制指南
  9. 多比物联MQTT-BOX102 物联网MQTT网关介绍
  10. 华为云会议的开放能力