Rewrite all params requests to index.php with Nginx - nginx

i've URL like this
http://www.example.com/index.php?page=profile&id=324&opt=edit&cat=23&...
I wish I had
http://www.example.com/profile/324/edit/23...
I read several tutorials on how to remove php extension but do not know how to pass other parameters
Thanks to everyone
UPDATE
Sovled with PHP solution.
nginx:
location / {
try_files $uri $uri/ /index.php;
}
PHP:
$params = explode("/",$_SERVER['REQUEST_URI']);
and use them

Actually it's pretty easy if those params are always in the same order as your example.
Add a rewrite rule in your nginx config.
rewrite ^/index.php?page=(.*)&id=(.*)&opt=(.*)&cat=(.*)(&.*)$ /$1/$2/$3/$4
But if the order of params changes in every request, we may need another solution.
UPDATE
nginx stores request args in variables like $arg_name, the name after $arg_ if the actual request param name. So you just need to rewrite requests to index.php with a tailing question mark to url style you want.
rewrite ^/index.php? /$arg_page/$arg_id/$arg_opt/$arg_cat;

Related

Nginx remove special character

My URL is: https://example.com/data=123456
I added the following line of code to the index.php file: var_dump($_GET['data']);
But this only works if I add a ? character to the URL.
(example: https://example.com/?data=123456)
This is in the root of index.php.
I tried to add this to the nginx.conf file:
location / {
try_files $uri $uri/ /index.php$is_args$args;
rewrite ^(.*)\?(.*)$ $1$2 last;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
rewrite ^(.*)\?(.*)$ $1$2 last;
include fastcgi.conf;
}
But not working. How to remove the "?" character from URL?
When your URL is https://example.com/data=123456, the data=123456 is a part of URL path. When your URL is https://example.com/?data=123456, the data=123456 is a query part of the URL, where query argument data has a value if 123456. Check at least the Wikipedia article.
Next, only query arguments can be accesses via $_GET array. Full request URI (including both path and query parts) is available via $_SERVER['REQUEST_URI']. You can analyze that variable in your PHP script and skip the rewrite part completely.
If you want to rewrite your URI and made that data to be accessible via $_GET['data'] variable, it is also possible. However your main mistake is that the rewrite directive works only with (normalized) path of the given URL and not the query part of it. Nevertheless it can be used to append (or replace) query arguments. To do it you can use
rewrite ^(.*/)(data=[^/]*)$ $1?$2;
(to rewrite only data parameter) or more generic
rewrite ^(.*/)([^/=]+=[^/]*)$ $1?$2;
(to count on every param=value form of the URL path suffix). You can place this rewrite rule at the server configuration level.

Nginx rewrite local file path

Is it possible to make this kind of url rewrite?
Request url:
https://image.domain.com/listing/1_10_iP2LROSEafC01584630756.jpg
Rewrite to:
https://image.domain.com/images/i/P/2/L/iP2LROSEafC01584630756.jpg
If /images/i/P/2/L/iP2LROSEafC01584630756.jpg exists in server, it's served, if not then query is redirected to php file /make_image.php
Thank you!
Request url: https://image.domain.com/listing/1_10_iP2LROSEafC01584630756.jpg Rewrite to: https://image.domain.com/images/i/P/2/L/iP2LROSEafC01584630756.jpg
If you mean an external redirect, then this is achieved using the rewrite directive. Place the statement in the server block, or within a location block that handles these kinds of request (i.e. URIs beginning with /listing/ and/or ending with .jpg).
Your question does not state what 1_10_ means, but let's assume that you want the two arbitrary numbers ignored.
For example:
rewrite ^/listing/\d+_\d+_(.)(.)(.)(.)(.*)$ /images/$1/$2/$3/$4/$5 permanent;
See this document for details.
If /images/i/P/2/L/iP2LROSEafC01584630756.jpg exists in server, it's served, if not then query is redirected to php file /make_image.php
This is achieved using a try_files statement within a location block that processes requests for URIs beginning with /images/.
For example:
location /images/ {
try_files $uri /make_image.php;
}
See this document for details.

Nginx URL routing

I think this is kind of basic stuff, but I'm struggling to find proper guide that would explain these things:
I have a index.php file and nginx config so that https://dev.something.com works ok.
But I need to change nginx config so that that address produces blank page, and index.php only works from https://dev.something.com/lists. I could put index.php inside lists directory, but isn't there more subtle solution?
And here's the hard part:
Users should be able to access
https://dev.something.com/lists/userName
https://dev.something.com/lists/userName/listName
userName and listName should be used as GET-parameters.
Can anyone help how I could achieve this kind of config with nginx?
You're asking a few (relatively basic) questions, and I would suggest you start with their free e-book https://www.nginx.com/blog/announcing-oreillys-new-book-nginx-a-practical-guide-to-high-performance/
You can define where nginx looks for index files with the root clause, and though they normally use the URL context relative to the server's root, it can be override in each location.
http://nginx.org/en/docs/http/ngx_http_core_module.html#root
You can use portions of URLs as variables, which can be passed as paramters too.
location = /lists { # '=' will match exactly, no trailing url
root /path/where/index.php/lives;
try_files $uri /index.php;
}
location /lists { # this will match anything under that url
rewrite ^/lists/(\d+)/?$ /lists?user=$1; # matches username
rewrite ^/lists/(\d+)/(\d+)/?$ /lists?user=$1&list=$2; # matches username/list
}
location /{ #everything else
root /path/where/index.html/lives; #index.html is empty file.
try_files $uri /index.html;
}

double try_files directive for the same location in nginx

I discovered a nginx config snippet in serveral gists and config examples (mostly for PHP apps):
#site root is redirected to the app boot script
location = / {
try_files #site #site;
}
#all other locations try other files first and go to our front controller if none of them exists
location / {
try_files $uri $uri/ #site;
}
But I just do not get it: Does the first try_files directive ever match? To me this looks like some nonsense hacking.
Please confirm or explain why not - thanks :)
This is what happens here:
The first location = / is only used when the path in the request is /, e.g. http://example.com/. The second location /is used for all other URLs, e.g. http://example.com/foo or http://example.com/bar.
The reason for the first location is to avoid any interference from index-directives that do a redirect to index.html or something similar.
Inside the first location the try_files-directive first looks for a file named #site, which does not exist and then redirects to the named location #site. The reason for this construct is that the redirect to the named location is purely internal, i.e. the #site location can not be accessed directly from the client and the $uri is kept unmodified during this redirect (which would not be the case for other redirects). The first parameter #site can be anything except a real existing file. I prefer to call it DUMMY for clarity.
The second location tries static files first and, if not found, then also redirects to the named location.

