PHP核心--源碼安裝與介紹____PHP

來源:互聯網
上載者:User

擷取PHP源碼 為了學習PHP的實現,首先需要下載PHP的原始碼。下載源碼首選是去 PHP官方網站http://php.net/downloads.php下載, 如果你喜歡使用svn/git等版本控制軟體,也可以使用svn/git來擷取最新的原始碼。
# git 官方地址git clone https://git.php.net/repository/php-src.git# 也可以訪問github官方鏡像git clone git://github.com/php/php-src.gitcd php-src && git checkout PHP-5.3 # 簽出5.3分支


PHP源碼目錄結構 俗話講:重劍無鋒,大巧不工。PHP的源碼在結構上非常清晰。下面先簡單介紹一下PHP源碼的目錄結構。 根目錄: / 這個目錄包含的東西比較多,主要包含一些說明檔案以及設計方案。 其實項目中的這些README檔案是非常值得閱讀的例如: /README.PHP4-TO-PHP5-THIN-CHANGES 這個檔案就詳細列舉了PHP4和PHP5的一些差異。 還有有一個比較重要的檔案/CODING_STANDARDS,如果要想寫PHP擴充的話,這個檔案一定要閱讀一下, 不管你個人的代碼風格是什麼樣,怎麼樣使用縮排和花括弧,既然來到了這樣一個團體裡就應該去適應這樣的規範,這樣在閱讀代碼或者別人閱讀你的 代碼是都會更輕鬆。 build 顧名思義,這裡主要放置一些和源碼編譯相關的一些檔案,比如開始構建之前的buildconf指令碼等檔案,還有一些檢查環境的指令碼等。 ext 官方擴充目錄,包括了絕大多數PHP的函數的定義和實現,如array系列,pdo系列,spl系列等函數的實現,都在這個目錄中。個人寫的擴充在測試時也可以放到這個目錄,方便測試和調試。 main 這裡存放的就是PHP最為核心的檔案了,主要實現PHP的基本設施,這裡和Zend引擎不一樣,Zend引擎主要實現語言最核心的語言運行環境。 Zend Zend引擎的實現目錄,比如指令碼的詞法文法解析,opcode的執行以及擴充機制的實現等等。 pear “PHP 擴充與應用倉庫”,包含PEAR的核心檔案。 sapi 包含了各種伺服器抽象層的代碼,例如apache的mod_php,cgi,fastcgi以及fpm等等介面。 TSRM PHP的安全執行緒是構建在TSRM庫之上的,PHP實現中常見的*G宏通常是對TSRM的封裝,TSRM(Thread Safe Resource Manager)安全執行緒資源管理員。 tests PHP的測試指令碼集合,包含PHP各項功能的測試檔案 win32 這個目錄主要包括Windows平台相關的一些實現,比如sokcet的實現在Windows下和*Nix平台就不太一樣,同時也包括了Windows下編譯PHP相關的指令碼。  

PHP中的全域變數宏 在PHP的源碼中經常會看到的一些很常見的宏,或者有些對於才開始接觸源碼的讀者比較難懂的代碼。 這些代碼在PHP的源碼中出現的頻率極高,基本在每個模組都會有他們的身影。
在PHP代碼中經常能看到一些類似PG(), EG()之類的函數,他們都是PHP中定義的宏,這系列宏主要的作用是解決安全執行緒所寫的全域變數包裹宏, 如$PHP_SRC/main/php_globals.h檔案中就包含了很多這類的宏。例如PG這個PHP的核心全域變數的宏。 如下所示代碼為其定義。
#ifdef ZTS   // 編譯時間開啟了安全執行緒則使用安全執行緒庫# define PG(v) TSRMG(core_globals_id, php_core_globals *, v)extern PHPAPI int core_globals_id;#else# define PG(v) (core_globals.v) // 否則這其實就是一個普通的全域變數extern ZEND_API struct _php_core_globals core_globals;#endif

