PHPはどういう仕組みで動くのか

なぜかPHPをやることになったので、今更感があるが調べる。トップページがブラウザに表示されるまでのPHPの動きを探る。

 

■XAMPP

XAMPP(ザンプ)というパッケージをDownloadしてインストールする。最新版のVer 7.3.2を使用してみる。

---[XAMPPのダウンロードページより抜粋]----------------------------

XAMPP は、MariaDBPHP、および Perl を含む、イントールが簡単な Apache ディストリビューションです。ダウンロードして、インストラーを起動しましょう。とても簡単です。

-------------------------------------------------------------------------------------

XAMPPの「M」は、昔はMySQLの「M」だったけど、MySQLOracleに買収されてからはライセンスの関係で使いにくくなったので、MySQLと互換のあるMariaDBを採用するように変わったみたいね。どちらも「M」で始まってて良かったね。

 

■起動

インストールも終わり、スタートメニューに、「Control panel」 がインストールされたので、起動してみる。5種類のプログラムが表示され、起動、停止Config修正、ログ参照などができるようだ。とりあえずApacheだけ起動してみる。

f:id:ittokoton:20190303142122p:plain

 

80番ポートをListenしたようなので、ブラウザでhttp://127.0.0.1/にアクセスしてみる。

f:id:ittokoton:20190303143226p:plain

 アクセスできた。リダイレクトされて、PHPのトップページである、http://127.0.0.1/dashboard/ が表示された模様だ。

 

■どういう仕組みで動作しているのか

では、PHPのトップページが表示されるまでに、どのような仕組みで動作しているのか調査してみる。

 

 まず、ブラウザが、http://127.0.0.1:80/ にアクセスする。

apacheの設定ファイル(httpd.conf)を見ると、以下の設定がある。

Listen 80

よって、apacheはブラウザからの80番ポートへのhttpアクセスを受け入れる。

次に、今回はルートディレクトリ("/")へのアクセスなので、下記のドキュメントルート直下のファイルを探しに行く。

DocumentRoot "F:/Program/xampp/htdocs"

このhtdocsディレクトリ直下には沢山のファイルがあるが、このうちのどのファイルを見るかというと、

LoadModule dir_module modules/mod_dir.so

上記のとおり、dirモジュール をロードする設定があるので、下記の if文が有効となり、

<IfModule dir_module>
  DirectoryIndex index.php index.pl index.cgi index.asp \
  index.shtml index.html index.htm \
  default.php default.pl default.cgi default.asp default.shtml \
  default.html default.htm \
  home.php home.pl home.cgi home.asp home.shtml home.html home.htm
</IfModule>

DirectoryIndexに列挙されたファイルがないか順に探しいていく。すると、いきなり

最初に書かれている F:/Program/xammp/htdocs/index.php が見つかる。

ところで、httpd.confには、下記の設定が記述されているため、このxampp用のconfファイルも併せて読み込まれる。

# XAMPP settings
Include "conf/extra/httpd-xampp.conf"

このhttpd-xampp.conf には、下記の設定があるため、

# PHP-Module setup
#
LoadFile "F:/Program/xampp/php/php7ts.dll"
LoadFile "F:/Program/xampp/php/libpq.dll"
LoadModule php7_module "F:/Program/xampp/php/php7apache2_4.dll"

<FilesMatch "\.php$">
SetHandler application/x-httpd-php
</FilesMatch>

FilesMatchにより拡張子が .php のファイルがブラウザからアクセスされた場合は、application/x-httpd-php というハンドラが対応付けされる。このハンドラを処理するモジュールがどこかにいるはずだ。おそらく、すぐ上に記述されている php7apache2_4.dll というモジュールがそれであろう。このdllは、LoadModuleによりapacheがメモリにロードしてくれる、PHPのコア部分だ。一応、php7apache2_4.dll のソースを見てみよう。sapi_apache2.cにて、ap_hook_handler()の引数に、php_handler()関数を渡している。

void php_ap2_register_hook(apr_pool_t *p)
{
    ap_hook_pre_config(php_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_post_config(php_apache_server_startup, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_handler(php_handler, NULL, NULL, APR_HOOK_MIDDLE);
#ifdef ZEND_SIGNALS
    ap_hook_child_init(php_apache_signal_init, NULL, NULL, APR_HOOK_MIDDLE);
#endif
    ap_hook_child_init(php_apache_child_init, NULL, NULL, APR_HOOK_MIDDLE);
}

php_handler()関数には、下記の処理があり、

    if (strcmp(r->handler, PHP_MAGIC_TYPE) && strcmp(r->handler, ・・・
        /* Check for xbithack in this case. */
        if (!AP2(xbithack) || strcmp(r->handler, "text/html") || ・・・
            PHPAP_INI_OFF;
            return DECLINED;
        }
    }

request_req構造体に登録されたハンドラが、PHP_MAGIC_TYPEと一致するかチェックしている。PHP_MAGIC_TYPEは、下記のdefineである。

#define PHP_MAGIC_TYPE "application/x-httpd-php"

以上により、.phpの拡張子は、application/x-httpd-php というコンテントタイプに関連付けられ、このコンテントタイプを処理すると宣言しているこのモジュールによって処理されることになる。

 index.phpの中身は以下のようになっており、<?php  ~  ?>で囲まれた部分を、このモジュール(php7_module)が解析、実行してくれる。

<?php
    if (!empty($_SERVER['HTTPS']) && ('on' == $_SERVER['HTTPS'])) {
        $uri = 'https://';
    } else {
        $uri = 'http://';
    }
    $uri .= $_SERVER['HTTP_HOST'];
    header('Location: '.$uri.'/dashboard/');
    exit;
?>
Something is wrong with the XAMPP installation :-(

 

 

ブラウザがルートディレクトリ("/")にアクセスしてきた場合は、無条件に dashboard ディレクトリにリダイレクトさせるコードになっている。/$_SERVERの説明はここにある。このif文の意味は、ブラウザからのリクエストが、「httpsでアクセスしたものであれば」という意味になる。header()関数で、Locationヘッダを組み立ててレスポンスを返している。Locationヘッダを付加すると、レスポンスコードは自動的に302になる。

 ブラウザは受け取ったレスポンスヘッダの中に、下記のような行を見つけると、

ブラウザの画面は変更せず、直ちに、http://127.0.0.1/dashboard/ を取得するために、立て続けにHTTPリクエストを送信する。その結果、apacheは、ドキュメントルート(F:/Program/xammp/htdocs/)の下のdashboardディレクトリの中からDirectoryIndexに列挙されたファイル名を順に探した結果、index.html か見つかったため、これをブラウザへ応答した。その結果、冒頭で述べた下記の画面が表示されるに至った。

f:id:ittokoton:20190303143226p:plain

 

まとめると、PHPapacheのモジュールとして動作し、HTTPリクエストやHTTPレスポンスを操作するものであった。

 

 

------------------------------------------------------------------------------

ITとことん の目次
┗■PHPの調査結果(目次)
 ┗■本ページ