Issues converting .htaccess to Nginx configuration for PHP scripts - php

I have an .htaccess file that I'm trying to convert so it can be run on my Nginx server.
I'm having two primary problems:
1. I'm not sure how to convert some lines
2. I don't know where to put the Nginx configuration code
Here are the lines I'm having issues converting:
Options All -Indexes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?page_request=$1 [QSA,L]
I've tried some online converters, but they don't seem to be working.
Also, once I've converted the lines, where do I put them? I assume I need to place them in the mysite.conf file in /etc/nginx/sites-available/, but within that file, do I just put them within the server {} block?
Thanks a lot for any help you can give me.
Edit: Here's the conf file
server {
listen 0.0.0.0:80;
server_name www.subdomain.domain.tld subdomain.domain.tld;
access_log /var/log/subdomain.domain.tld.log;
location / {
root /srv/www/subdomain.domain.tld/public_html;
index index.html index.php;
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /srv/www/subdomain.domain.tld/public_html$fastcgi_script_name;
}
try_files $uri $uri/ /index.php?page_request=$uri;
}

UPDATE
Doing some nginx research, came across this, give this a shot and see if it works as you expect:
location / {
# other code below this line
try_files $uri $uri/ /index.php?page_request=$uri;
}
Basically the try_files is the if statement, it tries the regular file first, if it cannot find it, it tries it as a directory, if it cannot find that it sends it to the last argument.
OLD
Have you tried using a service like: http://www.anilcetin.com/convert-apache-htaccess-to-nginx/
It outputs:
#ignored: condition 0
#ignored: condition 1
if ($rule_0 = "2"){
rewrite /RewriteRule ^/(.*)$;
}
For the data you provided.
Where you put them is inside the:
server {
}
Since this is not for a specific location you would just put it after the default stuff. There is order of operations to be had, so yea. It can be inside of a location, if you have more than one location type bit. For nginx, I would probably put this under the .php location definition.

Related

Return content based on REQUEST_URI by PHP

Say, My domain is 'www.miraj.com'. If users click on the link 'www.miraj.com/childhood-of-miraj' then I want to check my database if there is any post having the title 'childhood-of-miraj' it should be shown otherwise 404 page will be shown. But since there is no directory(folder) named 'childhood-of-miraj' it immediately returns 404 page. How can I do that?
This depends on the httpd you are using (Apache or Nginx).
For Apache, you should edit your .htaccess file to look like this:
RewriteEngine On # Turn on the rewriting engine
RewriteRule ^([A-Za-z-]+)/?$ FileToHandleDatabaseSearch.php?title=$1 [NC,L]
This will transform the URL on fly www.miraj.com/childhood-of-miraj to www.miraj.com/FileToHandleDatabaseSearch.php?childhood-of-miraj on the server, not in browser address bar.
FileToHandleDatabaseSearch.php
if (isset($_GET['title'])) {
//...Search DB for $title
//If title exists display page with title
//If title does not exist display 404 page not found
}
For NGINX you edit that in the conf file
www.miraj.com.conf in /etc/nginx/sites-available should look like this
server {
listen 80;
listen [::]:80;
root /path/to/project/root;
server_name www.miraj.com;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
rewrite ^([A-Za-z-]+)/?$ FileToHandleDatabaseSearch.php?title=$1 last;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
}
You would want to prefix the paths to be object-specific to avoid URL conflicts. For example if childhood-of-miraj is a movie title let the rewrite conditions be rewrite ^/movies/([A-Za-z-]+)/?$ "/path/to/project/root/FileToHandleDatabaseSearch.php?title=$1" last;
You can visit Apache Rewrite Rules for more .htaccess rules you can employ and Nginx Rewrite Rules for more Nginx rules you can employ.

How do I get NGINX to properly rewrite and execute on a custom PHP application?

