【PHP核心學習】SAPI____PHP

來源:互聯網
上載者:User

鳥哥的部落格提到了SAPI,我也來看下源碼。

-------------

php架構圖(圖片出自http://stblog.baidu-tech.com/?p=763):

中介層(sapi)解耦隔離了web server和php



每個SAPI實現都是一個_sapi_module_struct 結構體:

在php源碼目錄下用 grep -r _sapi_module_struct 搜尋到它的定義在main/SAPI.h中:

struct _sapi_module_struct {    char *name;    char *pretty_name;    int (*startup)(struct _sapi_module_struct *sapi_module);    int (*shutdown)(struct _sapi_module_struct *sapi_module);    int (*activate)(TSRMLS_D);    int (*deactivate)(TSRMLS_D);    int (*ub_write)(const char *str, unsigned int str_length TSRMLS_DC);    void (*flush)(void *server_context);    struct stat *(*get_stat)(TSRMLS_D);    char *(*getenv)(char *name, size_t name_len TSRMLS_DC);    void (*sapi_error)(int type, const char *error_msg, ...);    int (*header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC);    int (*send_headers)(sapi_headers_struct *sapi_headers TSRMLS_DC);    void (*send_header)(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC);    int (*read_post)(char *buffer, uint count_bytes TSRMLS_DC);    char *(*read_cookies)(TSRMLS_D);    void (*register_server_variables)(zval *track_vars_array TSRMLS_DC);    void (*log_message)(char *message TSRMLS_DC);    double (*get_request_time)(TSRMLS_D);    void (*terminate_process)(TSRMLS_D);    char *php_ini_path_override;    void (*block_interruptions)(void);    void (*unblock_interruptions)(void);    void (*default_post_reader)(TSRMLS_D);    void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC);    char *executable_location;    int php_ini_ignore;    int php_ini_ignore_cwd; /* don't look for php.ini in the current directory */    int (*get_fd)(int *fd TSRMLS_DC);    int (*force_http_10)(TSRMLS_D);    int (*get_target_uid)(uid_t * TSRMLS_DC);    int (*get_target_gid)(gid_t * TSRMLS_DC);    unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);    void (*ini_defaults)(HashTable *configuration_hash);    int phpinfo_as_text;    char *ini_entries;    const zend_function_entry *additional_functions;    unsigned int (*input_filter_init)(TSRMLS_D);};

下面,以cgi_sapi為例說明sapi的實現:

static sapi_module_struct cgi_sapi_module = {    "cgi-fcgi",                     /* name */    "CGI/FastCGI",                  /* pretty name */    php_cgi_startup,                /* startup 當SAPI初始化時,首先會調用該函數 */    php_module_shutdown_wrapper,    /* shutdown  關閉函數封裝器,它用來釋放所有的SAPI的資料結構、記憶體等*/    sapi_cgi_activate,              /* activate  此函數會在每個請求開始時調用,它會再次初始化每個請求前的資料結構*/    sapi_cgi_deactivate,            /* deactivate  此函數會在每個請求結束時調用,它用來確保所有的資料都,以及釋放在activate中初始化的資料結構*/    sapi_cgi_ub_write,              /* unbuffered write  不緩衝的寫操作(unbuffered write),它是用來將PHP的資料輸出給用戶端*/    sapi_cgi_flush,                 /* flush  重新整理輸出,在CLI模式下通過使用C語言的庫函數fflush實現*/    NULL,                           /* get uid */    sapi_cgi_getenv,                /* getenv */    php_error,                      /* error handler */    NULL,                           /* header handler */    sapi_cgi_send_headers,          /* send headers handler 發送頭部資訊*/    NULL,                           /* send header handler */    sapi_cgi_read_post,             /* read POST data  當請求的方法是POST時,程式會操作$_POST、$HTTP_RAW_POST_DATA等變數*/    sapi_cgi_read_cookies,          /* read Cookies  在SAPI啟用時,程式會調用此函數,並且將此函數擷取的值賦值給SG(request_info).cookie_data*/    sapi_cgi_register_variables,    /* register server variables */    sapi_cgi_log_message,           /* Log message */    NULL,                           /* Get request time */    NULL,                           /* Child terminate */    STANDARD_SAPI_MODULE_PROPERTIES};


通過上面cgi的例子,我們可以看到,整個SAPI類似於一個物件導向中的模板方法模式的應用。SAPI.c和SAPI.h檔案所包含的一些函數就是模板方法模式中的抽象模板, 各個伺服器對於sapi_module的定義及相關實現則是一個個具體的模板。


參考:

1.http://stblog.baidu-tech.com/?p=763

2.http://www.laruence.com/2008/08/12/180.html

3.http://www.nowamagic.net/librarys/veda/detail/1292




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.