如上,ZTS是安全執行緒的標記,這個在以後的章節會詳細介紹,這裡就不再說明。下面簡單說說,PHP運行時的一些全域參數, 這個全域變數為如下的一個結構體,各欄位的意義如欄位後的注釋:
struct _php_core_globals {        zend_bool magic_quotes_gpc; //  是否對輸入的GET/POST/Cookie資料使用自動字串轉義。        zend_bool magic_quotes_runtime; //是否對運行時從外部資源產生的資料使用自動字串轉義        zend_bool magic_quotes_sybase;  //   是否採用Sybase形式的自動字串轉義         zend_bool safe_mode;    //  是否啟用安全模式         zend_bool allow_call_time_pass_reference;   //是否強迫在函數調用時按引用傳遞參數        zend_bool implicit_flush;   //是否要求PHP輸出層在每個輸出塊之後自動重新整理資料         long output_buffering;  //輸出緩衝區大小(位元組)         char *safe_mode_include_dir;    //在安全模式下,該組目錄和其子目錄下的檔案被包含時,將跳過UID/GID檢查。        zend_bool safe_mode_gid;    //在安全模式下,預設在訪問檔案時會做UID比較檢查        zend_bool sql_safe_mode;        zend_bool enable_dl;    //是否允許使用dl()函數。dl()函數僅在將PHP作為apache模組安裝時才有效。         char *output_handler;   // 將所有指令碼的輸出重新導向到一個輸出處理函數。         char *unserialize_callback_func;    // 如果解序列化處理器需要執行個體化一個未定義的類,這裡指定的回呼函數將以該未定義類的名字作為參數被unserialize()調用,        long serialize_precision;   //將浮點型和雙精確度型資料序列化儲存時的精度(有效位元)。         char *safe_mode_exec_dir;   //在安全模式下,只有該目錄下的可執行程式才允許被執行系統程式的函數執行。         long memory_limit;  //一個指令碼所能夠申請到的最大記憶體位元組數(可以使用K和M作為單位)。        long max_input_time;    // 每個指令碼解析輸入資料(POST, GET, upload)的最大允許時間(秒)。         zend_bool track_errors; //是否在變數$php_errormsg中儲存最近一個錯誤或警告訊息。        zend_bool display_errors;   //是否將錯誤資訊作為輸出的一部分顯示。        zend_bool display_startup_errors;   //是否顯示PHP啟動時的錯誤。        zend_bool log_errors;   // 是否在記錄檔裡記錄錯誤,具體在哪裡記錄取決於error_log指令        long      log_errors_max_len;   //設定錯誤記錄檔中附加的與錯誤資訊相關聯的錯誤源的最大長度。        zend_bool ignore_repeated_errors;   //   記錄錯誤記錄檔時是否忽略重複的錯誤資訊。        zend_bool ignore_repeated_source;   //是否在忽略重複的錯誤資訊時忽略重複的錯誤源。        zend_bool report_memleaks;  //是否報告記憶體流失。        char *error_log;    //將錯誤記錄檔記錄到哪個檔案中。         char *doc_root; //PHP的”根目錄”。        char *user_dir; //告訴php在使用 /~username 開啟指令碼時到哪個目錄下去找        char *include_path; //指定一組目錄用於require(), include(), fopen_with_path()函數尋找檔案。        char *open_basedir; // 將PHP允許操作的所有檔案(包括檔案自身)都限制在此組目錄列表下。        char *extension_dir;    //存放擴充庫(模組)的目錄,也就是PHP用來尋找動態擴充模組的目錄。         char *upload_tmp_dir;   // 檔案上傳時存放檔案的臨時目錄        long upload_max_filesize;   // 允許上傳的檔案的最大尺寸。         char *error_append_string;  // 用於錯誤資訊後輸出的字串        char *error_prepend_string; //用於錯誤資訊前輸出的字串         char *auto_prepend_file;    //指定在主檔案之前自動解析的檔案名稱。        char *auto_append_file; //指定在主檔案之後自動解析的檔案名稱。         arg_separators arg_separator;   //PHP所產生的URL中用來分隔參數的分隔字元。         char *variables_order;  // PHP註冊 Environment, GET, POST, Cookie, Server 變數的順序。         HashTable rfc1867_protected_variables;  //  RFC1867保護的變數名,在main/rfc1867.c檔案中有用到此變數         short connection_status;    //  串連狀態,有三個狀態,正常,中斷,逾時        short ignore_user_abort;    //  是否即使在使用者中止請求後也堅持完成整個請求。         unsigned char header_is_being_sent; //  是否頭資訊正在發送         zend_llist tick_functions;  //  僅在main目錄下的php_ticks.c檔案中有用到,此處定義的函數在register_tick_function等函數中有用到。         zval *http_globals[6];  // 存放GET、POST、SERVER等資訊         zend_bool expose_php;   //  是否展示php的資訊         zend_bool register_globals; //  是否將 E, G, P, C, S 變數註冊為全域變數。        zend_bool register_long_arrays; //   是否啟用舊式的長式數組(HTTP_*_VARS)。        zend_bool register_argc_argv;   //  是否聲明$argv和$argc全域變數(包含用GET方法的資訊)。        zend_bool auto_globals_jit; //  是否僅在使用到$_SERVER和$_ENV變數時才建立(而不是在指令碼一啟動時就自動建立)。         zend_bool y2k_compliance;   //是否強制開啟2000年適應(可能在非Y2K適應的瀏覽器中導致問題)。         char *docref_root;  // 如果開啟了html_errors指令,PHP將會在出錯資訊上顯示超串連,        char *docref_ext;   //指定檔案的副檔名(必須含有’.')。         zend_bool html_errors;  //是否在出錯資訊中使用HTML標記。        zend_bool xmlrpc_errors;            long xmlrpc_error_number;         zend_bool activated_auto_globals[8];         zend_bool modules_activated;    //  是否已經啟用模組        zend_bool file_uploads; //是否允許HTTP檔案上傳。        zend_bool during_request_startup;   //是否在請求初始化過程中        zend_bool allow_url_fopen;  //是否允許開啟遠程檔案        zend_bool always_populate_raw_post_data;    //是否總是產生$HTTP_RAW_POST_DATA變數(原始POST資料)。        zend_bool report_zend_debug;    //  是否開啟zend debug,僅在main/main.c檔案中有使用。         int last_error_type;    //  最後的錯誤類型        char *last_error_message;   //  最後的錯誤資訊        char *last_error_file;  //  最後的錯誤檔案        int  last_error_lineno; //  最後的錯誤行         char *disable_functions;    //該指令接受一個用逗號分隔的函數名列表,以禁用特定的函數。        char *disable_classes;  //該指令接受一個用逗號分隔的類名列表,以禁用特定的類。        zend_bool allow_url_include;    //是否允許include/require遠程檔案。        zend_bool exit_on_timeout;  //  逾時則退出#ifdef PHP_WIN32        zend_bool com_initialized;#endif        long max_input_nesting_level;   //最大的嵌套層數        zend_bool in_user_include;  //是否在使用者包含空間         char *user_ini_filename;    //  使用者的ini檔案名稱        long user_ini_cache_ttl;    //  ini緩衝到期限制         char *request_order;    //  優先順序比variables_order高,在request變數產生時用到,個人覺得是曆史遺留問題         zend_bool mail_x_header;    //  僅在ext/standard/mail.c檔案中使用,        char *mail_log;         zend_bool in_error_log;};
上面的欄位很大一部分是與php.ini檔案中的配置項對應的。 在PHP啟動並讀取php.ini檔案時就會對這些欄位進行賦值, 而使用者空間的ini_get()及ini_set()函數操作的一些配置也是對這個全域變數進行操作的。 在PHP代碼的其他地方也存在很多類似的宏,這些宏和PG宏一樣,都是為了將安全執行緒進行封裝,同時通過約定的 G 命名來表明這是全域的, 一般都是個縮寫,因為這些全域變數在代碼的各處都會使用到,這也算是減少了鍵盤輸入。 我們都應該 儘可能的懶不是麼。 如果你閱讀過一些PHP擴充話應該也見過類似的宏,這也算是一種代碼規範,在編寫擴充時全域變數最好也使用這種方式命名和包裹, 因為我們不能對使用者的PHP編譯條件做任何假設。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.