I'm trying to migrate my php web application from Apache to Nginx. And I have a huge problem with converting rewrite rules.
I have used several converters. Even know how to convert it myself, but at the end I'm finish with pretty same result. Default page is downloading php source code instead of showing a page.
If I set root directly to public folder and remove rewrite rules. Default page is displaying but without css, images and with broken links. But this is sort of forseen because the same happens locally (with Apache) if I set DocumentRoot to public and delete .htacces files.
PHP is using Phalcon framework. So *.volt files are compiled to *.volt.php during "php runtime".
Here is my application dir tree.
<repo>
├── app
│ ├── config
│ │ ├── autoloader.php
│ │ ├── config.ini
│ │ └── services.php
│ ├── controllers
│ │ ├── CategoryController.php
│ │ ├── ControllerBase.php
│ │ ├── IndexController.php
│ │ ├── LoginController.php
│ │ ├── ProductController.php
│ │ ├── ProfileController.php
│ │ ├── RankController.php
│ │ └── SignupController.php
│ ├── library
│ │ └── Elements.php
│ ├── models
│ │ ├── Category.php
│ │ ├── CurlHandler.php
│ │ ├── OpinionVote.php
│ │ ├── Product.php
│ │ ├── REST.php
│ │ ├── Users.php
│ │ └── Validator.php
│ └── views
│ ├── category
│ │ └── show.volt
│ ├── index
│ │ └── index.volt
│ ├── index.volt
│ ├── layouts
│ │ ├── footer.volt
│ │ ├── leftColumn.volt
│ │ ├── logo.volt
│ │ └── topMenu.volt
│ ├── login
│ │ └── index.volt
│ ├── product
│ │ └── show.volt
│ ├── profile
│ │ ├── addCategory.volt
│ │ ├── addProduct.volt
│ │ ├── deleteCategory.volt
│ │ └── index.volt
│ ├── rank
│ │ ├── bottom.volt
│ │ ├── index.volt
│ │ └── top.volt
│ └── signup
│ └── index.volt
├── public
│ ├── css
│ │ └── main.css
│ ├── img
│ │ └── oceniarka-logo.png
│ ├── index.php
│ ├── scripts
│ │ └── opinionVoteJs.js
│ └── signup.php
└── README.md
In config.in baseUri = /
Htaccesses
/.htaccess
RewriteEngine on
RewriteRule ^$ public/ [L]
RewriteRule ((?s).*) public/$1 [L]
/public/.htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^.*/img/([a-zA-Z0-9-]+)[.]png$ img/$1.png [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^((?s).*)$ index.php?_url=/$1 [QSA,L]
This i my nginx configuration.
server {
listen ${OPENSHIFT_DIY_IP}:${OPENSHIFT_DIY_PORT};
server_name localhost;
root ${OPENSHIFT_REPO_DIR};
add_header Strict-Transport-Security max-age=691200;
location / {
index index.php index.html index.htm;
rewrite ^/$ /public/ break;
rewrite ((?s).*) /public/$1 break;
}
try_files $uri $uri/ @rewrites;
location /public {
rewrite ^/.*/img/([a-zA-Z0-9-]+)[.]png$ /img/$1.png last;
if (!-d $request_filename) {
set $rule_1 1$rule_1;
}
if (!-f $request_filename) {
set $rule_1 2$rule_1;
}
if ($rule_1 = "21") {
rewrite ^/((?s).*)$ /index.php?_url=/$1 last;
}
}
location = /robots.txt { access_log off; log_not_found off; }
location ~ /\. { access_log off; log_not_found off; deny all; }
location ~ ~$ { access_log off; log_not_found off; deny all; }
# Set expires max on static file types
location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|eot|mp4|ogg|ogv|webm)$ {
access_log off;
log_not_found off;
# Some basic cache-control for static files to be sent to the browser
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
location @rewrites {
rewrite ^(.*)$ /index.php?_url=/$1;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:${OPENSHIFT_RUN_DIR}/php-fpm.socket;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
include fastcgi_params;
}
}
I would be grateful for any help.
You need to rewrite your URIs and add a /public
prefix. This affects all of your files, including PHP files, and can be solved by using nested location blocks.
root ...;
index index.php index.html index.htm;
location / {
rewrite ^ /public$request_uri last;
}
location /public {
try_files $uri $uri/ /public/index.php?_url=$uri&$args;
location ~ \.php(/|$) {
...
}
location ~* \.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|eot|mp4|ogg|ogv|webm)$ {
rewrite (/img/.+\.png)$ /public$1 break;
...
}
}
location = /robots.txt { access_log off; log_not_found off; }
location ~ /\. { access_log off; log_not_found off; deny all; }
location ~ ~$ { access_log off; log_not_found off; deny all; }
I am assuming the /app
path is never accessed. If it is, the location /
needs modification.
Your location ~ \\.php(/|$)
block looks a little strange. It accepts scripts with path info but then fails to break it down. Maybe this works with your particular PHP implementation.
The alternative approach is to set the root to .../public
and identify which rewrite rules are necessary to make the rogue URIs work. Perhaps removing a leading /public
prefix.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.