Table of Contents
Talk about your understanding of Zend SAPIs (Zend SAPI Internals), sapissapi
Home Backend Development PHP Tutorial Talk about your understanding of Zend SAPIs (Zend SAPI Internals), sapissapi_PHP tutorial

Talk about your understanding of Zend SAPIs (Zend SAPI Internals), sapissapi_PHP tutorial

Jul 12, 2016 am 09:05 AM
zend

Talk about your understanding of Zend SAPIs (Zend SAPI Internals), sapissapi

SAPI: Server abstraction API, students who have studied PHP architecture should know the importance of this stuff , which provides an interface that allows PHP to interact with other applications. This article will not introduce each PHP SAPI in detail, but will only explain the mechanism of SAPI for the simplest CGI SAPI.

First, let’s take a look at the architecture diagram of PHP:

Figure 1 PHP Architecture

SAPI provides an interface for external communication. For PHP5.2, many kinds of SAPI are provided by default. The common ones are mod_php5 for Apache, CGI, ISAPI for IIS, and Shell CLI. This article starts from CGI SAPI Let’s start by introducing the mechanism of SAPI. Although CGI is simple, don't worry, it contains most of the content, enough to give you a deep understanding of how SAPI works.

To define a SAPI, you must first define a sapi_module_struct, see PHP-SRC/sapi/cgi/cgi_main.c:

 */
static sapi_module_struct cgi_sapi_module = {
#if PHP_FASTCGI
 "cgi-fcgi",      /* name */
 "CGI/FastCGI",     /* pretty name */
#else
 "cgi",       /* name */
 "CGI",       /* pretty name */
#endif
 
 php_cgi_startup,    /* startup */
 php_module_shutdown_wrapper, /* shutdown */
 
 NULL,       /* activate */
 sapi_cgi_deactivate,   /* deactivate */
 
 sapi_cgibin_ub_write,   /* unbuffered write */
 sapi_cgibin_flush,    /* flush */
 NULL,       /* get uid */
 sapi_cgibin_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 */
 sapi_cgi_read_cookies,   /* read Cookies */
 
 sapi_cgi_register_variables, /* register server variables */
 sapi_cgi_log_message,   /* Log message */
 NULL,       /* Get request time */
 
 STANDARD_SAPI_MODULE_PROPERTIES
};
Copy after login

This structure contains some constants, such as name, which will be used when we call php_info(). Some initialization, closing functions, and some function pointers are used to tell Zend how to obtain and output data.

1. php_cgi_startup, when an application calls PHP, this function will be called. For CGI, it simply calls PHP’s initialization function:

 static int php_cgi_startup(sapi_module_struct *sapi_module)
{
 if (php_module_startup(sapi_module, NULL, 0) == FAILURE) {
  return FAILURE;
 }
 return SUCCESS;
}
Copy after login

2. php_module_shutdown_wrapper, a simple wrapper for PHP shutdown function. Just simply call php_module_shutdown;

3. PHP will handle some initialization and resource allocation transactions at each request. This part is what the activate field is to be defined. From the above structure, we can see that for CGI, it does not provide an initialization handle. For mod_php, it's different. He needs to register the resource destructor in the apache pool, apply for space, initialize environment variables, and so on.

4. sapi_cgi_deactivate, this is the function corresponding to activate. As the name suggests, it will provide a handler to handle the finishing work. For CGI, it simply refreshes the buffer to ensure that the user can complete the process before Zend is closed. Get all output data:

 static int sapi_cgi_deactivate(TSRMLS_D)
{
 /* flush only when SAPI was started. The reasons are:
  1. SAPI Deactivate is called from two places: module init and request shutdown
  2. When the first call occurs and the request is not set up, flush fails on
   FastCGI.
 */
 if (SG(sapi_started)) {
  sapi_cgibin_flush(SG(server_context));
 }
 return SUCCESS;
}
Copy after login

5. sapi_cgibin_ub_write, this handler tells Zend how to output data. For mod_php, this function provides an interface for writing response data, while for CGI, it simply writes to stdout:

