简体   繁体   中英

Apache to nginx migration, rewrite problems with .htaccess

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM