Назад | Перейти на главную страницу

Как избежать index.php в маршруте Zend Framework с помощью Nginx rewrite

Я пытаюсь избавиться от index.php из маршрута Zend Framework по умолчанию. Думаю, это нужно исправлять на уровне сервера, а не в приложении. (Поправьте меня, если я ошибаюсь, но я думаю, что делать это на стороне сервера более эффективно).

Я запускаю Nginx 0.7.1 и php-fpm 5.3.3

Это моя конфигурация nginx

server {
    listen *:80;
        server_name domain;
        root   /path/to/http;
        index index.php;
        client_max_body_size 30m;

        location / {
                try_files $uri $uri/ /index.php?$args;
        }
        location /min {
                try_files $uri $uri/ /min/index.php?q=;
        }
        location /blog {
                try_files $uri $uri/ /blog/index.php;
        }
        location /apc {
                try_files $uri $uri/ /apc.php$args;
        }

        location ~ \.php {
                include /usr/local/etc/nginx/conf.d/params/fastcgi_params_local;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_script_name;
                fastcgi_param SERVER_NAME $http_host;
                fastcgi_pass 127.0.0.1:9000;
        }

        location ~* ^.+\.(ht|svn)$ {
                deny  all;
        }

        # Static files location
        location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
            expires max;
        }

}

Обычно www.domain.com/index.php/path/to/url и www.domain.com/path/to/url обслуживают один и тот же контент.

Я бы хотел исправить это с помощью nginx rewrite.

Идеальное решение действительно включает поддержку со стороны приложения, поскольку оно должно понимать, по какому пути оно работает. Это позволяет ему выбирать правильный ресурс для обслуживания и возвращать правильные ссылки и перенаправления. В этом случае конфигурация nginx будет выглядеть примерно так:

location / {
    include fastcgi_params;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_script_name;
    fastcgi_pass 127.0.0.1:9000;
}

т.е. просто передать все [0] в определенный PHP-скрипт. Это может действительно работать с Zend (я сам не использовал).

Если приложение не может быть изменено, чтобы понять это, тогда все становится беспорядочно с переписыванием путей и изменением содержимого. Уловка с перезаписью заключается в том, чтобы убедиться, что перезаписанный путь больше не будет перезаписан. Далее будут перезаписаны пути к /index.php и переданы Zend.

location ~ \.php(/|$) {
    include fastcgi_params;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_pass 127.0.0.1:9000;
}

location / {
    rewrite ^/(.*)$ /index.php/$1;
}

Если это не сработает, это, вероятно, связано с тем, что Zend неправильно обрабатывает запрос - проверьте журналы, чтобы узнать, какой путь он пытается найти.

Однако это не приведет к тому, что ссылки, возвращаемые в HTML, или перенаправления, отправленные Zend, будут использовать путь без "index.php", и nginx, похоже, не имеет механизма для их изменения. Проверьте, есть ли у Zend способ настроить корневой путь для ссылок и перенаправлений.

[0] Очевидно, вы захотите напрямую обслуживать статический контент, я это пропустил.

Вам понадобятся места, похожие на это в каждом из ваших мест. Я просто пишу пример для /blog расположение:

location /blog/ {
    try_files $uri $uri/ @blog;
}

location @blog {
    rewrite ^/blog/(.*)$ /blog/index.php/$1 last;
}

Также замечено в вашей конфигурации: вы можете использовать fastcgi_split_path_info в вашем местоположении PHP:

location ~ ^(.+\.php)(.*)$ {
    include fastcgi_params;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_pass   localhost:9000;
}   

Видеть документация для подробностей.

# Rewrite rule adapted for Zend Framework
location / {
    index index.php;
    if (!-f $request_filename) {
        rewrite ^(.*)$ /index.php last;
    }
}

Попробуйте что-нибудь подобное:

rewrite ^/(.*)$    /index.php/$1;