[译] 给PHP开发者的PHP源码-第一片-源码结构

文章来源:http://www.hoohack.me/2016/02/04/phps-source-code-for-php-developers-ch

原文:http://blog.ircmaxell.com/2012/03/phps-source-code-for-php-developers.html

作为一个开发者,我发觉在自家的便工作面临逾多地翻看PHP的源码。在为做明白奇怪之边界问题和怎么某些问题应发生的倒是不曾生如错过了解背后究竟生了哟工作的上死有效。在文档缺失、不完全或者不当的景象下呢十分有因此。因此,我早已决定通过一样系列之篇章来享受自己套到之知识,给予PHP开发者们足够的学问去真正阅读PHP的C语言源码。你并不需要有C语言的根底(我们见面总结一些基础),但要有的话会再次起扶持。

立刻是其一系列的首先首稿子。在即时篇稿子,我们会谈论PHP程序的根底:在哪找到其,基本的代码结构以及局部太基础的C语言概念。需要验证的是,这同一多样文章的对象是沾源码的开卷理解能力。这意味为了过一下或多或少点,某些概念会让简化而未是最最复杂的叙述。这不会见于读造成显著的歧异,但只要您想啊源码做贡献,则还有更多之文化要补给。在自举行简化的时刻,我会尽量指出这些简化。

除此以外,这一系列文章是因5.4本的源码,在不同版本被,大部分定义都是平的,但此间,我们得对这次的文章产生一个版本的概念(为了为新的本出来后交接下的文章还易于地仍)。

那,我们可以起来了吧?

当哪里找到PHP的源码

下载PHP源码最简便易行的方式是通过PHP的SVN仓库。对于当下是文章,我们检出(check
out)了5.4的子。这对于成为PHP的战线或者确实的开支PHP(解决bugs,实现特性等等)来说是特别深的。值得注意的是,PHP社区在(这首文章在写的时段)将源码迁移到GIT仓库中。一旦迁移完成,我会更新及时首文章以达成标准。(译者注:译者翻译的当儿PHP已经搬至GIT仓库了)。

实际上,下载源码对咱们的目的吧并无是的确的中。我们不思量编辑它,我们只是怀念使其与跟她是什么样运转的。我们可下载它,然后导入到一个吓之IDE中,在这些IDE中我们得点击过到函数的定义和声明,当我发现立即比想象着稍紧。我出一个重好之缓解方案。

事实证明,PHP社区于护一个对我们来说一个异常好之家伙。那便是lxr.php.net。这第一是一个自动生成可搜索的源码列表,而且出语法高亮同函数全部起链接的。这个是我几只用来浏览C源码的工具,实在太棒(即使以自写补丁的时,我仍交lxr而无是自身正在开发之代码库)。我们尚免见面说到怎样做更使得之找,但我们见面以谈论PHP核心函数的当儿说到。

自此间开始,我们拿开谈论PHP5.4。为了达成这目的,我们会采取这个lxr链接作其它文章的根基。当自己提到“5.4底到底目录”的早晚,我便是这页面。

那么,既然我们得以查看源码目录了,那么我们来讨论这之中都来啊吧。

PHP源码结构

这就是说,当您查看列在5.4的一干二净目录的公文以及目录时,还有很多可以研究。我想而一味关心个别个目录:ext和Zend。其他的文书与目录对于PHP扩展和开发以来非常重要,但对于我们的目的吧,我们全好忽略它。那么,为什么这半单目录那么重大呢?

PHP程序于分为,你猜对了,两独关键的片。第一有是Zend引擎,控制PHP代码运行时候的运行条件。它处理PHP提供的兼具“语言层”的特征,包括:变量,表达式,语法解析,代码执行和错误处理。没有此引擎,就不曾PHP。引擎的源码放在了Zend目录。

PHP第二独中心之片段,是富含在PHP里面的壮大。这些扩展包括我们得当PHP调用的各国一个骨干函数(例如strpos,substr,array_diff,mysql_connect等等)。也囊括基本之近乎(MySQLi,SplFixedArray,PDO等等)。

当核心代码中,决定于哪里找到您想翻的成效最简便易行的法子是,查看PHP的文档首页。PHP的文档也深受分为两单关键的有些(为了达成我们的目的),言语参考和函数参考。作为一个极大之统揽,如果你想查看的是于语言参考中的概念,很有或可以于Zend文件夹找到。如果是以函数参考中,可以在ext文件夹着找到。

部分中心的C语言概念