static inline size_t sapi_cgibin_single_write(const char *str, uint str_length TSRMLS_DC)
{
#ifdef PHP_WRITE_STDOUT
 long ret;
#else
 size_t ret;
#endif
#if PHP_FASTCGI
 if (fcgi_is_fastcgi()) {
  fcgi_request *request = (fcgi_request*) SG(server_context);
  long ret = fcgi_write(request, FCGI_STDOUT, str, str_length);
  if (ret <= 0) {
   return 0;
  }
  return ret;
 }
#endif
#ifdef PHP_WRITE_STDOUT
 ret = write(STDOUT_FILENO, str, str_length);
 if (ret <= 0) return 0;
 return ret;
#else
 ret = fwrite(str, 1, MIN(str_length, 16384), stdout);
 return ret;
#endif
}
static int sapi_cgibin_ub_write(const char *str, uint str_length TSRMLS_DC)
{
 const char *ptr = str;
 uint remaining = str_length;
 size_t ret;
 while (remaining > 0) {
  ret = sapi_cgibin_single_write(ptr, remaining TSRMLS_CC);
  if (!ret) {
   php_handle_aborted_connection();
   return str_length - remaining;
  }
  ptr += ret;
  remaining -= ret;
 }
 return str_length;
}
Copy after login

The real writing logic is stripped out in order to simply implement a fastcgi-compatible writing method.

6. sapi_cgibin_flush, this is the function handle provided to zend to refresh the cache. For CGI, it is just a simple call to fflush provided by the system;

7.NULL, this part is used to allow Zend to verify the state of a script file to be executed to determine whether the file has execution permissions, etc. CGI does not provide this.

8. sapi_cgibin_getenv, provides Zend with an interface to find environment variables based on name. For mod_php5, when we call getenv in the script, this handle will be called indirectly. For CGI, because its operating mechanism is very similar to CLI, the direct call parent is Shell, so it simply calls genenv:

provided by the system.
static char *sapi_cgibin_getenv(char *name, size_t name_len TSRMLS_DC)
{
#if PHP_FASTCGI
 /* when php is started by mod_fastcgi, no regular environment
  is provided to PHP. It is always sent to PHP at the start
  of a request. So we have to do our own lookup to get env
  vars. This could probably be faster somehow. */
 if (fcgi_is_fastcgi()) {
  fcgi_request *request = (fcgi_request*) SG(server_context);
  return fcgi_getenv(request, name, name_len);
 }
#endif
 /* if cgi, or fastcgi and not found in fcgi env
  check the regular environment */
 return getenv(name);
}
Copy after login

9. php_error, error handling function. Here, let me make a few digressions. Last time I saw the php maillist mentioned that the error handling mechanism of PHP is completely OO, that is, rewriting this function handle makes it possible whenever When an error occurs, an exception is thrown. CGI simply calls the error handling function provided by PHP.

10. This function will be called when we call PHP's header() function, which is not provided for CGI.

11. sapi_cgi_send_headers, this function will be called when the header is actually sent, generally speaking, before any output is to be sent:

static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
{
 char buf[SAPI_CGI_MAX_HEADER_LENGTH];
 sapi_header_struct *h;
 zend_llist_position pos;
 if (SG(request_info).no_headers == 1) {
  return SAPI_HEADER_SENT_SUCCESSFULLY;
 }
 if (cgi_nph || SG(sapi_headers).http_response_code != 200)
 {
  int len;
  if (rfc2616_headers && SG(sapi_headers).http_status_line) {
   len = snprintf(buf, SAPI_CGI_MAX_HEADER_LENGTH,
       "%s\r\n", SG(sapi_headers).http_status_line);
   if (len > SAPI_CGI_MAX_HEADER_LENGTH) {
    len = SAPI_CGI_MAX_HEADER_LENGTH;
   }
  } else {
   len = sprintf(buf, "Status: %d\r\n", SG(sapi_headers).http_response_code);
  }
  PHPWRITE_H(buf, len);
 }
 h = (sapi_header_struct*)zend_llist_get_first_ex(&sapi_headers->headers, &pos);
 while (h) {
  /* prevent CRLFCRLF */
  if (h->header_len) {
   PHPWRITE_H(h->header, h->header_len);
   PHPWRITE_H("\r\n", 2);
  }
  h = (sapi_header_struct*)zend_llist_get_next_ex(&sapi_headers->headers, &pos);
 }
 PHPWRITE_H("\r\n", 2);
 return SAPI_HEADER_SENT_SUCCESSFULLY;
 }
