php原始碼之路第二章第二節(SAPI概述之嵌入式)

2021-07-23 19:46:22 字數 2976 閱讀 7447

嵌入式php類似cli,也是sapi介面的另一種實現。一般情況下,它的乙個請求的生命週期也會和其它的sapi一樣:模組初始化=>請求初始化=>處理請求=>關閉請求=>關閉模組。當然,這只是理想情況。因為特定的應用由自己特殊的需求,只是在處理php指令碼這個環節基本一致。
#include 

#ifdef zts

void ***tsrm_ls;

#endif

/* extension bits */

zend_module_entry php_mymod_module_entry = ;

/* embedded bits */

static

void startup_php(void)

; php_embed_init(argc, argv ptsrmls_cc);

zend_startup_module(&php_mymod_module_entry);

}static

void execute_php(char *filename)

zend_end_try();

}int main(int argc, char *argv)

startup_php();

execute_php(argv[1]);

php_embed_shutdown(tsrmls_cc);

return

0;}

上面的**類似乙個嵌入式php執行器,在這個執行器上我們可以執行php**。這段**包括了對於php嵌入式支援的宣告,啟動嵌入式php執行環境,執行php**,關閉嵌入式php執行環境。下面我們就這段**分析php對於嵌入式的支援做了哪些工作。 首先看下第一行:
#include
在sapi目錄下的embed目錄是php對於嵌入式的抽象層所在。在這裡有我們所要用到的函式或巨集定義。如示例中所使用的php_embed_init,php_embed_shutdown等函式。

第2到4行:

#ifdef zts

void ***tsrm_ls;

#endif

zts是zend thread safety的簡寫,與這個相關的有乙個tsrm(執行緒安全資源管理)。

第6到17行:

zend_module_entry php_mymod_module_entry = ;
以上php內部的模組結構宣告,此處對於模組初始化,請求初始化等函式指標均為null,也就是模組在初始化及請求開始結束等事件發生的時候不執行任何操作。不過這些操作在sapi/embed/php_embed.c檔案中的php_embed_shutdown等函式中有體現。關於模組結構的定義在zend/zend_modules.h中。

startup_php函式:

static

void startup_php(void)

;

php_embed_init(argc, argv ptsrmls_cc);

zend_startup_module(&php_mymod_module_entry);

}

從函式的名稱來看,這個函式的功能是執行php**的。它通過呼叫spprintf函式構造乙個include語句,然後再呼叫zend_eval_string函式執行這個include語句。 

zend_eval_string最終是呼叫zend_eval_stringl函式,這個函式是流程是乙個編譯php**,生成zend_op_array型別資料,並執行opcode的過程。這段程式相當於下面的這段php程式,這段程式可以用php命令來執行,雖然下面這段程式沒有實際意義,而通過嵌入式php中,你可以在乙個用c實現的系統中嵌入php,然後用php來實現功能。

<?php

if($argc

< 2) die("usage: embed4 scriptfile");

include

$argv[1];

main函式:

int main(int argc, char *argv)

startup_php();

execute_php(argv[1]);

php_embed_shutdown(tsrmls_cc);

return

0;}

這個函式是主函式,執行初始化操作,根據輸入的引數執行php的include語句,最後執行關閉操作,返回。其中php_embed_shutdown函式定義在sapi/embed/php_embed.c檔案中。它完成了php對於嵌入式的關閉操作支援。包括請求關閉操作,模組關閉操作等。

以上是使用php的嵌入式方式開發的乙個簡單的php**執行器,它的這些呼叫的方式都基於php本身的一些實現,而針對嵌入式的sapi定義是非常簡單的,沒有apache和cgi模式的複雜,或者說是相當簡陋,這也是由其所在環境決定。在嵌入式的環境下,很多的網路協議所需要的方法都不再需要。如下所示,為嵌入式的模組定義。

sapi_module_struct php_embed_module = ;

/* }}} */

在這個定義中我們看到了若干的null定義,在前面一小節中說到sapi時,我們是以cookie的讀取為例,在這裡也有讀取cookie的實現——php_embed_read_cookies函式,但是這個函式的實現是乙個空指標null。

而這裡的flush實現與apache的不同:

static

void php_embed_flush(void *server_context)

}

第二章 第二節 注釋

零 怎麼編寫注釋 編寫注釋的方式有三種 1.以 開頭 2.以三個 開頭和結尾 3.以三個 開頭和結尾 定義乙個字串變數 name 張三 定義乙個函式 defgetname return name defsetname n param n 姓名 return name n defsetage age ...

Git學習第二章第二節

你不斷對檔案進行修改,然後不斷提交修改到版本庫里,就好比玩rpg遊戲時,每通過一關就會自動把遊戲狀態存檔,如果某一關沒過去,你還可以選擇讀取前一關的狀態。有些時候,在打boss之前,你會手動存檔,以便萬一打boss失敗了,可以從最近的地方重新開始。git也是一樣,每當你覺得檔案修改到一定程度的時候,...

作業系統第二章第二節

程序控制的基本過程 程序的建立 程序的終止 程序的阻塞與喚醒 程序的掛起和啟用 關於程序的親屬關係 系統中執行的程序並不都是孤立的,有的程序執行後,會呼叫其他程序來執行,這樣就組成了程序間的父子關係。可用 程序圖 描述乙個程序的家族關係,該圖實際就是一種有向樹。程序間的父子關係關係著資源的繼承。建立...