Zend FrameworkのWelcomeページにhttp://localhost/application/indexでアクセスできない（nginx / Docker / Zend Framework 3）

諸事情で Zend Framework を初めて学習中の西暦2022年。Zend Framework公式ドキュメントのtutorialを元にハンズオン学習している。

## 1. やりたいことを確認する。

- Zend FrameworkのWelcomeページは http://localhost/ もしくは http://localhost/application/index にアクセスするとWelcomeページが表示されるようにルーティングを設定できるようになっており、そのように表示されるようにしたい。
- 開発環境の構築にDockerを利用しており、下記の構成にしている。（Zend Framework の公式ドキュメントでは、Webサーバは Apache が使用されており、 nginx についての記述はない。）
    
    
    | Dockerコンテナ | Dockerイメージ | 備考 |
    | --- | --- | --- |
    | web | nginx:1.18.0-alpine |  |
    | app | php:7.4.19-fpm-alpine3.13 | パッケージ依存管理ツール：Composer 1系 / フレームワーク：Zend Framework 3系 |
    | db | mysql:5.6 |  |

## 2. 課題（エラーの状況、不明点、エラーログ）を確認する。

⚠️ Zend FrameworkのWelcomeページは http://localhost/ にアクセスすると表示されるが、http://localhost/application/index にアクセスするとWelcomeページが表示されない。

![スクリーンショット 2022-01-21 10.59.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527226/1dedf284-8a01-33b2-9e00-f21fd6328fbe.png)

nginx の 404 Not Found のエラー。

## 3. 調査する（ググる、ドキュメントを読む）

Zend Framework公式ドキュメントのtutorialを読み返してみる。

> You will not be able to navigate to any page other than the home page in this tutorial if you have not configured `mod_rewrite` and `.htaccess` usage correctly.
> 
> 
> （以下、DeepL翻訳）
> 
> `mod_rewrite` と `.htaccess` の使用法を正しく設定しないと、このチュートリアルのホームページ以外のページに移動することができません。
> 

https://docs.zendframework.com/tutorials/getting-started/overview/

現状はまさに「ホームページ以外のページに移動することができません」という状況であり、ここの設定を nginx で行えれば、解消するかもしれない。

**`localhost/application/index` にアクセスした時に、 `public/index.php` にリダイレクトできていないのが原因**ではないかと思う。

その線で調査する。

調査① conf

> nginx
> 
> 
> nginx は Apache のような `.htaccess` ファイルを利用しませんので、 サイトの設定で URLの書き換えルールを作成する必要があります。 これは大抵 `/etc/nginx/sites-available/your_virtual_host_conf_file` に記載します。 あなたの環境構成に応じて、このファイルを書き換えなければなりませんが、 少なくとも PHP を FastCGI として稼働させる必要はあるでしょう。 下記の設定は、**リクエストを `webroot/index.php` にリダイレクトします。**
> 
> ```diff_nginx
> location / {
>     try_files $uri $uri/ /index.php?$args;
> }
> ```
> 
> server ディレクティブの例は、次の通りです。
> 
> ```diff_nginx
> server {
>     listen   80;
>     listen   [::]:80;
>     server_name www.example.com;
>     return 301 http://example.com$request_uri;
> }
> 
> server {
>     listen   80;
>     listen   [::]:80;
>     server_name example.com;
> 
>     root   /var/www/example.com/public/webroot;
>     index  index.php;
> 
>     access_log /var/www/example.com/log/access.log;
>     error_log /var/www/example.com/log/error.log;
> 
>     location / {
>         try_files $uri $uri/ /index.php?$args;
>     }
> 
>     location ~ \.php$ {
>         try_files $uri =404;
>         include fastcgi_params;
>         fastcgi_pass 127.0.0.1:9000;
>         fastcgi_index index.php;
>         fastcgi_intercept_errors on;
>         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
>     }
> }
> ```

https://book.cakephp.org/3/ja/installation.html#nginx

 → 違うフレームワーク（CakePHP）のドキュメントだけど、同じ内容でいけそう。

もう少し調査。

調査② try_files

> **try_files**
Nginxの設定にて、静的なファイルと動的なURLを振り分けたいことがあります。
try_filesを利用すれば、指定した順番で確認と転送を実施してくれます。
> 
> 
> 以下の順番で確認してくれます。
> 
> URLのパスにファイルがあるか($uri)
> 
> 1がなかった場合、URLのパスにディレクトリがあるか($uri/)
> 
> 1も2もなかった場合、指定したロケーションへ行く。(/hogehoge/sample)
> 
> ```diff_nginx
> location /sample {
> 	try_files $uri $uri/ /hogehoge/sample;
> }
> ```
> 
> リダイレクトする前のURLのまま、リダイレクト先のphpなどを実行したい場合に使えます。
> 
> URLはhttps://sample.jp/sample のまま、
> https://sample.jp/hogehoge/sample/index.php を読み込ませたい。
> ↓
> 
> ```diff_nginx
> location = /sample/ {
> 	try_files $uri $uri/ /hogehoge/sample/$args;
> }
> ```
> 

https://blog.grasys.io/post/tsunoda/nginx-rewrite/#:~:text=php.txt.txt%0A%7D-,try_files,-Nginx%E3%81%AE%E8%A8%AD%E5%AE%9A

調査③ try_files

https://tsyama.hatenablog.com/entry/try_files_is_difficult

## 4. 調査結果からの考察、対策を実行する

### リクエストを `localhost/index.php` にリダイレクトするための設定を、 nginx.conf に `try_files` 記述する。

編集： docker/nginx/nginx.conf

```diff_nginx
server {
    listen 80;
    server_name localhost
    index index.php index.html;
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/sample-app/public;

    location / {
        root /var/www/sample-app/public;
        index index.php index.html;
+        try_files $uri $uri/ /index.php?$args;
        autoindex on;
        autoindex_localtime on;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
```

http://localhost/application/index にアクセスしても表示された！
![スクリーンショット 2022-01-21 10.58.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527226/eff39b79-fc08-c422-d0b4-468dab39a80a.png)
解決！