歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

PHP內核-Apache2的SAPI

我們知道定義SAPI之前,首先要定義sapi_module_struct這個結構,相看源碼:/soft/php-5.2.9/sapi/apache2handler/sapi_apache2.c,可以看到定義該結構,我直接復制過來:

  1. static sapi_module_struct apache2_sapi_module = {  
  2.         "apache2handler",  
  3.         "Apache 2.0 Handler",  
  4.   
  5.         php_apache2_startup,                            /* startup */  
  6.         php_module_shutdown_wrapper,                    /* shutdown */  
  7.   
  8.         NULL,                                           /* activate */  
  9.         NULL,                                           /* deactivate */  
  10.   
  11.         php_apache_sapi_ub_write,                       /* unbuffered write */  
  12.         php_apache_sapi_flush,                          /* flush */  
  13.         php_apache_sapi_get_stat,                       /* get uid */  
  14.         php_apache_sapi_getenv,                         /* getenv */  
  15.   
  16.         php_error,                                      /* error handler */  
  17.   
  18.         php_apache_sapi_header_handler,                 /* header handler */  
  19.         php_apache_sapi_send_headers,                   /* send headers handler */  
  20.         NULL,                                           /* send header handler */  
  21.   
  22.         php_apache_sapi_read_post,                      /* read POST data */  
  23.         php_apache_sapi_read_cookies,                   /* read Cookies */  
  24.   
  25.         php_apache_sapi_register_variables,  
  26.         php_apache_sapi_log_message,                    /* Log message */  
  27.         php_apache_sapi_get_request_time,               /* Request Time */  
  28.   
  29.         STANDARD_SAPI_MODULE_PROPERTIES  
  30. };  
1,php_apache2_startup:當通過apache調用PHP時,這個函數會被調用。該函數定義如下,主要是對PHP進行初始化。
  1. static int php_apache2_startup(sapi_module_struct *sapi_module)  
  2. {  
  3.         if (php_module_startup(sapi_module, &php_apache_module, 1)==FAILURE) {  
  4.                 return FAILURE;  
  5.         }  
  6.         return SUCCESS;  
  7. }  
2,php_module_shutdown_wrapper :PHP的關閉函數。

3,PHP會在每個request的時候,處理一些初始化,資源分配的事務。這部分就是activate字段要定義的。

4,與activate的函數,就是deactiveate,它會提供一個handler, 用來處理收尾工作。

5,php_apache_sapi_ub_write:提供一個向Response數據寫的接口。

  1. static int  
  2. php_apache_sapi_ub_write(const char *str, uint str_length TSRMLS_DC)  
  3. {  
  4.         request_rec *r;  
  5.         php_struct *ctx;  
  6.   
  7.         ctx = SG(server_context);  
  8.         r = ctx->r;  
  9.   
  10.         if (ap_rwrite(str, str_length, r) < 0) {  
  11.                 php_handle_aborted_connection();  
  12.         }  
  13.   
  14.         return str_length; /* we always consume all the data passed to us. */  
  15. }  

6,php_apache_sapi_flush:提供給zend刷新緩存的句柄。

  1. static void  
  2. php_apache_sapi_flush(void *server_context)  
  3. {  
  4.         php_struct *ctx;  
  5.         request_rec *r;  
  6.         TSRMLS_FETCH();  
  7.   
  8.         ctx = server_context;  
  9.   
  10.         /* If we haven't registered a server_context yet, 
  11.          * then don't bother flushing. */  
  12.         if (!server_context) {  
  13.                 return;  
  14.         }  
  15.   
  16.         r = ctx->r;  
  17.   
  18.         sapi_send_headers(TSRMLS_C);  
  19.   
  20.         r->status = SG(sapi_headers).http_response_code;  
  21.         SG(headers_sent) = 1;  
  22.   
  23.         if (ap_rflush(r) < 0 || r->connection->aborted) {  
  24.                 php_handle_aborted_connection();  
  25.         }  
  26. }  
7,php_apache_sapi_get_stat:這部分用來讓Zend可以驗證一個要執行腳本文件的state,從而判斷文件是否據有執行權限等等。
  1. static struct stat*  
  2. php_apache_sapi_get_stat(TSRMLS_D)  
  3. {  
  4.         php_struct *ctx = SG(server_context);  
  5.   
  6.         ctx->finfo.st_uid = ctx->r->finfo.user;  
  7.         ctx->finfo.st_gid = ctx->r->finfo.group;  
  8.         ctx->finfo.st_dev = ctx->r->finfo.device;  
  9.         ctx->finfo.st_ino = ctx->r->finfo.inode;  
  10. #if defined(NETWARE) && defined(CLIB_STAT_PATCH)   
  11.         ctx->finfo.st_atime.tv_sec = apr_time_sec(ctx->r->finfo.atime);  
  12.         ctx->finfo.st_mtime.tv_sec = apr_time_sec(ctx->r->finfo.mtime);  
  13.         ctx->finfo.st_ctime.tv_sec = apr_time_sec(ctx->r->finfo.ctime);  
  14. #else   
  15.         ctx->finfo.st_atime = apr_time_sec(ctx->r->finfo.atime);  
  16.         ctx->finfo.st_mtime = apr_time_sec(ctx->r->finfo.mtime);  
  17.         ctx->finfo.st_ctime = apr_time_sec(ctx->r->finfo.ctime);  
  18. #endif   
  19.   
  20.         ctx->finfo.st_size = ctx->r->finfo.size;  
  21.         ctx->finfo.st_nlink = ctx->r->finfo.nlink;  
  22.   
  23.         return &ctx->finfo;  
  24. }  
8,php_apache_sapi_getenv:為Zend提供了一個根據name來查找環境變量的接口,當我們在腳本中調用getenv的時候,就會間接的調用這個句柄。
  1. static char *  
  2. php_apache_sapi_getenv(char *name, size_t name_len TSRMLS_DC)  
  3. {  
  4.         php_struct *ctx = SG(server_context);  
  5.         const char *env_var;  
  6.   
  7.         env_var = apr_table_get(ctx->r->subprocess_env, name);  
  8.   
  9.         return (char *) env_var;  
  10. }  
Copyright © Linux教程網 All Rights Reserved