立即有非是为成为C的入门,而是一个“读者的配套指南”。有如下概念:

变量

于C里面,变量是静态和强类型的。这代表变量必须使动一个类型定义之后才能够利用。一旦定义之后,你莫能够改变它的项目(你得当此后换成为外类,但你需要使用不同的变量来贯彻)。因为,在C语言里面,变量并无实地存。它们才是为我们使用的惠及的内存地址的价签。正缘如此,C语言没有PHP中的援。取而代之,它起指针。为了我们的目的,把指针想象成指于任何变量的变量。把其当作PHP中变量的变量。

那,通过地方的讲述,我们来谈谈一下变量的语法。C语言没有应用其它的前缀来标识变量。因此,要说出它们的不同的唯一方式(为了达到我们的目的)是查其的概念。如果你在函数的顶部(或者函数的声明)看到在品种和空格之后的字符,那就是是变量。一个要是证实的关键点是变量名前可发一个或者这差不多单记号。星号(*)表明变量是凭于某个项目的指针(一个援)。两只星号表明变量是凭借于指针的指针。三单星号表明变量是靠于一个对任何指针的指针。

是间接寻址非常重大,因为PHP内部以多的双层指针。这是坐引擎需要会传递块数据(PHP变量),和享有有趣的档次如PHP引用,写时复制和对象引用等等。因此,只要发觉及**ptr意味着我们正利用简单重叠的援(不是变量的援,而是一个数码援引的援)。这还要好几糊弄,但万一引用对君吧是全新的学问,我建议你读书一下当即面的文化(尽管我们的目的是毫不必需阅读C)。会产生协助的。

现在,另一个知晓指针的政工是其是哪些在C的数组里采取之(不是PHP的一再组,而是C语言中之数组)。因为指针是内存地址,我们得以经过分配一片的内存来定义一个累组,然后通过递增指针来遍历它。正常状态下,我们得以以代表一个字符(8号)的C的数据类型char来存储字符串中的一个字符。但咱吧得以像下数组那样使其来走访字符串后面的字节。因此,我们可以独自于首先独字节里储存一个指南针而无是储存正一个字符串在变量中。然后,我们可以递增指针(增加其的内存地址)来遍历整个字符串。

char *foo = "test"; // foo 是指向"t"在内存的片段保存"test"的指针 // 要访问"e",我们可以通过下面的方式: char e = foo[1]; char e = *(foo + 1); char e = *(++foo);

倘若另外阅读C语言重点的变量和指针,查看这本那个好的免费图书。

先处理说明

C在编译之前以同一步叫做“预处理”的步调。这同样步包含优化以及依据你传递给编译器的挑三拣四项动态下有代码。我们用讨论两独重要的预处理器说明:条件语句和宏。

标准语句允许代码在编译输出或者无是因概念时给引入。这看起非常像下的例证。这允许不同之代码根据不同的操作系统为采用(因此尽管它采取不同之API,也得于Windows和Linux中酷好之运用)。另外,它同意一部分代码被引入或者无是根据概念的指示。事实上,这是布置步骤中争编译PHP的施行过程。

#define FOO 1 #if FOO Foo is defined and not 0 #else Foo is not defined or is 0 #endif #ifdef FOO Foo is defined #else Foo is not defined #endif

外一个说明自己给它做宏。这是极简便易行简化代码的迷你函数。它们不是确实的函数,但是于编译预处理是会见实行简单的公文替换。因此,宏不见面真的地调用函数。你可以吗函数定义写一个翻天覆地(事实上,PHP就是这样做的,但咱会于后边的篇章被深深了解这个)。我想说的凡,宏允许在先行处理编译时利用更简单的代码。

#define FOO(a) ((a) + 1) int b = FOO(1); // Converted to int b = 1 + 1

源文件

最终这同样片,我们用了解的凡简单种植于C源码使用的门类的文件。主要出零星栽文件:.c和.h。.c文件是含了源码准备编译的文件。通常来说,.c文件包含了无克分享至其他文件的私函数的兑现。.h(或者说头文件)定义了以.c文件被可以让其他文件看到底函数,包括预处理宏。头文件定义公共API的不二法门,是由此不以函数体重新声明函数的签(跟PHP中之接口及架空方法一般)。这样,源码就可由此头文件链接于联合了。

下一部分

夫系列的下一部分文章,我们即将讨论中函数在C里面是怎定义之。因此而得跨到自由的其中函数(比如strlen)查看其的定义及其是怎工作之。保持这个点子。