<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>潘锦的空间 &#187; SAPI</title>
	<atom:link href="https://www.phppan.com/tag/sapi/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.phppan.com</link>
	<description>SaaS SaaS架构 团队管理 技术管理 技术架构 PHP 内核 扩展 项目管理</description>
	<lastBuildDate>Sun, 12 Apr 2026 03:47:23 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>TIPI020200-SAPI概述</title>
		<link>https://www.phppan.com/2011/01/tipi020200-sapi/</link>
		<comments>https://www.phppan.com/2011/01/tipi020200-sapi/#comments</comments>
		<pubDate>Fri, 28 Jan 2011 06:16:27 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[SAPI]]></category>
		<category><![CDATA[TIPI]]></category>
		<category><![CDATA[深入理解PHP内核]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1243</guid>
		<description><![CDATA[前一小节介绍了PHP的生命周期, 所有的请求都是通过SAPI接口实现的. 在源码的SAPI目录存放了PHP对各 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="text-indent: 2em;">前一小节介绍了PHP的生命周期, 所有的请求都是通过SAPI接口实现的. 在源码的SAPI目录存放了PHP对各种服务器抽象层的代码，例如命令行程序的实现, mod_php的apache模块实现以及fastcgi的实现等等.</p>
<p style="text-indent: 2em;">在各个服务器抽象层之间遵守着相同的约定，这里我们称之为SAPI接口。每个服务器都需要实现各自己的_sapi_module_struct结构中的各个方法。 然后在这个接口层之下，关于PHP的公共部分，全部通过这个结构体的相关方法调用实现。 如cgi模式和apache2服务器中的启动方法：</p>
<pre style="background-color: #333333; color: #ffffff; font: normal normal normal 13px/normal 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', 'Courier New', monospace; overflow-x: auto; overflow-y: auto; padding: 10px;">cgi_sapi_module.<span style="color: #ffffff;">startup</span><span style="color: #ffffff;">(</span><span style="color: #e0882f;">&amp;</span>cgi_sapi_module<span style="color: #ffffff;">)</span>   <span style="color: #bc9458; font-style: italic;">//  cgi模式 cgi/cgi_main.c文件</span>

apache2_sapi_module.<span style="color: #ffffff;">startup</span><span style="color: #ffffff;">(</span><span style="color: #e0882f;">&amp;</span>apache2_sapi_module<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>  <span style="color: #bc9458; font-style: italic;">//  apache2服务器  apache2handler/sapi_apache2.c文件</span></pre>
<p style="text-indent: 2em;">除了startup方法，sapi_module_struct结构还有许多其它方法。其部分定义如下：</p>
<pre style="background-color: #333333; color: #ffffff; font: normal normal normal 13px/normal 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', 'Courier New', monospace; overflow-x: auto; overflow-y: auto; padding: 10px;"><span style="color: #1299da;">struct</span> _sapi_module_struct <span style="color: #ffffff;">{</span>
    <span style="color: #1299da;">char</span> <span style="color: #e0882f;">*</span>name<span style="color: #e0882f;">;</span>         <span style="color: #bc9458; font-style: italic;">//  名字（标识用）</span>
    <span style="color: #1299da;">char</span> <span style="color: #e0882f;">*</span>pretty_name<span style="color: #e0882f;">;</span>  <span style="color: #bc9458; font-style: italic;">//  更好理解的名字（自己翻译的）</span>

    <span style="color: #1299da;">int</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>startup<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span><span style="color: #1299da;">struct</span> _sapi_module_struct <span style="color: #e0882f;">*</span>sapi_module<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>    <span style="color: #bc9458; font-style: italic;">//  启动函数</span>
    <span style="color: #1299da;">int</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>shutdown<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span><span style="color: #1299da;">struct</span> _sapi_module_struct <span style="color: #e0882f;">*</span>sapi_module<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>   <span style="color: #bc9458; font-style: italic;">//  关闭方法</span>

    <span style="color: #1299da;">int</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>activate<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span>TSRMLS_D<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>  <span style="color: #bc9458; font-style: italic;">// 激活</span>
    <span style="color: #1299da;">int</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>deactivate<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span>TSRMLS_D<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>    <span style="color: #bc9458; font-style: italic;">//  停用</span>

    <span style="color: #1299da;">int</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>ub_write<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span><span style="color: #1299da;">const</span> <span style="color: #1299da;">char</span> <span style="color: #e0882f;">*</span>str<span style="color: #e0882f;">,</span> <span style="color: #1299da;">unsigned</span> <span style="color: #1299da;">int</span> str_length TSRMLS_DC<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>    <span style="color: #bc9458; font-style: italic;">//  不缓存的写操作(unbuffered write)</span>
    <span style="color: #1299da;">void</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>flush<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span><span style="color: #1299da;">void</span> <span style="color: #e0882f;">*</span>server_context<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>    <span style="color: #bc9458; font-style: italic;">//  flush</span>
    <span style="color: #1299da;">struct</span> stat <span style="color: #e0882f;">*</span><span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>get_stat<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span>TSRMLS_D<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>     <span style="color: #bc9458; font-style: italic;">//  get uid</span>
    <span style="color: #1299da;">char</span> <span style="color: #e0882f;">*</span><span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>getenv<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span><span style="color: #1299da;">char</span> <span style="color: #e0882f;">*</span>name<span style="color: #e0882f;">,</span> size_t name_len TSRMLS_DC<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span> <span style="color: #bc9458; font-style: italic;">//  getenv</span>

    <span style="color: #1299da;">void</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>sapi_error<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span><span style="color: #1299da;">int</span> type<span style="color: #e0882f;">,</span> <span style="color: #1299da;">const</span> <span style="color: #1299da;">char</span> <span style="color: #e0882f;">*</span>error_msg<span style="color: #e0882f;">,</span> ...<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>   <span style="color: #bd48b3; font-style: italic;">/* error handler */</span>

    <span style="color: #1299da;">int</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>header_handler<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span>sapi_header_struct <span style="color: #e0882f;">*</span>sapi_header<span style="color: #e0882f;">,</span> 
        sapi_header_op_enum op<span style="color: #e0882f;">,</span> sapi_headers_struct <span style="color: #e0882f;">*</span>sapi_headers TSRMLS_DC<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>   <span style="color: #bd48b3; font-style: italic;">/* header handler */</span>
    <span style="color: #1299da;">int</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>send_headers<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span>sapi_headers_struct <span style="color: #e0882f;">*</span>sapi_headers TSRMLS_DC<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>   <span style="color: #bd48b3; font-style: italic;">/* send headers handler */</span>
    <span style="color: #1299da;">void</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>send_header<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span>sapi_header_struct <span style="color: #e0882f;">*</span>sapi_header<span style="color: #e0882f;">,</span> <span style="color: #1299da;">void</span> <span style="color: #e0882f;">*</span>server_context TSRMLS_DC<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>   <span style="color: #bd48b3; font-style: italic;">/* send header handler */</span>

    <span style="color: #1299da;">int</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>read_post<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span><span style="color: #1299da;">char</span> <span style="color: #e0882f;">*</span>buffer<span style="color: #e0882f;">,</span> uint count_bytes TSRMLS_DC<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span> <span style="color: #bd48b3; font-style: italic;">/* read POST data */</span>
    <span style="color: #1299da;">char</span> <span style="color: #e0882f;">*</span><span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>read_cookies<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span>TSRMLS_D<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>    <span style="color: #bd48b3; font-style: italic;">/* read Cookies */</span>

    <span style="color: #1299da;">void</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>register_server_variables<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span>zval <span style="color: #e0882f;">*</span>track_vars_array TSRMLS_DC<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>    <span style="color: #bd48b3; font-style: italic;">/* register server variables */</span>
    <span style="color: #1299da;">void</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>log_message<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span><span style="color: #1299da;">char</span> <span style="color: #e0882f;">*</span>message<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>     <span style="color: #bd48b3; font-style: italic;">/* Log message */</span>
    time_t <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>get_request_time<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span>TSRMLS_D<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>   <span style="color: #bd48b3; font-style: italic;">/* Request Time */</span>
    <span style="color: #1299da;">void</span> <span style="color: #ffffff;">(</span><span style="color: #e0882f;">*</span>terminate_process<span style="color: #ffffff;">)</span><span style="color: #ffffff;">(</span>TSRMLS_D<span style="color: #ffffff;">)</span><span style="color: #e0882f;">;</span>    <span style="color: #bd48b3; font-style: italic;">/* Child Terminate */</span>

    <span style="color: #1299da;">char</span> <span style="color: #e0882f;">*</span>php_ini_path_override<span style="color: #e0882f;">;</span>    <span style="color: #bc9458; font-style: italic;">//  覆盖的ini路径</span>

    ...
    ...
<span style="color: #ffffff;">}</span><span style="color: #e0882f;">;</span></pre>
<p style="text-indent: 2em;">以上的这些结构在各服务器的接口实现中都有定义。如apache2的定义：</p>
<pre style="background-color: #333333; color: #ffffff; font: normal normal normal 13px/normal 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', 'Courier New', monospace; overflow-x: auto; overflow-y: auto; padding: 10px;"><span style="color: #1299da;">static</span> sapi_module_struct apache2_sapi_module <span style="color: #e0882f;">=</span> <span style="color: #ffffff;">{</span>
    <span style="color: #99ff00;">"apache2handler"</span><span style="color: #e0882f;">,</span>
    <span style="color: #99ff00;">"Apache 2.0 Handler"</span><span style="color: #e0882f;">,</span>

    php_apache2_startup<span style="color: #e0882f;">,</span>                <span style="color: #bd48b3; font-style: italic;">/* startup */</span>
    php_module_shutdown_wrapper<span style="color: #e0882f;">,</span>            <span style="color: #bd48b3; font-style: italic;">/* shutdown */</span>

    ...
<span style="color: #ffffff;">}</span></pre>
<p style="text-indent: 2em;">整个SAPI类似于一个面向对象中的模板方法模式的应用。SAPI.c和SAPI.h文件所包含的一些函数就是模板方法模式中的抽象模板，各个服务器对于sapi_module的定义及相关实现则是一个个具体的模板。只是这里没有继承。</p>
<p style="text-indent: 2em;">作者：TIPI团队</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2011/01/tipi020200-sapi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
