7.

URL から index.php を消す方法(Apache / Nginx / Laravel / CodeIgniter 完全ガイド)

編集
この記事の要点
  • Apache: .htaccessRewriteEngine On + RewriteRule を書き、AllowOverride All を有効化
  • Nginx: try_files $uri $uri/ /index.php?$query_string; をサーバーブロックに記述
  • Apache では mod_rewrite が必須 → sudo a2enmod rewritesystemctl reload apache2
  • Laravel は public/ がドキュメントルート想定で public/.htaccess 同梱済
  • 404 になる原因の多くは AllowOverride Nonemod_rewrite 未有効

なぜ index.php を消したいのか

多くの PHP フレームワーク(Laravel / CodeIgniter / Symfony / CakePHP)はシングルエントリポイントです。すべてのリクエストが index.php を経由してルーティングされる仕組みなので、URL は次のような形になりがちです:

http://example.com/index.php/user/show/123
http://example.com/index.php?route=user/show&id=123

これをクリーン URL(綺麗な URL)に書き換えるのが本記事のテーマです:

http://example.com/user/show/123

Apache での設定(.htaccess)

Apache では mod_rewrite + .htaccess で実現します。ドキュメントルートに .htaccess を置きます:

# /var/www/html/.htaccess


    RewriteEngine On

    # 1) 既存のファイル / ディレクトリはそのまま配信
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    # 2) それ以外は index.php へ
    RewriteRule ^ index.php [L]

クエリ文字列を引き継ぐパターン(CodeIgniter 系):


    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?/$1 [L,QSA]

Apache: mod_rewrite を有効化

.htaccess を置いても動かない最大の原因は mod_rewrite 未有効です:

# Ubuntu / Debian
sudo a2enmod rewrite
sudo systemctl restart apache2

# CentOS / RHEL は通常デフォルト有効。確認するには
httpd -M | grep rewrite
# rewrite_module (shared) が表示されれば OK

Apache: AllowOverride All を確認

.htaccess は AllowOverride ディレクティブで許可されていないと完全に無視されます。これが「.htaccess を書いても何も起こらない」場合の典型原因です:

# /etc/apache2/apache2.conf または /etc/httpd/conf/httpd.conf


    Options Indexes FollowSymLinks
    AllowOverride All        # ← None ではなく All に
    Require all granted
# 設定変更後は再読み込み
sudo systemctl reload apache2

# 構文チェック(reload 前推奨)
sudo apachectl configtest

Nginx での設定

Nginx には .htaccess が無く、nginx.conf または sites-available/*.conf に直接記述します:

server {
    listen 80;
    server_name example.com;
    root /var/www/html/public;     # Laravel なら public/
    index index.php index.html;

    # 既存ファイル / ディレクトリ → そのまま
    # 無ければ index.php に引き渡し
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # PHP を php-fpm にプロキシ
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    # .ht* を隠す
    location ~ /\.ht {
        deny all;
    }
}
# 構文チェック → リロード
sudo nginx -t
sudo systemctl reload nginx

Laravel の場合

Laravel は標準で public/.htaccess を同梱しています。ドキュメントルートが public/ になっていれば追加設定不要です:

# Laravel 標準の public/.htaccess

    
        Options -MultiViews -Indexes
    

    RewriteEngine On

    # Authorization ヘッダ転送
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # 末尾スラッシュ削除(外部リダイレクト)
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Front controller へ
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

共用サーバで public/ をドキュメントルートにできない場合の対策:

# プロジェクトルート(/var/www/myapp/)の .htaccess
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]

CodeIgniter の場合

# CodeIgniter 4 のドキュメントルート/public/.htaccess

    Options +FollowSymlinks
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([\s\S]*)$ index.php/$1 [L,QSA]

さらに CodeIgniter の app/Config/App.php で:

public string $indexPage = '';   // 'index.php' から空文字へ
public string $uriProtocol = 'REQUEST_URI';

動かないときのチェックリスト

症状原因対処
500 Internal Server Error.htaccess の文法エラー / mod_rewrite 未有効tail -f /var/log/apache2/error.log で確認
404 Not FoundAllowOverride Noneconf で AllowOverride All
.htaccess を書いても変化なし.htaccess 自体が無視されているAllowOverridea2enmod rewrite を確認
静的ファイルまで index.php に飛ぶRewriteCond !-f が抜けている条件式を追加
Nginx で index.php がダウンロードされるphp-fpm 未連携location ~ \.php$ ブロック追加

FAQ

Q: 共用サーバで mod_rewrite が無効
A: ホスティング業者に申請するか、PHP 側で $_SERVER['PATH_INFO'] を使うルーティングに変更してください。

Q: HTTPS リダイレクトと併用したい
A: RewriteCond %{HTTPS} off + RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]index.php ルールのに書きます。

Q: WordPress と同じ .htaccess で動く?
A: WordPress も同じ仕組みです。WordPress 用 .htaccess(RewriteRule . /index.php [L])をそのまま使えます。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. インストール方法(Ubuntu + Apache)
  2. Wordpressのインストール方法(CentOS + nginx)
  3. ローカル環境への導入方法
  4. PHPの使用方法
  5. DB設定
  6. DB接続方法
  7. index.phpをURLに含めないようにする方法
  8. コメントに絵文字を入力可能にする方法
  9. サイト(ドメイン)の引越し方法
  10. 独自の関数一覧
  11. エラー一覧
  12. (未完)Wordpressの一連の処理の流れ