文章来自:http://www.aintnot.com/2016/02/04/phps-source-code-for-php-developers-ch
作为一个开发者,我发现在我的日常工作中越来越多地查看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)查看它的定义和它是如何工作的。保持这个节奏。

PHP在現代Web開發中仍然重要,尤其在內容管理和電子商務平台。 1)PHP擁有豐富的生態系統和強大框架支持,如Laravel和Symfony。 2)性能優化可通過OPcache和Nginx實現。 3)PHP8.0引入JIT編譯器,提升性能。 4)雲原生應用通過Docker和Kubernetes部署,提高靈活性和可擴展性。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP在現代編程中仍然是一個強大且廣泛使用的工具,尤其在web開發領域。 1)PHP易用且與數據庫集成無縫,是許多開發者的首選。 2)它支持動態內容生成和麵向對象編程,適合快速創建和維護網站。 3)PHP的性能可以通過緩存和優化數據庫查詢來提升,其廣泛的社區和豐富生態系統使其在當今技術棧中仍具重要地位。

在PHP中,弱引用是通過WeakReference類實現的,不會阻止垃圾回收器回收對象。弱引用適用於緩存系統和事件監聽器等場景,需注意其不能保證對象存活,且垃圾回收可能延遲。

\_\_invoke方法允許對象像函數一樣被調用。 1.定義\_\_invoke方法使對象可被調用。 2.使用$obj(...)語法時,PHP會執行\_\_invoke方法。 3.適用於日誌記錄和計算器等場景,提高代碼靈活性和可讀性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)