【結論】
Apacheはデフォルトでは、index.phpまたはindex.htmlを探す
ルートディレクトリにindex.phpだけを置いた状態で、
そのindex.phpをAPIとして、GETやPOSTで返却する値を操作したい時、
併せてルーティングを設定する必要がある
【実例】
Dockerで
FROM php:8.2-apache
でPHP+Apacheのローカル環境を構築し、
hogeprojectディレクトリ内に
index.php
todos.json
のようにファイルを配置した状態で、
index.php内で
# JSONファイルの中身を表示する
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $path === '/todos') {
$todos = json_decode(file_get_contents(__DIR__ . '/todos.json'), true);
echo json_encode($todos);
}
else if ($_SERVER['REQUEST_METHOD'] === 'POST' && $path === '/todos') {
# 〜POSTされた値を受けてそれをtodos.jsonに書き込む処理〜
}
というように、
hogeproject/todos というURLに対してGETとPOSTで異なる結果を得たい時、
hogeproject
- index.php
- todos.json
という構造で、ブラウザでhogeproject/todosにアクセスしても、
404NotFoundエラーになる。
これは、Apacheによる「project/todosディレクトリ内のindex.phpないしindex.htmlを探したが見つからなかった」というエラーである。
つまり、Apacheはデフォルトではディレクトリ内のindex.phpないしindex.htmlを探そうとする。
その挙動を制御するためには、ルーティング設定が必要になる。
やり方は色々あると思うが、シンプルに.htaccessファイルを配置する方法を以下に記述する。
hogeproject
- index.php
- todos.json
- .htaccess # 追加
- Dockerfile # 修正
# .htaccess
# pathの内容問わずすべてのアクセスがルートディレクトリのindex.phpに向かうようにする
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
# Dockerfile
# mod_rewriteを有効化
RUN a2enmod rewrite
# Apacheの設定を調整してAllowOverrideをAllに設定
RUN sed -i 's/AllowOverride None/AllowOverride All/g' /etc/apache2/apache2.conf
これによって、hogeproject/todosというpathへのアクセスが、
hogeproject直下のindex.phpに向くようになり、
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $path === '/todos') {
などの判定処理に入るようになる。
補足)
Dockerfileの完全な内容
FROM php:8.2-apache
# 必要なPHP拡張機能をインストール
RUN docker-php-ext-install pdo pdo_mysql
# mod_rewriteを有効化
RUN a2enmod rewrite
# Apacheの設定を調整してAllowOverrideをAllに設定
RUN sed -i 's/AllowOverride None/AllowOverride All/g' /etc/apache2/apache2.conf
# ワーキングディレクトリ設定
WORKDIR /var/www/html
# パーミッションを設定
RUN chown -R www-data:www-data /var/www/html && \
chmod -R 755 /var/www/html