Canonical URLs with Nginx

We're working on removing the directory index files from our URLs to clean things up and provide more consistency to improve our SEO.
However, I'm not familiar with how to take care of this in Nginx.
I found the following for Apache (we're just looking for the Nginx equivalent)
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+/)*index\.php\ HTTP/
RewriteRule ^(([^/]+/)*)index\.php$ http://www.%{HTTP_HOST}/ [R=301,NS,L]
I've read the docs and tried several different options - the closest I can get will still return an infinite loop error.
The snippet you posted for Apache uses the immutable global variable %{THE_REQUEST} to determine the original URI requested by the client. However, this variable contains the entire request, including the HTTP method, version, and query string. Therefore, parsing this variable is a bit messy, as seen in the example you posted.
However, nginx has a dedicated variable that holds the original request URI received from the client: $request_uri. This allows you to do the following:
## REDIRECT foo/index(.html) to foo/
if ($request_uri ~ ^(.*/)index(?:\.html)?$) {
return 301 $1;
}
If you wanted to also strip the file suffix, e.g. .html, you could use the following snippet:
## REDIRECT foo/bar.html to foo/bar
if ($request_uri ~ ^(.+)\.html$) {
return 301 $1;
}
Now, in order for nginx to still be able to serve the correct file, one uses the try_files directive, which checks all given URIs in sequence until one matches:
## Rewrite internal requests for foo/bar to foo/bar.html
try_files $uri $uri.html =404;
So a request for /foo/bar would be handled as follows:
return $uri = /foo/bar, if that file exists in the document
root, otherwise
return $uri.html = /foo/bar.html if it exists, finally
issue a 404 error.

Resources