FastCGI を使用して IIS 7 で PHP アプリケーションをホストする
公開日: 2007 年 12 月 5 日 (作業者: IIS Team (英語))
更新日: 2009 年 6 月 26 日 (作業者: IIS Team (英語))
この記事では、FastCGI モジュールと PHP を構成して、IIS 7 で PHP アプリケーションをホストする方法について説明します。
重要: この記事では、Windows Server 2008 および Windows Vista SP1 上での FastCGI コンポーネントのインストール方法および使用方法を説明します。Windows Vista に SP1 をインストールされていることが必須であることに注意してください。
- 概要
- IIS 7 で FastCGI サポートを有効にする
- Windows Server 2008
- Windows Vista SP1
- FastCGI モジュールの更新
- IIS 7 管理パック
- PHP のインストールおよび構成
- IIS を構成して、PHP 要求を処理する
- IIS マネージャーを使用する方法
- コマンド ラインを使用する方法
- FastCGI および PHP の構成に関するベスト プラクティス
- セキュリティの分離
- プロセスのリサイクル
- PHP バージョン管理
- セキュリティに関する推奨事項
- サイトごとの PHP 構成
- PHP アプリケーションの URL 書き換え
- 関連情報
IIS の FastCGI モジュールによって、FastCGI プロトコルに対応した一般的なアプリケーション フレームワークを、パフォーマンスと信頼性に優れた方法で IIS Web サーバーでホストすることができます。Common Gateway Interface (CGI) は、Web サーバーと外部アプリケーションの標準インターフェイスとして、IIS の初回リリース以来、機能セットの 1 つとしてサポートされてきましたが、FastCGI はこの CGI に代わる高性能なインターフェイスです。
CGI プログラムは、Web サーバーに対する要求ごとに起動される実行可能ファイルであり、要求を処理して応答を動的に生成し、クライアントに送信します。これらのフレームワークの多くはマルチスレッド処理をサポートしていないので、CGI ではプロセスごとに 1 つの要求を確実に処理することにより IIS でフレームワークが信頼性の高い処理を行えるようにしています。そのため、CGI では要求ごとにプロセスの起動とシャットダウンを行うため処理負荷がかかり、パフォーマンスは高くありません。
CGI のこのパフォーマンス面の問題に対して、FastCGI では 1 つのプロセスを多数の要求に対して繰り返し再利用することで対処しています。加えて、FastCGI では、再利用可能なプロセスをプールし、確実にそれぞれのプロセスが一度に 1 つの要求のみを処理することにより、スレッド セーフではないライブラリとの互換性を維持しています。
[サーバー マネージャー] -> [役割] -> [役割サービスの追加] で CGI 役割サービスを追加します。ここで CGI および FastCGI サービス両方を有効にします。
[コントロール パネル] -> [プログラムと機能] -> [Windows の機能の有効化または無効化] で CGI の機能を追加します。ここで CGI および FastCGI サービス両方を有効にします。
IIS 7 の FastCGI モジュールの更新プログラムによって、一般的な PHP アプリケーションとの互換性に関するいくつかの既知の問題が修正されます。以下のいずれかのサイトから更新プログラムをインストールしてください。
- Windows Server 2008 の更新プログラム
- Windows Server 2008 x64 Edition の更新プログラム
- Itanium ベース システム用の Windows Server 2008 の更新プログラム
- Windows Vista SP1 の更新プログラム
- x64 ベース システム用の Windows Vista SP1 の更新プログラム
メモ: この手順はオプションです。
実用的な機能は他にもありますが、IIS 7 管理パックは、FastCGI 設定を構成するうえでとても便利なユーザー インターフェイスを備えています。以下のサイトより、管理パックをインストールできます。
IIS 7 FastCGI と共にスレッド セーフではない PHP ビルドを使用することをお勧めします。スレッド セーフではない PHP ビルドでは、不要なスレッド セーフ チェックを行わないので、標準ビルドよりも大幅にパフォーマンスが向上します。FastCGI がシングル スレッドの実行環境をサポートしているため、スレッド セーフ チェックの必要がありません。
http://www.php.net/downloads.php(英語) より、スレッド セーフではない PHP バイナリの最新 ZIP パッケージをダウンロードします。
ファイルを任意のディレクトリに解凍します (例 C:\PHP)。php.ini-recommended から php.ini へ名前を変更します。
php.ini ファイルを開き、コメントを解除し、設定を以下のように変更します。
fastcgi.impersonate = 1 と指定する。IIS の FastCGI では、呼び出しているクライアントのセキュリティ トークンを偽装する機能がサポートされています。この機能により、IIS では要求を実行するセキュリティ コンテキストを定義できます。
cgi.fix_pathinfo=1 と指定する。cgi.fix_pathinfo によって、CGI の "本来の" PATH_INFO/PATH_TRANSLATED がサポートされます。PHP の以前の動作では、SCRIPT_FILENAME に PATH_TRANSLATED を設定するというもので、PATH_INFO に関しては特に意識されていませんでした。PATH_INFO に関する詳細については、CGI の仕様書を参照してください。cgi.fix_pathinfo に 1 を設定すると、PHP CGI は仕様に従ってパスを修正します。
cgi.force_redirect = 0 と指定する。
open_basedir に、Web サイトのコンテンツがあるフォルダーまたはネットワーク パスを指定する。
extension_dir に、PHP 拡張モジュールがある場所を指定する。通常 PHP 5.2.X では、extension_dir = "./ext" として設定します。
対応する行のコメントを解除して、必要な PHP 拡張機能を有効にする。たとえば、
extension=php_mssql.dll
extension=php_mysql.dll
PHP のインストールが成功しているか確認するために、コマンド ライン プロンプトから以下のコマンドを実行します。
C:\PHP>php –info
正常に PHP がインストールされ、マシンでのすべての依存関係が正常に機能していると、このコマンドによって現在の PHP 構成情報が出力されます。
IIS 7 に PHP アプリケーションをホストさせるには、ハンドラー マッピングを追加して、FastCGI プロトコルで PHP の特定の要求すべてを PHP アプリケーション フレームワークへ送るよう IIS に命令する必要があります。
IIS マネージャーを開き、サーバー レベルで [ハンドラー マッピング] を選択し、ハンドラー マッピングを開きます。
[モジュール マップの追加] アクションを選択し、以下のように構成設定を指定します。
- 要求パス: *.php
- モジュール: FastCgiModule
- 実行可能ファイル: "C:\[Path to your PHP installation]\php-cgi.exe"
- 名前: PHP via FastCGI
[OK] をクリックします。この実行可能ファイルの FastCGI アプリケーションを作成するかどうか確認するダイアログ ボックスが表示されます。[はい] をクリックします。
ハンドラー マッピングが正常に機能しているか確認するため、以下のコードを記述した phpinfo.php ファイルを C:\inetpub\wwwroot フォルダーに作成します。
<?php phpinfo(); ?>
ブラウザーを開き、https://localhost/phpinfo.php へ移動します。すべて正常にセットアップされた場合、以下のような PHP の標準情報ページが表示されます。
メモ: [モジュール] ドロップダウン リストの中に [FastCgiModule] がない場合、このモジュールが登録されていないか、または有効にされていないことを意味します。FastCGI モジュールが登録されているか確認するには、IIS 構成ファイル %WINDIR%\windows\system32\config\applicationHost.config を開き、<globalModules> セクションに以下の行があるか確認してください。
<add name="FastCgiModule" image="%windir%\System32\inetsrv\iisfcgi.dll" />
また、同じファイルで、<modules> セクションに FastCGI モジュールが追加されているか確認してください。
<add name="FastCgiModule" />
もう 1 つの方法として、コマンド ライン ツール appcmd を使用して、上記のステップを完了することもできます。
FastCGI アプリケーションのプロセス プールを作成するために、以下のコマンドを実行します。
C:\>%windir%\system32\inetsrv\appcmd set config /section:system.webServer/fastCGI /+[fullPath='c:\{php_folder}\php-cgi.exe']
>
その後、ハンドラー マッピングを作成します。
C:\>%windir%\system32\inetsrv\appcmd set config /section:system.webServer/handlers /+[name='PHP_via_FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='c:\{php_folder}\php-cgi.exe',resourceType='Unspecified']
メモ: PHP バージョン 4.X を使用している場合、php-cgi.exe の代わりに、php.exe を使用できます。
このダウンロード (英語) から、共有ホスティング環境における PHP のホスティングに関するベスト プラクティスのプレゼンテーションをご覧いただけます。
共有ホスティング環境における PHP Web サイトの推奨される分離と IIS 7 の推奨される一般的なセキュリティの分離には、整合性があります。以下の点が特に推奨されています。
- Web サイトごとに 1 つのアプリケーション プールを使用する。
- アプリケーション プールの ID として専用ユーザー アカウントを使用する。
- アプリケーション プール ID を使用するように、匿名ユーザー ID を構成する。
- php.ini ファイルで FastCGI 偽装が有効 (fastcgi.impersonate=1) か確認する。
共有ホスティング環境におけるセキュリティの分離に関する詳細については、「アプリケーション プールを使用したサイトの分離」を参照してください。
ネイティブ PHP のリサイクルが開始する前に、FastCGI が必ず php-cgi.exe プロセスをリサイクルしていることを確認してください。構成プロパティ instanceMaxRequests によって、FastCGI プロセスのリサイクル動作を制御します。このプロパティでは、リサイクルする前に FastCGI プロセスが要求をいくつ処理するか指定します。PHP にも、環境変数 PHP_FCGI_MAX_REQUESTS によって制御する同様のプロセス リサイクル機能があります。PHP_FCGI_MAX_REQUESTS の値以下に instanceMaxRequests を設定することにより、ネイティブ PHP プロセスのリサイクル ロジックが作動しないようにすることができます。
FastCGI の設定は、IIS マネージャーおよび appcmd コマンド ライン ツールのどちらを使用しても構成できます。
IIS マネージャーを使用して FastCGI リサイクル設定を構成するには、IIS 7 管理パック をインストールし、サーバー レベルで FastCGI 設定を選択する必要があります。
次に、構成する FastCGI アプリケーションを選択し、右側の [操作] ウィンドウにある [編集] をクリックします。
[FastCGI アプリケーションの編集] ダイアログで、[instanceMaxRequest] を 10,000 に設定して [EnvironmentVariables] 設定の隣にある参照ボタンをクリックします。
PHP_FCGI_MAX_REQUESTS 環境変数を追加し、値に 10,000 を設定します。
メモ: これらの設定を構成しない場合、次の既定の設定が使用されます。instanceMaxRequests = 200、PHP_FCGI_MAX_REQUESTS = 500 (ほとんどの PHP ビルド)。
appcmd を使用して FastCGI および PHP のリサイクル動作を構成するには、以下のコマンドを使用します。
C:\>%windir%\system32\inetsrv\appcmd set config -section:system.webServer/fastCgi /[fullPath='c:\{php_folder}\php-cgi.exe'].instanceMaxRequests:10000
C:\>%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi /+"[fullPath='C:\{php_folder}\php-cgi.exe'].environmentVariables.[name='PHP_FCGI_MAX_REQUESTS',value='10000']"
多くの PHP アプリケーションでは、PHP の特定のバージョンでのみ利用できる機能に依存することがあります。そのようなアプリケーションが同じサーバー上にホストされる場合、異なる PHP バージョンを有効にし、並列で実行する必要があります。IIS 7 FastCGI ハンドラーでは、同じ Web サーバー上での PHP の複数バージョンの使用を完全にサポートします。
たとえば、Web サーバーに PHP 4.4.8、PHP 5.2.1、および非スレッドセーフ版 PHP 5.2.5 をサポートする計画を立てるとします。これを実現するために、対応する PHP バイナリをファイル システム上の別のフォルダーにそれぞれ配置する必要があります (たとえば、C:\php448\、C:\php521\、および C:\php525nts\)。それから各バージョンの FastCGI アプリケーション プロセス プールを作成します。
C:\>%windir%\system32\inetsrv\appcmd set config /section:system.webServer/fastCGI /+[fullPath='c:\php448\php.exe']
C:\>%windir%\system32\inetsrv\appcmd set config /section:system.webServer/fastCGI /+[fullPath='c:\php521\php-cgi.exe']
C:\>%windir%\system32\inetsrv\appcmd set config /section:system.webServer/fastCGI /+[fullPath='c:\php525nts\php-cgi.exe']
さらに、それぞれのサイトで異なるバージョンの PHP を使用する必要のある 3 つの Web サイト (site1、site2、および site3) があるとすると、対応する FastCGI アプリケーション プロセス プールを参照するようにそれぞれのサイトでハンドラー マッピングを定義できます。
メモ: それぞれの FastCGI プロセス プールは、完全なパスと引数プロパティの組み合わせによって一意に識別されます。
C:\>%windir%\system32\inetsrv\appcmd set config site1 –section:system.webServer/handlers /+'..[name='PHP448_via_FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='c:\php448\php.exe',resourceType='Either']
C:\>%windir%\system32\inetsrv\appcmd set config site2 –section:system.webServer/handlers /+'..[name='PHP521_via_FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='c:\php521\php-cgi.exe',resourceType='Either']
C:\>%windir%\system32\inetsrv\appcmd set config site3 –section:system.webServer/handlers /+'..[name='PHP525nts_via_FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='c:\php525nts\php-cgi.exe',resourceType='Either']
以下の設定を使用して、PHP インストールのセキュリティを強化できます。推奨されている変更を行うために、php.ini ファイルを検索し、開きます。以下のとおりに構成設定を編集します。
設定値 | 説明 |
---|---|
allow_url_fopen=Off allow_url_include=Off |
コードの挿入に関する脆弱性の原因になり得る、ファイル処理関数のリモート URL を無効にします。 |
register_globals=Off | register_globals を無効にします。 |
open_basedir="c:\inetpub\" | ファイル システムで PHP プロセスが読み取り/書き込み可能な場所を制限します。 |
safe_mode=Off safe_mode_gid=Off |
セーフ モードを無効にします。 |
max_execution_time=30 max_input_time=60 |
スクリプト実行時間を制限します。 |
memory_limit=16M upload_max_filesize=2M post_max_size=8M max_input_nesting_levels=64 |
メモリー使用量およびファイル サイズを制限します。 |
display_errors=Off log_errors=On error_log="C:\path\of\your\choice" |
エラー メッセージおよびログ記録を構成します。 |
fastcgi.logging=0 | PHP が FastCGI プロトコルを使用して stderr でデータを送信するとき、IIS FastCGI モジュールは要求を失敗します。FastCGI のログ記録を無効にすると、PHP は stderr でエラー情報を送信することや、クライアントへの 500 応答コードを生成することができません。 |
expose_php=Off | PHP の存在を隠します。 |
このセクションでは、サイトごとの PHP 構成を有効にする推奨方法を紹介します。この方法は、ホスティング プロバイダー GoDaddy.com (英語) と共同で Radney Jasmin 氏によって発案、検証された方法です。Windows Server 2008 で FastCGI を使用して PHP ホスティングを提供しています。
各 Web サイトが独自のアプリケーション プールを所有する (IIS 7 の推奨プラクティス) 場合、専用 FastCGI プロセス プールを各 Web サイトと結び付けることが可能です。FastCGI プロセス プールは、完全なパスおよび引数属性の組み合わせによって、一意に識別されます。それで、1 つの php-cgi.exe のような実行可能ファイルに対して複数の FastCGI プロセス プールを作成する必要がある場合、プロセス プールの定義を区別するのに引数属性を使用できます。加えて、PHP プロセスの INI エントリを定義するのに、php-cgi.exe プロセスに対してコマンド ライン スイッチ "-d" を使用できます。このスイッチは、引数文字列を一意にする PHP 設定を行うのに使用します。
たとえば、独自の PHP 設定が必要な 2 つの Web サイト "website1" および "website2" がある場合、FastCGI プロセス プールを以下のように定義できます。
<fastCgi>
<application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\Websites\Website1" />
<application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\Websites\Website2" />
</fastCgi>
この例では、PHP 設定 open_basedir を使用して、各プロセス プール定義を区別しています。加えて、この設定により、各プロセス プールの PHP 実行可能ファイルは、対応する Web サイトのルート フォルダーのみでファイル操作を行うようになります。
website1 の PHP ハンドラー マッピングは、以下のようになります。
<system.webServer>
<handlers accessPolicy="Read, Script">
<add name="PHP via FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\PHP\php-cgi.exe|-d open_basedir=C:\Websites\Website1" resourceType="Unspecified" requireAccess="Script" />
</handlers>
</system.webServer>
また、website2 の PHP ハンドラー マッピングは、以下のようになります。
<system.webServer>
<handlers accessPolicy="Read, Script">
<add name="PHP via FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\PHP\php-cgi.exe|-d open_basedir=C:\Websites\Website2" resourceType="Unspecified" requireAccess="Script" />
</handlers>
</system.webServer>
PHP プロセスが起動すると、さまざまな設定によって、構成 php.ini ファイルの場所が決定されます。PHP ドキュメントでは、PHP の起動プロセスについて詳しく説明されています。PHP プロセスが php.ini ファイルの場所を検索する場所の 1 つに、PHPRC 環境変数があります。PHP プロセスがこの環境変数に指定されたパスに php.ini ファイルを確認するとそのファイルを使用します。指定されたパスになければ、php.ini ファイルの既定の場所を検索します。この環境変数を使用することにより、ホスティングの顧客が独自のバージョンの php.ini ファイルを使用することができます。
たとえば、2 つの Web サイト website1 および website2 が、それぞれファイル パス C:\WebSites\website1 および C:\WebSites\website2 にあるとします。applicationHost.config の <fastCgi> セクションにある php-cgi.exe プロセス プールは以下のように構成されています。
<fastCgi>
<application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\Websites\Website1">
<environmentVariables>
<environmentVariable name="PHPRC" value="C:\WebSites\website1" />
</environmentVariables>
</application>
<application fullPath="C:\PHP\php-cgi.exe" arguments="-d open_basedir=C:\WebSites\Website2">
<environmentVariables>
<environmentVariable name="PHPRC" value="C:\WebSites\website2" />
</environmentVariables>
</application>
</fastCgi>
このようにして、website1 は独自のバージョンの php.ini ファイルを C:\WebSites\website1 に所有することができ、website2 も独自のバージョンの php.ini ファイルを C:\WebSites\website2 に所有できます。この構成では、PHPRC 環境変数で指定された場所に php.ini ファイルが見つからない場合、PHP は php-cgi.exe が存在するフォルダーにある既定の php.ini ファイルを使用します。
一般的な PHP アプリケーションの多くは、URL をユーザーにとっても、検索エンジンにとっても扱いやすくする Web サーバーでの URL 書き換え機能に依存しています。IIS 7 では、URL 書き換えモジュールによる URL 書き換え機能を提供します。
URL 書き換えモジュールの使用方法の詳細については、以下の記事を参照してください。
Microsoft URL 書き換えモジュールのチュートリアル。 URL 書き換えモジュールの使用方法を説明します。
Microsoft URL 書き換えモジュール構成のリファレンス。 モジュールの機能とすべての構成オプションについて説明します。
URL 書き換えモジュールを使用する一般的な PHP アプリケーションの構成については、以下を参照してください。
IIS での PHP アプリケーションのホスティングに関する詳細については、以下の情報を参照してください。