Copy after login

12. NULL, this is used to send each header separately, CGI does not provide it

13. sapi_cgi_read_post, this handle specifies how to obtain POST data. If you have done CGI programming, we know that CGI reads POST DATA from stdin,

static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
{
 uint read_bytes=0, tmp_read_bytes;
#if PHP_FASTCGI
 char *pos = buffer;
#endif
 count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - SG(read_post_bytes));
 while (read_bytes < count_bytes) {
#if PHP_FASTCGI
  if (fcgi_is_fastcgi()) {
   fcgi_request *request = (fcgi_request*) SG(server_context);
   tmp_read_bytes = fcgi_read(request, pos, count_bytes - read_bytes);
   pos += tmp_read_bytes;
  } else {
   tmp_read_bytes = read(0, buffer + read_bytes, count_bytes - read_bytes);
  }
#else
  tmp_read_bytes = read(0, buffer + read_bytes, count_bytes - read_bytes);
#endif
  if (tmp_read_bytes <= 0) {
   break;
  }
  read_bytes += tmp_read_bytes;
 }
 return read_bytes;
}
Copy after login

14. sapi_cgi_read_cookies, this is the same as the function above, except to get the cookie value:

static char *sapi_cgi_read_cookies(TSRMLS_D)
{
 return sapi_cgibin_getenv((char *) "HTTP_COOKIE", sizeof("HTTP_COOKIE")-1 TSRMLS_CC);
}

Copy after login

15. sapi_cgi_register_variables, this function provides an interface for adding variables to the $_SERVER variable. For CGI, a PHP_SELF is registered so that we can access $_SERVER['PHP_SELF'] in the script. Get

This request_uri:

