歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> PHP內核-Apache2的SAPI

PHP內核-Apache2的SAPI

日期:2017/3/1 10:09:14   编辑:Linux編程

我們知道定義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. php_apache2_startup, /* startup */
  5. php_module_shutdown_wrapper, /* shutdown */
  6. NULL, /* activate */
  7. NULL, /* deactivate */
  8. php_apache_sapi_ub_write, /* unbuffered write */
  9. php_apache_sapi_flush, /* flush */
  10. php_apache_sapi_get_stat, /* get uid */
  11. php_apache_sapi_getenv, /* getenv */
  12. php_error, /* error handler */
  13. php_apache_sapi_header_handler, /* header handler */
  14. php_apache_sapi_send_headers, /* send headers handler */
  15. NULL, /* send header handler */
  16. php_apache_sapi_read_post, /* read POST data */
  17. php_apache_sapi_read_cookies, /* read Cookies */
  18. php_apache_sapi_register_variables,
  19. php_apache_sapi_log_message, /* Log message */
  20. php_apache_sapi_get_request_time, /* Request Time */
  21. STANDARD_SAPI_MODULE_PROPERTIES
  22. };
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. ctx = SG(server_context);
  7. r = ctx->r;
  8. if (ap_rwrite(str, str_length, r) < 0) {
  9. php_handle_aborted_connection();
  10. }
  11. return str_length; /* we always consume all the data passed to us. */
  12. }

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. ctx = server_context;
  8. /* If we haven't registered a server_context yet,
  9. * then don't bother flushing. */
  10. if (!server_context) {
  11. return;
  12. }
  13. r = ctx->r;
  14. sapi_send_headers(TSRMLS_C);
  15. r->status = SG(sapi_headers).http_response_code;
  16. SG(headers_sent) = 1;
  17. if (ap_rflush(r) < 0 || r->connection->aborted) {
  18. php_handle_aborted_connection();
  19. }
  20. }
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. ctx->finfo.st_uid = ctx->r->finfo.user;
  6. ctx->finfo.st_gid = ctx->r->finfo.group;
  7. ctx->finfo.st_dev = ctx->r->finfo.device;
  8. ctx->finfo.st_ino = ctx->r->finfo.inode;
  9. #if defined(NETWARE) && defined(CLIB_STAT_PATCH)
  10. ctx->finfo.st_atime.tv_sec = apr_time_sec(ctx->r->finfo.atime);
  11. ctx->finfo.st_mtime.tv_sec = apr_time_sec(ctx->r->finfo.mtime);
  12. ctx->finfo.st_ctime.tv_sec = apr_time_sec(ctx->r->finfo.ctime);
  13. #else
  14. ctx->finfo.st_atime = apr_time_sec(ctx->r->finfo.atime);
  15. ctx->finfo.st_mtime = apr_time_sec(ctx->r->finfo.mtime);
  16. ctx->finfo.st_ctime = apr_time_sec(ctx->r->finfo.ctime);
  17. #endif
  18. ctx->finfo.st_size = ctx->r->finfo.size;
  19. ctx->finfo.st_nlink = ctx->r->finfo.nlink;
  20. return &ctx->finfo;
  21. }
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. env_var = apr_table_get(ctx->r->subprocess_env, name);
  7. return (char *) env_var;
  8. }
Copyright © Linux教程網 All Rights Reserved