SAPI を定義する前に、最初に sapi_module_struct 構造体を定義する必要があることがわかります。ソース コード /soft/php-5.2.9/sapi/apache2handler/sapi_apache2.c を見ると、構造体がコピーされていることがわかります。直接:
[cpp]
静的 sapi_module_struct apache2_sapi_module = {
"apache2handler"、
「Apache 2.0 ハンドラー」、
php_apache2_startup, /* スタートアップ */
php_module_shutdown_wrapper, /* シャットダウン */
NULL、 /* アクティブ化 */
NULL、 /* 非アクティブ化 */
php_apache_sapi_ub_write, /* バッファなし書き込み */
php_apache_sapi_flush, /* フラッシュ */
php_apache_sapi_get_stat, /* uid を取得 */
php_apache_sapi_getenv, /* getenv */
php_error, /* エラーハンドラー */
php_apache_sapi_header_handler, /* ヘッダー ハンドラー */
php_apache_sapi_send_headers, /* ヘッダー送信ハンドラー */
NULL, /* ヘッダーハンドラーを送信 */
php_apache_sapi_read_post, /* POST データを読み取る */
php_apache_sapi_read_cookies, /* Cookie を読み取る */
php_apache_sapi_register_variables、
php_apache_sapi_log_message, /* ログメッセージ */
php_apache_sapi_get_request_time, /* リクエスト時間 */
STANDARD_SAPI_MODULE_PROPERTIES
};
1、php_apache2_startup: apache 経由で PHP を使用するときにこの関数が使用されます。この関数は次のように定義されており、主に PHP の初期化を実行します。
[cpp]
static int php_apache2_startup(sapi_module_struct *sapi_module)
{
if (php_module_startup(sapi_module, &php_apache_module, 1)==FAILURE) {
失敗を返します。
}
成功を返します
}
3. PHP は、リクエストごとにいくつかの初期化およびリソース割り当てトランザクションを処理します。この部分は、activate フィールドが定義されているものです。
5、php_apache_sapi_ub_write: 応答データを書き込むためのインターフェイスを提供します。
[cpp]
静的整数
php_apache_sapi_ub_write(const char *str, uint str_length TSRMLS_DC)
{
request_rec *r;
php_struct *ctx;
ctx = SG(サーバーコンテキスト)
r = ctx->r;
If (ap_rwrite(str, str_length, r)
php_handle_aborted_connection();
}
return str_length; /* 渡されたデータは常にすべて消費されます。
}
6. php_apache_sapi_flush: キャッシュを更新するためのハンドルを zend に提供します。
[cpp]
静的ボイド
php_apache_sapi_flush(void *server_context)
{
php_struct *ctx;
request_rec *r;
TSRMLS_FETCH();
ctx = サーバーコンテキスト
/* まだserver_contextを登録していない場合は、
* 洗い流す必要はありません */
If (!server_context) {
戻る
}
r = ctx->r;
sapi_send_headers(TSRMLS_C);
r->status = SG(sapi_headers).http_response_code;
SG(headers_sent) = 1;
If (ap_rflush(r) connection->aborted) {
php_handle_aborted_connection();
}
}
7. php_apache_sapi_get_stat: この部分は、Zend が実行されるスクリプト ファイルの状態を確認できるようにするために使用され、それによってファイルに実行権限があるかどうかなどを判断します。
[cpp]
静的構造体 stat*
php_apache_sapi_get_stat(TSRMLS_D)
{
php_struct *ctx = SG(server_context);
ctx->finfo.st_uid = ctx->r->finfo.user;
ctx->finfo.st_gid = ctx->r->finfo.group;
ctx->finfo.st_dev = ctx->r->finfo.device;
ctx->finfo.st_ino = ctx->r->finfo.inode;
#if 定義された (NETWARE) && 定義された (CLIB_STAT_PATCH)
ctx->finfo.st_atime.tv_sec = apr_time_sec(ctx->r->finfo.atime);
ctx->finfo.st_mtime.tv_sec = apr_time_sec(ctx->r->finfo.mtime);
ctx->finfo.st_ctime.tv_sec = apr_time_sec(ctx->r->finfo.ctime);
#その他
ctx->finfo.st_atime = apr_time_sec(ctx->r->finfo.atime);
ctx->finfo.st_mtime = apr_time_sec(ctx->r->finfo.mtime);
ctx->finfo.st_ctime = apr_time_sec(ctx->r->finfo.ctime);
#endif
ctx->finfo.st_size = ctx->r->finfo.size;
ctx->finfo.st_nlink = ctx->r->finfo.nlink;
&ctx->finfo; を返す
}
8. php_apache_sapi_getenv: スクリプト内で getenv を呼び出すと、このハンドルが間接的に呼び出されます。
[CP]
静的文字 *
php_apache_sapi_getenv(char *name, size_t name_len TSRMLS_DC)
{
php_struct *ctx = SG(server_context);
const char *env_var;
env_var = apr_table_get(ctx->r->サブプロセス環境, 名前);
return (char *) env_var;
}
9、php_error: エラー処理関数。PHP エラー処理関数を直接呼び出します。
10. php_apache_sapi_header_handler: この関数は、PHP の header() 関数を呼び出すときに呼び出されます。
[cpp]
静的整数
php_apache_sapi_header_handler(sapi_header_struct *sapi_header,sapi_headers_struct *sapi_headers TSRMLS_DC)
{
php_struct *ctx;
char *val、*ptr;
ctx = SG(サーバーコンテキスト);
val = strchr(sapi_header->header, ':');
if (!val) {
sapi_free_header(sapi_header);
0を返します。
}
ptr = val;
*val = ' ';
してください{
val++;
while (*val == ' ');
if (!strcasecmp(sapi_header->header, "content-type")) {
if (ctx->content_type) {
efree(ctx->content_type);
}
ctx->content_type = estrdup(val);
} else if (sapi_header->replace) {
apr_table_set(ctx->r->headers_out, sapi_header->header, val);
} その他 {
apr_table_add(ctx->r->headers_out, sapi_header->header, val);
}
*ptr = ':';
SAPI_HEADER_ADD を返します。
}
11、php_apache_sapi_send_headers: ヘッダーを真に送信する必要がある場合、この関数が使用される可能性があります。
[cpp]
静的整数
php_apache_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
{
php_struct *ctx = SG(サーバーコンテキスト);
const char *sline = SG(sapi_headers).http_status_line;
ctx->r->status = SG(sapi_headers).http_response_code;
/* httpd では、r->status_line が
の最初の桁に設定されている必要があります
* ステータスコード: */
if (sline && strlen(sline) > 12 && strncmp(sline, "HTTP/1.", 7) == 0 && sline[8] == ' ') {
ctx->r->status_line = apr_pstrdup(ctx->r->pool, sline + 9);
ctx->r->proto_num = 1000 + (sline[7]-'0');
if ((sline[7]-'0') == 0) {
apr_table_set(ctx->r->subprocess_env, "force-response-1.0", "true");
}
}
/* ap_set_content_type を 1 回だけ呼び出し、それ以外は呼び出すたびに呼び出します
そのコンテンツ タイプ用に構成された出力フィルターが追加されます */
If (!ctx->content_type) {
ctx->content_type = sapi_get_default_content_type(TSRMLS_C);
}
ap_set_content_type(ctx->r, apr_pstrdup(ctx->r->pool, ctx->content_type));
efree(ctx->content_type);
ctx->content_type = NULL;
戻り SAPI_HEADER_SENT_SUCCESSFULLY
;
}
12. php_apache_sapi_send_headers ポインターの下にフィールドがあり、各ヘッダーを送信するときに呼び出しを示すために使用されます。
13. php_apache_sapi_read_post: POST データの読み取り方法を示します。
静的整数
php_apache_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC)
apr_size_t レン、tlen=0;
php_struct *ctx = SG(server_context);
request_rec *r;
apr_bucket_brigade *旅団;
r = ctx->r;
旅団 = ctx->旅団;
len = count_bytes;
/*
* このループが必要なのは、ap_get_brigade() が部分的なデータを返す可能性があるためです
* これはリクエスト読み取りの早期終了を引き起こす可能性があるため、
* データが利用可能な場合はバッファーを完全に埋めることを確認する必要があります。
*/
While (ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES, APR_BLOCK_READ, len) == APR_SUCCESS) {
apr_brigade_ flatten(旅団, buf, &len);
apr_brigade_cleanup(旅団);
tlen +=
If (tlen == count_bytes || !len) {
壊す;
buf += len;
len = count_bytes - tlen;
}
戻ります
}
14. php_apache_sapi_read_cookie: Cookie の読み取り方法。
[cpp]
静的文字 *
php_apache_sapi_read_cookies(TSRMLS_D)
{
php_struct *ctx = SG(server_context);
const char *http_cookie
http_cookie = apr_table_get(ctx->r->headers_in, "cookie");
/* SAPI インターフェースは 'const char *' を使用する必要があります */
return (char *) http_cookie
}
15、php_apache_sapi_register_variables: $_SERVER[] 数グループに量を提供するために使用されるインターフェイスを提供します。
[cpp]
静的ボイド
php_apache_sapi_register_variables(zval *track_vars_array TSRMLS_DC)
{
php_struct *ctx = SG(サーバーコンテキスト);
const apr_array_header_t *arr = apr_table_elts(ctx->r->subprocess_env);
char *キー、*val;
int new_val_len;
APR_ARRAY_FOREACH_OPEN(arr、key、val)
if (!val) {
val = "";
}
if (sapi_module.input_filter(PARSE_SERVER, key, &val, strlen(val), &new_val_len TSRMLS_CC)) {
php_register_variable_safe(key, val, new_val_len, track_vars_array TSRMLS_CC);
}
APR_ARRAY_FOREACH_CLOSE()
if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &ctx->r->uri, strlen(ctx->r->uri), &new_val_len TSRMLS_CC)) {
php_register_variable_safe("PHP_SELF", ctx->r->uri, new_val_len, track_vars_array TSRMLS_CC);
}
}
static void php_apache_sapi_log_message(char *msg)
{
php_struct *ctx;
TSRMLS_FETCH();
ctx = SG(サーバーコンテキスト);
if (ctx == NULL) { /* ctx はまだ初期化されていません。まあまあ */
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, 0, NULL, "%s", msg);
} その他 {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, "%s", msg);
}
}
[cpp]
php_struct *ctx = SG(サーバーコンテキスト);
return apr_time_sec(ctx->r->request_time);
}
これで、Apache の SAPI 設定が完了します。その後、ユーザーの URL が Apache サービスを要求すると、これらの関数は適切なタイミングで機能する (使用される) ことになります。
http://www.bkjia.com/PHPjc/477971.html
www.bkjia.com