static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC)
{
 /* In CGI mode, we consider the environment to be a part of the server
  * variables
  */
 php_import_environment_variables(track_vars_array TSRMLS_CC);
 /* Build the special-case PHP_SELF variable for the CGI version */
 php_register_variable("PHP_SELF", (SG(request_info).request_uri &#63; SG(request_info).request_uri : ""), track_vars_array TSRMLS_CC);
}
Copy after login

16. sapi_cgi_log_message, used to output error messages. For CGI, it is simply output to stderr:

static void sapi_cgi_log_message(char *message)
{
#if PHP_FASTCGI
 if (fcgi_is_fastcgi() && fcgi_logging) {
  fcgi_request *request;
  TSRMLS_FETCH();
  request = (fcgi_request*) SG(server_context);
  if (request) {
   int len = strlen(message);
   char *buf = malloc(len+2);
   memcpy(buf, message, len);
   memcpy(buf + len, "\n", sizeof("\n"));
   fcgi_write(request, FCGI_STDERR, buf, len+1);
   free(buf);
  } else {
   fprintf(stderr, "%s\n", message);
  }
  /* ignore return code */
 } else
#endif /* PHP_FASTCGI */
 fprintf(stderr, "%s\n", message);
}
Copy after login

After analysis, we have understood how a SAPI is implemented. After analyzing CGI, we can also imagine the implementation mechanism of SAPI such as mod_php, embed and so on. :)

How about this article? Is this article very detailed? I hope you like it.

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/1069342.htmlTechArticleTalk about your understanding of Zend SAPIs (Zend SAPI Internals), sapissapi SAPI: Server abstraction API, have studied PHP Architecture students should know the importance of this stuff. It provides an interface...
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to use ACL (Access Control List) for permission control in Zend Framework How to use ACL (Access Control List) for permission control in Zend Framework Jul 29, 2023 am 09:24 AM

How to use ACL (AccessControlList) for permission control in Zend Framework Introduction: In a web application, permission control is a crucial function. It ensures that users can only access the pages and features they are authorized to access and prevents unauthorized access. The Zend framework provides a convenient way to implement permission control, using the ACL (AccessControlList) component. This article will introduce how to use ACL in Zend Framework

PHP Implementation Framework: Zend Framework Getting Started Tutorial PHP Implementation Framework: Zend Framework Getting Started Tutorial Jun 19, 2023 am 08:09 AM

PHP implementation framework: ZendFramework introductory tutorial ZendFramework is an open source website framework developed by PHP and is currently maintained by ZendTechnologies. ZendFramework adopts the MVC design pattern and provides a series of reusable code libraries to serve the implementation of Web2.0 applications and Web Serve. ZendFramework is very popular and respected by PHP developers and has a wide range of

How to configure the Window2003 IIS+MySQL+PHP+Zend environment How to configure the Window2003 IIS+MySQL+PHP+Zend environment Jun 02, 2023 pm 09:56 PM

The Windows 2003 installation package includes Zend, PHP5.2.17, PHPWind8.7 and PHPMyadmin3.5.2. You can download the installation package directly to save time searching for resources. However, since MySQL has exceeded the upload limit, you need to go to the MySQL official website to download. Then unzip and copy to the D drive, as shown below: MySQLinDdisk Install and configure WindowsIIS+FTP Click Start>Control Panel>Add or Remove Programs.AddingordeletingaPG Click Add/Remove Windows Components (A). Addingorde

PHP does not recognize ZendOptimizer, how to solve it? PHP does not recognize ZendOptimizer, how to solve it? Mar 19, 2024 pm 01:09 PM

PHP does not recognize ZendOptimizer, how to solve it? In PHP development, sometimes you may encounter a situation where PHP cannot recognize ZendOptimizer, which will cause some PHP codes to not run properly. In this case, we need to take some measures to solve the problem. Some possible workarounds are described below, along with specific code examples. 1. Confirm whether ZendOptimizer is installed correctly: First, we need to confirm that ZendOptimizer

How to use the PHP framework Zend to develop an efficient ERP management platform How to use the PHP framework Zend to develop an efficient ERP management platform Jun 26, 2023 pm 11:00 PM

With the rapid development of information technology, more and more enterprises are beginning to realize the necessity of information management. ERP (Enterprise Resource Planning) management platform is an important tool for modern enterprise management, which can help enterprises realize resource planning, collaboration, control, optimization and management. Among them, the PHP framework Zend is an excellent development tool that can help developers develop ERP systems quickly and efficiently. This article will introduce how to use Zend to develop an efficient ERP management platform. 1. Determine requirements analysis before starting the development process

Laravel vs Zend: Which framework is better for developing large applications? Laravel vs Zend: Which framework is better for developing large applications? Jun 19, 2023 am 08:52 AM

With the continuous development of Internet applications, the demand for the development of large-scale applications is also increasing. In this context, it is particularly important to choose a development framework that suits you. Laravel and Zend are two widely used PHP frameworks. They each have their own advantages, but which one is more suitable for developing large-scale applications? Laravel is a popular development framework that has become one of the preferred frameworks for PHP developers. It adopts a modern design concept and has a variety of powerful built-in functions and tools, such as EloquentOR

How to optimize the performance of Zend Framework How to optimize the performance of Zend Framework Jan 22, 2024 am 11:25 AM

Zend framework is an open source web application framework based on PHP language and is widely used in the development of enterprise-level web applications. Although the Zend Framework occupies an important position in the market due to its high degree of modularity, scalability, and code reusability, this does not mean that its performance is necessarily efficient. In fact, how to optimize the performance of the Zend Framework has always been one of the focuses of developers. This article will explore how to improve the performance of the Zend Framework from multiple aspects. 1. Reasonable use of Zend framework’s caching mechanism Z

Develop a high-performance search engine using the PHP framework Zend Develop a high-performance search engine using the PHP framework Zend Jun 27, 2023 am 08:36 AM

With the explosive growth of Internet information, search engines have become one of the preferred ways for people to obtain information. Now, as the number of websites continues to increase, the rapid response and accuracy of search engines have become more and more important, which requires search engines to have high performance. In this article, I will introduce how to use the PHP framework Zend to develop a high-performance search engine. 1. Why use Zend Framework? Zend Framework is a high-performance PHP framework that has excellent performance and scalability.

See all articles