百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

后端开发干货:PHP源码阅读技巧

wptr33 2025-01-03 19:19 10 浏览

作者:张勇,腾讯IEG后台开发工程师

写在前面

时光匆匆 光阴似箭,今年已经是小张做码农的第N个年头了,得益于世界上最好的语言(PHP),小张的头发依旧茂密。但是项目写了一个又一个,PHP、swoole用到飞起,这些年的成长却大不如从前。

你是否也纠结于此,今天让我们换个角度看PHP,打开源码从C的角度看PHP,看一眼这个具有20年历史的庞大C项目是如何工作的。

从这一刻开始,你将荣升为C程序员,你可以去温习一下C的语法、结构体、指针和引用。

你也许会问,看个代码git拉一下用sublime打开不就好了吗,为什么要写个KM。确实这样可以看代码,但那叫看代码片段,不是看工程。PHP项目需要兼容Windows、Linux、Mac平台还要处理线程安全,其代码包含大量宏定义。我们需要借助IDE的自动跳转和提示才能更好的阅读。

我们需要一个IDE无错误提示的项目。(当你要看一个方法却无法跳转的时候,真是太难受了)

devCloud配置

devCloud是内部用于开发调试的linux虚拟机。没有的小伙伴可以自己准备一台可以ssh的CentOS虚拟机,本地虚拟机或云平台都可以。(最好网络能好一点,后面要传不少东西)

cmake re2c

后面我们需要使用Clion作为C项目的IDE,Clion需要使用cmake作为项目自动化构建工具。所以我们首先需要安装cmake devCloud上的yum默认的cmake版本为2.8.12.2符合要求,这里就直接用yum安装。

yum install cmake

re2c 是语法生成器

yum install re2c

gdb

devCloud的gdb版本过低,这里需要手动安装一个符合要求的版本,我选了7.8.2

wget http://ftp.gnu.org/gnu/gdb/gdb-7.8.2.tar.gz
tar zxvf gdb-7.8.2.tar.gz
cd gdb-7.8.2
./configure
make
make install


代码拉取

选择一个php版本,这里我用7.1.33版本。 有几个理由:

1.项目中使用了这个版本。

2.php7对内核做了大量的改动,之前的php5已经不适合学习了。

3.后续会介绍的书籍也是基于php7.0的版本和php7.1比较接近。

4.php8目前还在测试,且和php7比较接近。

注意:本地远程都拉取一份,要保持tag一致,两边都要执行下面的cmake改造

git clone https://github.com/php/php-src.git
cd php-src
git tag -l
git checkout php-7.1.33

Clion配置

工欲善其事必先利其器,要看代码需要选一个好的IDE,多年使用PhpStorm的我推荐使用全家桶里面的Clion。一般我们不会直接使用Linux做桌面系统,这里使用Clion的远程部署功能配合devCloud做环境部署。我的本地是Windows环境,构建编译在远端的devCloud进行。(用WSL也是一样的,但是PHP的git仓库太大在WSL中做git操作非常卡,应该是WSL文件系统的bug)

PHP cmake改造

这一步是阻止大部分同学使用Clion查看PHP源码的主要原因。PHP项目由于历史悠久一直使用autoconfig作为项目自动管理工具。然而Clion并不支持autoconfig,它需要项目使用cmake构建,因此我们需要对php的源码做cmake构建改造。

https://wiki.php.net/internals/cmake 官网有一份cmake的改造文档。

https://github.com/gloob/php-cmake github上也有对应的代码。

但是这个文档和代码都太老了,应该是PHP5年代的代码。我对这个项目做了一些升级,兼容了PHP7(水平有限可能存在问题,欢迎提PR)。

在本地执行如下命令,clone php-cmake项目,切换分支,拷贝php-cmake/cmake中的所有文件到php源代码目录。注意目录合并。

