質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

10269閲覧

PHP-FPM使用時のPHPファイルへのErrorDocument設定について・検証追記

snic518

総合スコア39

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2016/02/22 09:19

編集2016/02/25 08:40

前回、こちらの質問をさせていただきまして、その結果下記の構成で構築を進めていました。
また少し躓いてしまったので、質問を書かせていただいております。

  • VPS(さくらVPS)
  • CentOS7
  • Apache 2.4.6
  • PHP 7.0.3(PHP-FPM)

PHP-FPMを利用するため、Apacheには下記の設定をしています。

apache

1# php-fpm用の設定 2ProxyPassMatch ^(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1 3DirectoryIndex /index.php index.php

これで、PHPファイルがFPM/FastCGIで動いていることを確認できました。
ここまでは良かったのですが、この後ちょっと困ったことになりました。

バーチャルホスト設定のところで、独自のエラー画面を出すために、ErrorDocumentを設定しました。

apache

1<Directory "/var/www/html"> 2 : 3 : 4 ErrorDocument 503 /error/503.html 5 ErrorDocument 404 /error/404.html 6</Directory>

これで、存在しないアドレスにブラウザアクセスすると、HTMLファイルや画像ファイル等は、思った通りのエラー画面(/error/404.html)が表示されるのですが、PHPファイルだけは、おそらくPHP-FPMの標準のエラー表示がされるようなのです。
その時の表示は、「File not found.」とのテキスト表示のみで、ステータスコードは404です。

PHPファイルはFCGIの実行パスに飛ばしているから、そこのディレクトリにErrorDocumentを設定しないといけないのかと思いますが、PHP-FPMの実行ディレクトリがどこなのか、そもそもそれで良いのか等が、なかなか調べても出てこなかったので、質問させていただきました。

こうした場合にPHPファイルにもErrorDocumentを適用するには、どのようにすればよいのでしょうか。

ご意見賜れますと幸いです。
よろしくお願いいたします。


###【20160225追記】

回答いただいた通りに、

この解決方法は、下記のサイトにもありました。

Apache 2.4 + PHP-FPM, catching error pages

結果、VirtualHostディレクティブの設定は以下のようになりました。

※今回の問題に関係ない記述もあると思いますが、念のためすべて掲載しました。

apache

