I have the following couched in my .htaccess file:
Options -Indexes
RewriteEngine on
RewriteBase /properties/
RewriteRule ^view/([0-9]+)$ view.php?id=$1 [QSA]
I want to write a "pretty" URL like http://example.com/properties/view/1 to http://example.com/properties/view.php?id=1.
The RewriteRule is passing the request to my view.php script, but it doesn't seem to be doing the query string bit. For example, if I do print_r($_SERVER) I see the following:
Array
(
...
[DOCUMENT_ROOT] => /Users/Martin/Sites/[removed]/
...
[SCRIPT_FILENAME] => /Users/Martin/Sites/[removed]/properties/view.php
[REQUEST_METHOD] => GET
[QUERY_STRING] =>
[REQUEST_URI] => /properties/view/1
[SCRIPT_NAME] => /properties/view.php
[PATH_INFO] => /1
[PATH_TRANSLATED] => /Users/Martin/Sites/[removed]/1
[PHP_SELF] => /properties/view.php/1
...
)
Why is QUERY_STRING empty? And why can't I access "1" with $_GET['id']?
Note: Obviously I've placed the [removed] tokens in the file paths.
It doesn't look to me like your rewrite rule is working. Otherwise I think the following values would be converted:
[REQUEST_URI] => /properties/view/1
[PHP_SELF] => /properties/view.php/1
If the rewrite rule were working, your php script would see the rewritten URI.
Some ideas...
What is your RewriteCond? Is that matching?
I have never tried matching the partial path without trying to at least use a .* to match from the beginning. What if you tried one of the following?
RewriteRule ^/?properties/view/([0-9]+)$ /properties/view.php?id=$1 [NC,L]
RewriteRule ^.*/view/([0-9]+)$ /properties/view.php?id=$1 [NC,L]
You are only rewriting urls that start with view using:
^view/([0-9]+)$
because the ^ means anchored to the start.
You could change it to for example:
^properties/view/([0-9]+)$
Related
I use in my .htaccess
RewriteRule ^profiles/([A-Za-z0-9-]+)/$ /profile.php?city=$1 [NC]
Works normally when accessing the url:
https://site.com.br/profiles/londres
But in the page, after insert an variable get, the php recognizes only the variable configured in htaccess, example when accessing the url:
https://site.com.br/profiles/londres?s=username
print_r($_GET);
return
Array ( [city] => londres)
that is, it does not return the variable s in GET
Use QSA flag in your rule to get query string as well.
RewriteRule ^profiles/([A-Za-z0-9-]+)/$ /profile.php?city=$1 [NC,QSA]
Reference:
https://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_qsa
For my own MVC I need to read the request URI from the global variables ($_GET or $_SERVER).
First I thought to read it from $_GET array. But then I discovered that it's contained in the $_SERVER array as well.
So, I would like to ask, from which global array should the request URI be read?
An example:
The URI could have the following structure:
http://local.mvc/PsrTest/testRequest/123?var=someval
with:
PsrTest as controller name;
testRequest as action name;
123 as argument for the controller action;
var=someval as some query string key/value pair;
By applying a RewriteRule in ".htaccess", it will be translated to:
http://local.mvc/index.php?url=PsrTest/testRequest/123&var=someval
and it will be saved in the following items of the $_GET and $_SERVER arrays:
------------
$_GET array:
------------
'url' => 'PsrTest/testRequest/123'
'var' => 'someval'
---------------
$_SERVER array:
---------------
'HTTP_REFERER' => 'http://local.mvc/PsrTest/testRequest/123?var=someval'
'REDIRECT_QUERY_STRING' => 'url=PsrTest%2ftestRequest%2f123&var=someval'
'REDIRECT_URL' => '/PsrTest/testRequest/123'
'QUERY_STRING' => 'url=PsrTest%2ftestRequest%2f123&var=someval'
'REQUEST_URI' => '/PsrTest/testRequest/123?var=someval'
Thank you for your time!
But if you want to use .htaccess this is a start.
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
# One param
RewriteRule ^/?([^/]*)$ index.php?section=$1 [NC,L]
# Two params
# IE: search/12345
RewriteRule ^edituser/([a-zA-Z0-9]+)/?$ index.php?section=edituser&id=$1 [NC,L]
# Three params
# IE: search/12345/676767
RewriteRule ^editcontact/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/?$ index.php?section=editcontact&contactID=$1&reservationID=$2 [NC,L]
This is a small example from an older program I wrote.
As #teresko suggested, .htaccess are not always a possibility. Then it makes indeed no more sense (at least for me) to write RewriteRules in .htaccess, which translate the given URI into query string parameters. It will be sufficient to:
Just write a simple rule, like RewriteRule ^ index.php [L] in .htaccess;
Just parse the $_SERVER['REQUEST_URI'] value in PHP, in order to get the URI components needed to call a controller action and to pass the corresponding parameters to it.
I'm grateful to all the users who helped me finding my answer. Thanks!
So, my directory structure is something like this;
index.php
location / {
rewrite ^(.*)$ /index.php?params=$1 last;
}
public/assets/
location /public/assets {
rewrite ^(.*)$ /public/assets/index.php?params=$1 last;
}
So, I do need 2 rewrites for this project, one for everything expect assets and one for assets. But problem comes when using Nginx. When using Nginx to rewrite public/assets PHP $_GET params are following:
Array
(
[params] => /public/assets/css/syles.css
)
Array
(
[0] =>
[1] => public
[2] => assets
[3] => css
[4] => syles.css
)
And these are wrong. I do not want url to passed to GET. Because when using Apache I do get following result. When using Apache, code is working as it should.
Array
(
[params] => css/styles.css
)
Array
(
[0] => css
[1] => styles.css
)
So, how do I can remove these "extra" parameters from url with Nginx config? Or Do I need to use PHP to remove this extra parameters if webserver is Nginx? I do not want that solution to be even proposed as solution.
So, I want get same parameters with Nginx what I do get with Aoache to be clean.
FYI when using Apache I have following .htaccess placed under public/assets.
RewriteEngine on
RewriteCond %{REQUEST_URI} !/index.php
RewriteRule ^(.*)$ index.php/?params=$1 [NC] #L
The path before rewriting contains /public/assets/, so the easiest way to exclude it from what is passed to params is to hardcode it in the regexp and only extract what you want, using something like:
location /public/assets {
rewrite ^/public/assets/(.*)$ /public/assets/index.php?params=$1 last;
}
what i'm trying to accomplish is to make my urls compatible with all kinds of extra arguments.
it must be able to work with n number of slashes.so my htaccess gets everything after 127.0.0.1/store/ and sends it redirect.php as id.
as in
http://127.0.0.1/store/category/cars/show/1/page/2
or
http://127.0.0.1/store/category/cars/color/red/price/min/100
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.domain\.com$
RewriteRule ^(.*)$ http://127.0.0.1/store$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ redirect.php?id=$1 [QSA,L]
in my redirect.php i explode slashes to get the script name and its parameters
if($_GET['id']){
$param = explode('/', $_GET['id']);
$template = $param[0];
// header redirect -> go to category.php
}
this gives me
Array
(
[0] => category
[1] => electronics-computers
[2] => show
[3] => 1
[4] => page
[5] => 2
)
so far so good, then i try to redirect to the file which is category.php in this example with parameters but since the htaccess controls the traffic, it becomes infinite redirection
i thought i should add some exception to htaccess to not to interfere requests coming from redirect.php but i couldnt make it work
ps: if there is a better way of doing this please let me know
then i try to redirect to the file which is category.php in this example
Well, that's the thing, you shouldn't be redirecting that this stage. Redirecting involves sending a redirect response back to the client and the client then makes a second/new request back to the server (which results in your redirect loop).
if there is a better way of doing this please let me know
You need to route the request. Since you know that the required file is contact.php (in this example), then read this file server-side, passing all the necessary parameters and send this in the same response back to the client.
I would like to make a rewrite rule to redirect to what the user has typed right after the main url, so no folder (like www.site.com/user1), I think that would mean to access $0 which doesn't work...
The rule I'm trying to use is:
RewriteRule ^([0-9a-zA-Z]+) show-user.php?user=$0
But it does not work...
Any ideas?
Ok, new file and it's still wrong...
Full .htaccess file:
DirectoryIndex index.php
RewriteEngine on
RewriteRule ^([0-9a-zA-Z]+) test.php?var1=$1 [L]
full test.php file:
<?php
print_r($_GET);
?>
Ouput for domain/user1
Array ( [var1] => test )
It makes no sense :(
How can I make sure in php var1 will be user1 (as it should be) in the example above? I think the rewrite rule is wrong somehow...
The parameters are not 0-indexed
RewriteRule ^([0-9a-zA-Z]+) show-user.php?user=$1