[譯] 給PHP開發者的PHP源碼-第一部分-源碼結構

来源:http://www.cnblogs.com/h-hq/archive/2016/02/12/5186861.html
-Advertisement-
Play Games

作為一個開發者,我發現在我的日常工作中越來越多地查看PHP的源碼。在為了弄清楚奇怪的邊界問題和為什麼某些問題應該發生的卻沒有發生而去理解背後究竟發生了什麼事情的時候非常有用。在文檔缺失、不完整或者錯誤的情況下也很有用。因此,我已經決定通過一系列的文章來分享我學到的知識,給予PHP開發者們足夠的知識去...


文章來自:http://www.aintnot.com/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)查看它的定義和它是如何工作的。保持這個節奏。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、 1、現象:我們把資料庫的字元集編碼設置為utf-8,我們通過DOS界面向表的某一列插入漢字時會遇到類似 data too long for column 'name' at row 1 的錯誤。 2、錯誤原因: 3、解決的辦法: (1)set names gbk;(只對當前視窗有效) (2)找
  • 如何獲取 GemFire 8.2 安裝介質,以及在CentOS和Mac OS X的安裝過程。
  • -- 修改欄位 alter table emp MODIFY dept_id int; -- 刪除欄位 alter table emp drop COLUMN dept_id; 之前就當是 熱身了,跟著這個老師 你會覺得 真的能學到很多東西。要好好努力了! 上面兩個語句是通用性很強的語句。是 在 o
  • --1.sp_databas:列出伺服器上的所有資料庫信息,包括資料庫名稱和資料庫大小 exec sp_databases --2.sp_helpdb:報告有關指定資料庫或所有資料庫的信息 exec sp_helpdb --3.sp_renamedb:更改資料庫的名稱 exec sp_renamed
  • Nancy中Pipelines三兄弟(Before After OnError)的簡要概述以及多種用法。
  • 轉發至:http://www.ituring.com.cn/article/130823 導言 現代的應用程式面臨著諸多的挑戰,如何構建具有可伸縮性和高性能的應用成為越來越多軟體開發者思考的問題。隨著應用規模的不斷增大,業務複雜性的增長以及實時處理需求的增加,開發者不斷嘗試榨取硬體資源、優化。 在不
  • 原文地址 本文只是帶你進入 Scala 的世界,包括安裝、不可變變數 val、可變變數 var、定義類、集合(包括列表(list)、集(set)、映射(map))以及集合遍歷和集合庫(能達到並行/併發效果)。 題外話,如果 Java 爭氣的話,還就真不會出現像 Scala 這些語言。對於函數編程風格...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...