git clone https://github.com/bobzhangyong/php-cmake
cd php-cmake
git checkcout feature/support_php_7_1
cp -r cmake/* ../php-src //这里是php源码的路径

Toolchains配置

这里设置远程机器的信息,设置相关工具的路径。一般会自己识别,如果不能识别可以手动输入。会检查版本,默认devCloud上的版本好像都不正确需要自己升级。

Deployment配置

这里需要设置代码同步的目录,设置好以后点按√好设置为默认。完成上面Toolchains设置后,这里可能默认出现一个devCloud的信息,但是Mappings 里面的Deployment path是/tmp/目录下面,你可以删除自己配置,也可以直接修改Deployment path到你需要的项目目录。

注意:这里的Local path如果是windows上需要使用/分割路径,不是windows默认的\,否则在执行cmake构建的时候会提示目录无法找到。

在Options里面可以设置 不要同步.phpt文件,这是php项目中的测试用例文件。(我们在拉代码的时候其实已经会手动保证本地和远程机器的文件一致,但是Clion还会自己同步一次,设置这个可以加速同步速度。)

同步代码到devCloud。首次同步真的很慢,你需要耐心等待。

执行cmake构建,看看报错不?

由于PHP cmake构建会在远端生成一些文件,我们需要同步这些文件到本地,否则打开代码会因为这部分.c .h文件不存在导致代码没有提示,各种报错。

选择比对方式 用Size adn Timestamp 会快一点,这里比较慢,耐心等待一下。

分析完成以后,就可以看到远程比本地多的文件了,我们需要把他们同步到本地。最上面的.clion.source.upload.marker 不需要同步,可以点击红框中的箭头取消。 之后点击同步。

打开php_cli.c看看源码,是不是干干净净一个红线都没有。

断点

光看肯定是不行的,最好能把代码跑起来 打个断点可以更深入的了解运行机制。你可以用gdb去断点。我这里既然用了clion就直接用clion的断点功能,用起来更直观。

1、准备一个yong.php 写一点代码用来做测试文件。

2、这里配置运行配置。

3、设置 arguments 和 Working directory

4、把yong.php文件同步到远端。执行以下看看。

5、打断点。真的很爽~~

开始阅读

目录结构

PHP项目有很多目录,大概功能如下:

├── CMake //用于cmake构建的文件,我们做cmake 改造的时候拷贝进去的。
├── TSRM //线程安全相关,你如果刚开始看就先忽略 不要看了
├── Zend //Zend内核的代码
├── appveyor //一些脚本 忽略
├── build //autoconf 构建用脚本 忽略
├── cmake-build-debug //cmake构建后产物 忽略
├── ext //扩展目录,这块可以找感兴趣的扩展看一下
├── main //主要的php逻辑 
├── netware //用于兼容Netware操作系统的 直接忽略
├── pear //忽略
├── sapi //入口部分,fpm cgi 都在这里,我们可以先看一下cgi目录
├── scripts //脚本忽略
├── tests //测试用例 忽略
├── travis //构建用 忽略
└── win32 //兼容windows系统 忽略

其实和源代码相关的 只有这几个目录, 在Clion中标记为Source和Header目录方便IDE构建索引。

main
ext\standard
sapi\cli
Zend

从哪里开始

准备工作都做好了,还有借口不看代码吗?如果你还是不知道从哪里开始,那我推荐从main函数开始吧。 它在sapi\cli\php_cli.c的最后面。 附图一张可以和源代码结合起来看。 图片引自:https://github.com/pangudashu/php7-internal/blob/master/1/base_process.md

最后推荐一本书 秦朋 的 《PHP7内核剖析》

相关推荐

【推荐】一款开源免费、美观实用的后台管理系统模版

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍...

Android架构组件-App架构指南,你还不收藏嘛

本指南适用于那些已经拥有开发Android应用基础知识的开发人员,现在想了解能够开发出更加健壮、优质的应用程序架构。首先需要说明的是:AndroidArchitectureComponents翻...

高德地图经纬度坐标批量拾取(高德地图批量查询经纬度)

使用方法在桌面上新建一个index.txt文件,把下面的代码复制进去保存,再把文件名改成index.html保存,双击运行打开即可...

flutter系列之:UI layout简介(flutter ui设计)

简介对于一个前端框架来说,除了各个组件之外,最重要的就是将这些组件进行连接的布局了。布局的英文名叫做layout,就是用来描述如何将组件进行摆放的一个约束。...

Android开发基础入门(一):UI与基础控件

Android基础入门前言:...

iOS的布局体系-流式布局MyFlowLayout

iOS布局体系的概览在我的CSDN博客中的几篇文章分别介绍MyLayout布局体系中的视图从一个方向依次排列的线性布局(MyLinearLayout)、视图层叠且停靠于父布局视图某个位置的框架布局(M...

TDesign企业级开源设计系统越发成熟稳定,支持 Vue3 / 小程序

TDesing发展越来越好了,出了好几套组件库,很成熟稳定了,新项目完全可以考虑使用。...

WinForm实现窗体自适应缩放(winform窗口缩放)

众所周知,...

winform项目——仿QQ即时通讯程序03:搭建登录界面

上两篇文章已经对CIM仿QQ即时通讯项目进行了需求分析和数据库设计。winform项目——仿QQ即时通讯程序01:原理及项目分析...

App自动化测试|原生app元素定位方法

元素定位方法介绍及应用Appium方法定位原生app元素...

61.C# TableLayoutPanel控件(c# tabcontrol)

摘要TableLayoutPanel在网格中排列内容,提供类似于HTML元素的功能。TableLayoutPanel控件允许你将控件放在网格布局中,而无需精确指定每个控件的位置。其单元格...

想要深入学习Android性能优化?看完这篇直接让你一步到位

...

12个python数据处理常用内置函数(python 的内置函数)

在python数据分析中,经常需要对字符串进行各种处理,例如拼接字符串、检索字符串等。下面我将对python中常用的内置字符串操作函数进行介绍。1.计算字符串的长度-len()函数str1='我爱py...

如何用Python程序将几十个PDF文件合并成一个PDF?其实只要这四步

假定你有一个很无聊的任务,需要将几十个PDF文件合并成一个PDF文件。每一个文件都有一个封面作为第一页,但你不希望合并后的文件中重复出现这些封面。即使有许多免费的程序可以合并PDF,很多也只是简单的将...

Python入门知识点总结,Python三大数据类型、数据结构、控制流

Python基础的重要性不言而喻,是每一个入门Python学习者所必备的知识点,作为Python入门,这部分知识点显得很庞杂,内容分支很多,大部分同学在刚刚学习时一头雾水。...