程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> 設置嵌入php的宿主環境

設置嵌入php的宿主環境

編輯:PHP綜合

設置宿主環境

現在你已經了解了PHPAPI的世界, 並可以使用zval以及語言內部擴展機制執行很多工作了, 是時候轉移目標用它做它最擅長的事情了: 解釋腳本代碼.

嵌入式SAPI

回顧介紹中, php構建了一個層級系統. 最高層是提供用戶空間函數和類庫的所有擴展. 同時, 其下是服務API(SAPI)層, 它扮演了webserver(比如apache, iis以及命令行接口cli)的接口.

在這許多sapi實現中有一個特殊的sapi就是嵌入式sapi. 當這個sapi實現被構建時, 將會創建一個包含所有你已知的php和zend api函數以及變量的庫對象, 這個庫對象還包含一些額外的幫助函數和宏, 用以簡化外部程序的調用.

生成嵌入式api的庫和頭文件和其他sapi的編譯所執行的動作相同. 只需要傳遞--enable-embed到./configure命令中即可. 和以前一樣, 使用--enable-debug對於錯誤報告和跟蹤很有幫助.

你可能還需要打開--enable-maintainer-zts, 當然, 理由你已經耳熟能詳了, 它將幫助你注意到代碼的錯誤, 不過, 這裡還有其他原因. 假設某個時刻, 你有多個應用使用php嵌入庫執行腳本任務; 其中一個應用是簡單的短生命周期的, 它並沒有使用線程, 因此為了效率你可能想要關閉ZTS.

現在假設第二個應用使用了線程, 比如webserver, 每個線程需要跟蹤自己的請求上下文. 如果ZTS被關閉, 則只有第一個應用可以使用這個庫; 然而, 如果打開ZTS, 則兩個應用都可以在自己的進程空間使用同一個共享對象.

當然, 你也可以同時構建兩個版本, 並給它們不同的名字, 但是這相比於在不需要ZTS時包括ZTS帶來的很小的效率影響更多的問題.

默認情況下, 嵌入式庫將構建為libphp5.so共享對象, 或者在windows下的動態鏈接庫, 不過, 它也可能使用可選的static關鍵字(--enable-embed=static)被構建為靜態庫.

構建為靜態庫的版本避免了ZTS/非ZTS的問題, 以及潛在的可能在一個系統中有多個php版本的情況. 風險在於這就意味著你的結果應用二進制將顯著變大, 它將承載整個ZendEngine和PHP框架, 因此, 選擇的時候就需要慎重的考慮你是否需要的是一個相對更小的庫.

無論你選擇那種構建方式, 一旦你執行make install, libphp5都將被拷貝到你的./configure指定的PREFIX目錄下的lib/目錄中. 此外還會在PREFIX/include/php/sapi/embed目錄下放入名為php_embed.h的頭文件, 以及你在使用php嵌入式庫編譯程序時需要的其他幾個重要的頭文件.

構建並編譯一個宿主應用

究其本質而言, 庫只是一個沒有目的的代碼集合. 為了讓它工作, 你需要用以嵌入php的應用. 首先, 我們來封裝一個非常簡單的應用, 它啟動Zend引擎並初始化PHP處理一個請求, 接著就回頭進行資源的清理.

#include <sapi/embed/php_embed.h>  
      
int main(int argc, char *argv[])  
{  
    PHP_EMBED_START_BLOCK(argc,argv)  
    PHP_EMBED_END_BLOCK()  
      
    return 0;  
}

由於這涉及到了很多頭文件, 構建實際上需要的時間要長於這麼小的代碼片段通常需要的時間. 如果你使用了不同於默認路徑(/usr/local)的PREFIX, 請確認以下面的方式指定路徑:

gcc -I /usr/local/php-dev/include/php/   \
    -I /usr/local/php-dev/include/php/main/   \
    -I /usr/local/php-dev/include/php/Zend/   \
    -I /usr/local/php-dev/include/php/TSRM/   \
    -lphp5   \
    -o embed1   
    embed1.c

由於這個命令每次輸入都很麻煩, 你可能更原意用一個簡單的Makefile替代:

CC = gcc   
CFLAGS = -c   
    -I /usr/local/php-dev/include/php/   \
    -I /usr/local/php-dev/include/php/main/   \
    -I /usr/local/php-dev/include/php/Zend/   \
    -I /usr/local/php-dev/include/php/TSRM/   \
    -Wall -g  \
LDFLAGS = -lphp5  
      
all: embed1.c  
    $(CC) -o embed1.o embed1.c $(CFLAGS)  
    $(CC) -o embed1 embed1.o $(LDFLAGS)

這個Makefile和前面提供的命令有一些重要的區別. 首先, 它用-Wall開關打開了編譯期的警告, 並且用-g打開了調試信息. 此外它將編譯和鏈接兩個階段分為了兩個獨立的階段, 這樣在後期增加更多源文件的時候就相對容易. 請自己重新組著這個Makefile, 不過這裡用於對齊的是Tab(水平制表符)而不是空格.

現在, 你對embed1.c源文件做修改後, 只需要執行一個make命令就可以構建出新的embed1可執行程序了.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved