この記事を書く前まで、私はWordPressをルート直下に入れていると別のアプリや配布フォルダを設置できないと思っていました。
ChatGPTに相談したところ、.htaccessを修正するだけでWordPressと別アプリが両立できることが分かりました。

この記事では、/app にPHPアプリ、/download に配布ディレクトリを用意する構成を紹介します。
「WordPressの外側に小さな実行環境や配布口を加えられる」と理解できたことで、サイトの自由度が大きく広がったと実感しています。

この記事で分かること

  • ルート直下WordPressとサブフォルダを共存させる設計の要点を整理します。
  • ルートの.htaccessで行うリダイレクトと除外の最小手順を提示します。
  • サブフォルダ側.htaccessで親のリダイレクトやリライトを無効化する方法を解説します。
  • /download を安全な配布置き場として扱う基本設定を示します。
  • 検証の順番と復旧の考え方を手順化します。

結論と全体像

次の3つの手順で共存環境を実現できます。

  1. ルートの.htaccessで「HTTP→HTTPSの統一」を実行する。
  2. 続けて「/app/download をWordPress処理から除外」する。
  3. 各サブフォルダ直下に.htaccessを配置し、親リライトを無効化する。

この設定により、WordPressのパーマリンク設定に影響されず、PHPや静的配布をそれぞれ動かすことができます。
私は全体を理解した後、少し設定しながら確認しながら進めたので、短時間で設定ができました。

前提とフォルダ構成

XServerを使用し、public_html直下にWordPressが配置されている前提で説明します。

public_html/
├─ app/ # PHPアプリを置く
│ ├─ test.php
│ └─ phpinfo.php
├─ download/ # 配布ファイルを置く
│ └─ sample.zip
├─ .htaccess # ルート(本稿の設定)
└─ WordPress一式

サイト全体のリクエストは以下の図の通りです。

ルートの.htaccess最小構成

WordPress自動領域より前に、次のブロックを追加します。
最初にHTTPSへ統一し、その後で /app/download を除外しています。

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  # 1) HTTP→HTTPS の統一
  RewriteCond %{HTTPS} off
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

  # 2) WordPress処理から /app /download を除外
  RewriteCond %{REQUEST_URI} ^/(app|download)(/|$)
  RewriteRule ^ - [L]
</IfModule>

# BEGIN WordPress
# (この下はWordPressが自動管理する領域)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

WordPressの既定ブロックは変更せず、上部に追記する形がおすすめです。

サブフォルダ側.htaccessで親のリダイレクトやリライトを無効化

親の.htaccessの影響を受けないように、/app/download に次の.htaccessを置きます。

# public_html/app/.htaccess
<IfModule mod_rewrite.c>
  RewriteEngine Off
</IfModule>

この設定により、上位のリダイレクトやリライトが当たらなくなります。
私の環境では、この設定で予期しない挙動が減り、安心して確認ができました。

/download を安全な配布置き場にする

配布専用フォルダでは、PHP実行を禁止しておくと安全性が高まります。
さらに、表示ではなくダウンロードを促す設定も付けられます。

下記はPHP実行禁止の設定です。

# 実行抑止と一覧抑止(public_html/download/.htaccess に追記)
Options -Indexes -ExecCGI
<FilesMatch "\.(php|phar)$">
  Require all denied
</FilesMatch>

下記の設定は、ダウンロード画面を表示するファイルの拡張子です。
設定は任意です。

# 任意: ダウンロードを促すヘッダ(表示より保存を優先)
<IfModule mod_mime.c>
  AddType application/octet-stream .pdf .zip .csv .xlsx .jpg .png
</IfModule>
<IfModule mod_headers.c>
  <FilesMatch "\.(pdf|zip|csv|xlsx|jpg|png)$">
    Header set Content-Disposition "attachment"
  </FilesMatch>
</IfModule>

配布方法はサイトの目的に合わせて調整してください。
私は最初に制限を強めに設定し、必要に応じて緩めていく形で進めています。

ChatGPTに相談して進めたポイント

私は「ルート直下のWordPressでは別アプリは難しい」と思い込んでいましたが、ChatGPTから、除外とサブフォルダ側の無効化を組み合わせる方法を提案され、簡単に設定できました。
こんなに簡単に設定できるのであれば、ChatGPTに早く聞いておけばよかったと少し後悔しています。

動作確認チェックリスト

確認作業は次の順で進めます。
一度に多くを変えず、段階的に進める方が復旧もしやすくなります。

  • http://ドメイン/ へアクセスすると https:// に統一される。
  • https://ドメイン/app/test.php で「Hello」などが表示される。
  • https://ドメイン/app/phpinfo.php でPHP情報が見える。
  • https://ドメイン/download/sample.zip へ直アクセスでファイル取得ができる。
  • デベロッパーツールのネットワークで、不要な重複リダイレクトが発生していない。

私は変更を少しずつ行って、問題が出たら直前の状態に戻して差分を確認しています。

トラブルシュートの要点

よく起きるトラブルと解決策を紹介します。

500エラーが出る

.htaccessの構文エラーが原因となることが多いです。
編集を戻して最小構成にし、1ブロックずつ追加することで原因を特定できます。

サブフォルダに到達しない

除外ルールの順序や位置を確認します。
設定に問題がある場合、WordPress既定ブロックより前に除外を書き、サブフォルダ側で親リライトを無効化になっているのか確認してみてください。

配布ファイルが実行扱いになる

/download 側でPHP実行を禁止する設定を入れます。
それでも意図せぬ動作が続く場合は、拡張子やヘッダ指定を見直す必要があります。

まとめ

.htaccessの分岐とサブフォルダ側の無効化を組み合わせることで、ルート直下のWordPressでも/app/download を安全に共存させられます。
小さなアプリ公開やファイル配布の導線を新たに加えることができ、サイト運用の幅が大きく広がりました。
私はこの仕組みを導入したことで、土台が安定し、用途に応じて段階的に拡張する準備が整ったと感じています。
今後は配布エリアの限定に役立つBasic認証や、運用を助ける301の正規化パターンなども取り上げる予定です。