如何學習 PHP 原始碼 從編譯開始

2021-09-17 06:10:14 字數 2726 閱讀 3649

php mailing lists 上這兩天有個好玩兒的問題:introduction to the php source code,大概就是有人想知道如何學習 php 原始碼,可是這種事情不是應該自己去發掘的嗎?

上面是玩笑話,現在我也說說如何學習 php 直譯器的原始碼。

從 branch 中選擇乙個版本 tag,和每次 php 發布出來的版本就是一致的。也許你會發現你想編譯的的時候缺找不到configure檔案,但是有configure.in檔案。這時候需要先執行的是buildconf(如果是在 windows 下面可以執行buildconf.bat,不過我從來沒有嘗試過在 windows 下面編譯 php,所以具體的步驟我就不清楚了)。buildconf 本身是個簡單的 shell 指令碼,你可以用記事本開啟看看它(最終的執行檔案在build目錄裡,這個目錄裡有一些與編譯有關的檔案)。

re2c 和 bison 分別是 php 用到的詞法解析器和語法分析器。在 genfiles 這個檔案中可以看到它們的呼叫其實是在makefile.frag中寫著,分別通過zend_language_scanner.lzend_language_parser.y生成相應的 c 語言檔案(這個應該很多地方都有提到過)。

到了編譯環節,編譯之前需要先通過configure檔案生成 makefile 然後執行make,所以gcc自然是必不可少的。configure 檔案本身也是乙個 shell 指令碼,你也可以簡單閱讀一下它的內容。不過既然它是由autoconfconfigure.in中生成的,也許直接檢視 configure.in 會更輕鬆一些。

到這裡總結一下就是:拋開一些核心擴充套件額依賴(比如 xml,ssl 等),編譯 php 的先決條件是機器上有 autotools 的工具(automake,autoconf 等),需要安裝 re2c 和 bison,當然還有編譯工具(gcc)。

也許大家都知道,使用configure生成 makefile 的時候可以通過--prefix引數指定目錄,同時也可以選擇編譯哪些核心模組。至於哪些模組會被預設整合而哪些不會,這些本身是寫在每個擴充套件的config.m4(也有幾個是被命名為 config0.m4 或 config9.m4)檔案裡的的,全都通過一些--enable--disable--with--without的選項來控制。

編譯的也與你採用的 web 伺服器有關,這涉及到你需要使用哪個sapi,如果是 apache,也許需要指定--with-apxs2的引數,如果是 nginx,php-fpm在預設條件下是會被編譯的,但可以指定 php-fpm 的執行組和使用者,不過這個是可以在編譯完成後在配置中修改的。

編譯完成之後還有一些事情需要考慮,最基本的問題是 php 的配置檔案的問題,還有乙個是如果使用的是 php-fpm,如何更便捷的控制它的啟動、停止以及重啟等。

在 php 原始碼根中已經準備了兩份配置檔案的模板:php.ini-developmentphp.ini-production。顯然是分別用於開發環境和生產環境的,將其中乙個複製到配置檔案目錄並重命名為php.ini即可(如果你不知道配置檔案的目錄在**,可以使用php --ini命令檢視)。然後也可以根據你的需要修改它。

至於 php-fpm 的控制指令碼,原始碼中本身也是有提供的,在sapi/fpm目錄下。這個目錄下的幾個檔案中有 php-fpm 配置檔案的模板,也有稍微修改即可放到伺服器/etc/init.d目錄下用於控制 php-fpm 的startstoprestartreload動作的指令碼,現在的版本中也提供了用於systemd的 service 檔案。

如果 php 編譯完成之後,發現還需要一些沒有編譯進去的核心擴充套件或者第三方擴充套件,你可以單獨編譯它們。

擴充套件編譯的整個過程一共四句命令:

phpize

./configure

make

make install

phpize命令是用來準備 php 擴充套件庫的編譯環境的。在執行phpize的時候,如果有多個版本的 php,用哪個就要選哪個。這個命令和編譯後的 php 的二進位制檔案在同乙個目錄中,也是乙個 shell 指令碼。

執行configure的時候,如果當前$path中找不到php-config或者有多個版本的 php 時,也需要通過--with-php-config的指令來指定 php-config 的目錄。php-config 是乙個用於獲取所安裝的 php 配置的資訊,它也一樣是和 php 的二進位制檔案在同乙個目錄的 shell 指令碼。

phpize 和 php-config 的原始碼生成檔案都是在 scripts 目錄下。

所有工作完成之後,就可以愉快的使用你自己定製的 php 了。

從原始碼編譯InfluxDB

作業系統 centos7.3.1611 x64 go語言版本 1.8.3 linux amd64 influxdb版本 1.1.0 go語言安裝參考 首先安裝git yum install git y 設定gopath 獲取依賴庫 或者使用 http proxy 127.0.0.1 1080 go ...

從原始碼編譯OPENWRT

openwrt官方站點 鏈結 要編譯openwrt首先要搞清楚它複雜的版本命名規則,可以看官方文件 鏈結 從文件中,我們可以了解到目前的最新穩定版是attitude adjustment,svn版本號為36088,發布於2013年中,而上乙個穩定版是backfire 10.03.1,發布於2011年...

從原始碼編譯InfluxDB

作業系統 centos7.3.1611 x64 go語言版本 1.8.3 linux amd64 influxdb版本 1.1.0 go語言安裝參考 首先安裝git yum install git y 設定gopath 獲取依賴庫 或者使用 http proxy 127.0.0.1 1080 go ...