We have a custom PHP application that we wrote and runs on Apache with .htaccess files to handle the url rewrites. We are trying to convert it to work under NGINX with FPM under Plesk Onyx.
The application generates links like:
https://somedomain.com/mypage (same as index/mypage)
https://somedomain.com/index/sitemap
https://somedomain.com/blog/some-article-name
These URL's map to index.php files that take the request_uri and use it to render the page responses.
The structure of the application is nested as follows:
docroot (/)
./index.php //handler for the request in /
./blog/index.php //handler for any request to /blog
Each index.php expects to receive a ?path={request_uri} so that it can map the request to the controllers and actions.
I have tried multiple ways to get NGINX to do this using tryfiles and rewrite, but no luck. Using rewrite I can get / to work, but it wont render /mypage or /index/sitemap.
If I try to hit /index/sitemap it downloads the index.php instead of executing it, and if I try the blog the same thing happens. In fact the only path that works is /, all others just download the index.php file.
Here is my configuration as it is now, where am I going wrong?
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Pragma public;
add_header Cache-Control “public”;
try_files $uri #fallback;
}
location / {
#index index.php index.html index.html;
rewrite ^/([^?]*) /index.php?path=$1 break;
rewrite ^blog/([^?]*) /blog/index.php?path=$1 break;
#try_files $uri #fallback;
}
Your configuration has multiple issues. I will ignore the first location block as it seems to have nothing to do with your question.
The first rewrite will always match, so the second rewrite will never be consulted. The second rewrite will never match anyway, as nginx URIs always begin with a /. The [^?] is meaningless, because rewrite uses a normalised URI which does not include the ? or query string. Using rewrite...break means that the rewritten URI is processed within the same location, which is an error as this location is not equipped to process PHP files. See this document for more.
A solution using try_files might look like this:
location / {
try_files $uri $uri/ /index.php?path=$uri&$args;
}
location /blog {
try_files $uri $uri/ /blog/index.php?path=$uri&$args;
}
location ~ \.php$ { ... }
See this document for more.

Clean URLs and php extension on nginx

I've looked at dozens of other questions and references on the web - and by all my calculations, my setup should work, but it doesn't.
I have nginx installation with php-fpm. If I try to access a .php file, it runs correctly and I get the correct results. I got this in my config file:
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
Now, I want to setup my web app so that /somedir/file automatically executes /somdir/file.php while still displaying /somdir/file in the browser's address bar. So I modified my config to contain the following:
location / {
try_files $uri $uri/ $uri.php?query_string
}
This kind of works, that is, the server does access the .php file. Yet, instead of executing it using the existing location ~ \.php$ block above, it simply spits the php source code as the download into the browser. If I append the .php manually to the requested URL, then the php is executed.
It feels as if once the server matches try_files to $uri.php, it then does not do another pass at locations to see that what it needs to do with the php files. I tried putting the php block above and below the location /, but it makes no difference.
How can I get the php to be executed?
You want file.php to be treated as an index file, so that domain.com/dir/file.php works on domain.com/dir/ ?
Why not just rename it to index.php?
You can do this by adding this param on your location block:
index index.html file.php index.php;
If not, you might want to look into writing a rewrite rule for nginx to map domain.com/dir/ to domain.com/dir/file.php (but you have to do it for each dir that you need it to work)

How to remove a path segment from NGiNX fastcgi_script_name?