1<VirtualHost *:80> 2 ServerName hoge.jp 3 DocumentRoot /var/www/html 4 5 ProxyErrorOverride On 6 ErrorDocument 503 /error/503.html 7 ErrorDocument 404 /error/404.html 8 ProxyPassMatch ^(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1 9 <Directory "/var/www/html"> 10 Require all granted 11 Options FollowSymLinks 12 13 # Expires settings 14 ExpiresActive On 15 ExpiresByType text/css "access plus 7 day" 16 ExpiresByType text/javascript "access plus 7 day" 17 ExpiresByType application/x-javascript "access plus 7 day" 18 19 # gzip transrate 20 RewriteEngine On 21 RewriteCond %{HTTP:Accept-Encoding} gzip 22 RewriteCond %{REQUEST_FILENAME} \.js$ [OR] 23 RewriteCond %{REQUEST_FILENAME} \.css$ 24 RewriteCond %{REQUEST_FILENAME} !\.gz$ 25 RewriteCond %{REQUEST_FILENAME}\.gz -s 26 RewriteRule .+ %{REQUEST_URI}.gz 27 28 <FilesMatch "\.js\.gz$"> 29 ForceType application/x-javascript 30 AddEncoding x-gzip .gz 31 </FilesMatch> 32 33 <FilesMatch "\.css\.gz$"> 34 ForceType text/css 35 AddEncoding x-gzip .gz 36 </FilesMatch> 37 </Directory> 38</VirtualHost> 39

その結果、下記のような状態になりました。

・PHP以外のファイル … 変化無し。期待通りのエラーページ表示
・PHPファイル … 「File not found.」ではなく、ブラウザのエラーが発生。

ブラウザのエラーは、chromeの場合下記画像のような表示になります。

エラー表示

また、アドバイスいただいた通り、コンソールからcurlでアクセスしてみた場合は、期待通りのページのソースが返ってきました。

SSH

1$ curl http://127.0.0.1/nofile.php 2<!doctype html> 3<html lang="ja"> 4<head> 5<meta charset="utf-8"> 6<meta name="robots" content="noindex,nofollow"> 7<title>404</title> 8</head> 9: 10: 11</html>

これは外部の別のサーバーからIPを指定して実行しても同じで、なおかつ外部サーバーから、例えばPHPの下記のようなスクリプトを叩いてみても、期待する404ページHTMLが出力される状態です。

PHP

1<?php 2$context = stream_context_create(array( 3 'http' => array('ignore_errors' => true) 4 )); 5 6$url = "http://hoge.jp/nofile.php"; 7echo file_get_contents($url, false, $context);

この時のレスポンスヘッダは以下でした。

HTTP/1.1 404 Not Found Date: Thu, 25 Feb 2016 08:35:23 GMT Server: Apache Last-Modified: Thu, 25 Feb 2016 08:31:54 GMT Accept-Ranges: bytes Content-Length: 1823 X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Connection: close Content-Type: text/html; charset=UTF-8

つまり、データの通信上は正しく設定されたものがやり取りされているものの、ブラウザが受信した場合はそれをHTMLページとして表示できていない、という状態なのかなと思います。

なお、iPhone Safariでアクセスすると、エラーページの表示は「RAWデータをデコードできません」というものになりました。

Content-Typeはちゃんとtext/htmlになっているみたいなのですが、どうしてこのような状態になっているのか、色々調べてもわかりませんでした。

何か問題点があるか、どなたかおわかりになりませんでしょうか。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

php-fpm 側にエラードキュメントを設定する方法についてはわかりませんが、
RewriteCond で .php ファイルが存在する場合のみ php-fpm に渡す方法はどうでしょうか。

RewriteEngine On RewriteCond %{REQUEST_URI} ^/(.*\.php)(/.*)?$ RewriteCond /var/www/html/%1 -f RewriteRule ^(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1 [P,L]

(追記)
ProxyErrorOverride On とする方法もありました。
ただし、<Directory "/var/www/html"> のスコープから外れるようですので、
別途、ErrorDocument を設定する必要があります。

ProxyErrorOverride On ErrorDocument 503 /error/503.html ErrorDocument 404 /error/404.html ProxyPassMatch ^(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1

投稿2016/02/22 15:37

編集2016/02/22 15:54
TaichiYanagiya

総合スコア12146

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

snic518

2016/02/23 00:32

回答ありがとうございます。 PHP-FPMの設定をRewriteRuleでやると、他のRewriteRule設定と干渉しないように気をつけないといけなくなる、というのをどこかで見たので、後者の方が良さそうだと思いました。 この場合、 ><Directory "/var/www/html"> のスコープから外れる とのことですが、上記の記述はDirectoryの外に移動して、 ErrorDocumentのパスをフルパス(/var/www/html/error/404.htnl など)に変更する、ということで良いのでしょうか。
TaichiYanagiya

2016/02/23 01:14

ErrorDocument を Directory の外に移動するだけでいいと思います。 パスは DocumentRoot からの相対パスでしか設定できないはず。
snic518

2016/02/23 08:27

コメントありがとうございます。大変助かります。 早速ProxyErrorOverrideの方を試してみました。 ------------------------------------------------------------------- #Directoryの外に追記 ProxyErrorOverride On ErrorDocument 503 /error/503.html ErrorDocument 404 /error/404.html ProxyPassMatch ^(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1 <Directory "/var/www/html"> : : #ErrorDocument 503 /error/503.html #ErrorDocument 404 /error/404.html </Directory> ------------------------------------------------------------------- すると、今度は存在しないPHPファイルにアクセスした時にブラウザのエラーが返るようになりました。 ※Chromeだと「このウェブページにアクセスできません ERR_CONTENT_DECODING_FAILED」と出ます。 エラーログは下記のようになっていて、これは変更前と同じです。 AH01071: Got error 'Primary script unknown\n' PHP以外のファイルについては、変更前後も同じように意図したページ表示になりました。 これは、エラーのHTMLをPHP-FPMが参照できる場所に追加で置かないといけないということでしょうか。 たびたびすみません。
snic518

2016/02/23 09:46

コメントありがとうございます。 >curl http://127.0.0.1/nofile.php こちら、試したところ、コンソール上には指定したページのソースが返ってきました。 ------------------------------------------------------------------- $ curl http://127.0.0.1/nofile.php <!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="robots" content="noindex,nofollow"> <title>404</title> </head> : : </html> ------------------------------------------------------------------- また、こことは別のサーバーから同じようにcurlを叩いた場合も 同様に404エラー用のHTMLソースが返ってきました。 しかし、依然ブラウザからのアクセスでは見えない状態です。 ドメインではなくIP直アクセスにしてみてもダメでした。 通信環境の問題も考え、スマートフォンからアクセスしてみても、同様にページが見つからないエラーとなりました。 何か他に原因になりそうなことはありますでしょうか。
guest

0

追記をした後、エラーメッセージを再度検索していろいろ調べたところ、解決しました。

参考ページ:
Fixing ERR_CONTENT_DECODING_FAILED in Apache+PHP

php.iniの設定で、zlib.output_compressionを有効にしていました。

PHP

1zlib.output_compression=On

これが原因だったようで、Offにした後PHP-FPMを再起動したところ、エラーページが表示されるようになりました。
お騒がせいたしました。

zlib.output_compression=On の設定は、存在するスクリプトだけで機能するよう、スクリプト内のini_setで指定するようにします。

投稿2016/02/25 09:06

snic518

総合スコア39

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問