This question could also be: "How to modify an NGiNX variable with a RegEx?",
or: "Can RegEx backreference have gaps?"
Either of those would resolve the problem I'm having. Perhaps a really simple solution exists, and after digging the web for few hours, it's time to ask for help.
Here's the scenario:
There's a part of the request URI that is going to be present always (for a sort of a gimmicky domain name + URI combination :-). I enforce the presence of that always-present URI path component, which follows immediately after the domain name, like so:
http://somedomain.com/basepart/rest/of/the/path?q=123
In the above example the "/basepart" represents the always-present URI component.
So far so good. The problem arises when I want the base file path to be /var/www/somedomain.com/htdocs/ without the basepart, and php5_fpm proxy is used. I obviously set:
location /basepart {
alias /var/www/somedomain.com/htdocs;
try_files $uri $uri/ /index.php?$args;
}
But since the dynamic files are in PHP, I need to either use fastcgi_split_path_info or $request_uri to build/pass the SCRIPT_FILENAME to php5_fpm. How do I do that? How do I remove the /basepart from $fastcgi_script_name, or from $request_uri, as otherwise PHP will look for the file in /var/www/somedomain.com/htdocs/basepart?
I've considered named backreferences, or "collecting" or "fragmented" backreferences (which I don't think exist in regex) so that I could capture the segment in $fastcgi_script_name before and after the basepart when fastcgi_split_path_info assignment happens, but haven't got them to work. Dayo writes earlier at SO: »Nginx is a webserver and not a scripting application.», and suggests use of Lua for more complex scripting. But I have a feeling I may be overlooking some really simple, facepalm-worthy solution :-].
Any thoughts, anyone?
If someone else stumbles on this question, after some brainstorming i came up with stupidly obvious solution:
root /app/frontend/web/;
location /api/ {
alias /app/backend/web/;
index index.php index.html;
# Double /api/ because "that's how nginx alias and try_files works together"
try_files $uri /api//api/index.php$is_args$args;
location ~ ^/api(/.*\.php(?:\?.*)?)$ {
try_files $uri /api//api/index.php$is_args$args;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$1;
...
}
}
I.e. using regex capturing group.
With this rules requests will be routed following way:
/index.html -> /app/frontend/web/index.html
/test/test.php -> /app/frontend/web/test/test.php as plaintext
/api/<somepath> -> /app/backend/web/<somepath> (proxied to FPM if .php) if it exists, otherwise /app/backend/web/index.php
The alias directive is fine for static websites but not so useful when PHP is involved. My preferred solution is to internally rewrite the URI without the /basepart and then use root rather than alias.
The problem is that many PHP scripts use $request_uri in order to process the request, which is frozen with the /basepart intact. However, we can specify any value we choose for REQUEST_URI and construct a more appropriate value from $uri or captures. In the example below, I preserve the value of $uri after the first rewrite so that it can be used to pass our modified request URI to the PHP script.
root /var/www/somedomain.com/htdocs;
location ^~ /basepart {
rewrite ^/basepart/(.*)$ /$1 last;
rewrite ^ / last;
}
location / {
internal;
try_files $uri #index;
}
location #index {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_param REQUEST_URI $uri;
...
}
location ~ \.php$ {
internal;
try_files $uri #index;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param REQUEST_URI $uri;
...
}
The fastcgi code block is duplicated across two locations. If it becomes unwieldy, the common code can be placed into a separate include file.
Locations are made private by using the internal directive keeping the /basepart mandatory for external access.

nginx redirects 302 instead of rewrite 200

If a user requests any .php file on my webserver I want his request (e.g. he requested mysite.com/testfile.php) to be handled by index.php
In index.php I use $_SERVER['REQUEST_URI'] to see which page the user wants to see (e.g. /testfile.php), so the index.php can generate the appropriate html-code. Notice that testfile.php doesn't need to exist.
My problem is that I always get a redirect 302 to / when I try to request testfile.php (as a result $_SERVER['REQUEST_URI'] is /). But what I want is a 200 OK for testfile.php and that index.php generates the right html-code for this.
This is a snippet from my buggy nginx.conf:
server {
[...]
root /home/test;
# When I go to mysite.com redirect my to mysite.com/
location = / {
index index.php;
}
# For any php file request: let index.php handle the request
location ~ \.(php)$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME /home/test/index.php;
}
}
Anyone can help me out?
Thanks.
If the files never exist you can do this:
try_files $uri $uri/ /index.php
you can also rewrite the request like this:
location / {
rewrite ^.*$ /index.php last;
}
in both cases you should be able to read the original request with PATH_INFO or REQUEST_URI.
Have a look at these links for some more suggestions: http://drupal.org/node/110224, http://michaelshadle.com/2010/08/20/front-controller-patterns-and-nginx/, Zend Framework on nginx

Categories