Mod Rewrite syntax: path to GET - apache

I'm having a bit of trouble with the mod_rewrite syntax for Apache. Here's what I need:
The path
"www.example.com/public/path/to/file.txt"
needs to become:
www.example.com/public/?p=path%2Fto%2Ffile.txt
That is, everything after "public/" should be URL encoded and added as GET parameter "p". Any simple code snippets to do this?

Put these rules in the htaccess file in the public folder:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /?p=$1 [L,B]
The important thing here is the B flag which makes sure the /'s get encoded into %2F. Though, I'm not sure whether you really need it.

Related

Apache mod_rewrite path to query string for specific path format

I've been working on this for weeks. I want to be able to use a friendly URL to pass variables to a PHP script. For example, if someone uses this URL:
https://example.com/foo/bar/who
I would like my PHP script to receive this:
https://example.com/index.php/?var1=foo&var2=bar&var3=who
The catch is that I ONLY want to do this rewrite when there are three vars in the path. If there are fewer or more than three, I do not want to rewrite the URL.
I've seen several other explanations related to this type of rewrite but nothing quite like this.
This is almost working, but not quite. I only want the rewrite done if there's something present for those first three variables. I know this is incomplete, but with this method at least the REQUEST_URI contains the values I can parse. But again, I only want to do this when there are three vars in the path.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !^index\.php/([^/]*)/([^/]*)/([^/]*)$ index.php [L]
Thank you.
You were pretty close, have it this way. Please make sure you clear your browser cache before testing your URLs. You had already created back references only thing you needed to use them, which I have added those now.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ index.php?var1=$1&var2=$2&var3=$3 [L]

mod_rewrite - Removing index.php from URL (in subfolder)

I'm trying to get an API working (locally, for now), which lives in a subfolder. I've been trying every example I can find, but all are ending up in 404 errors.
I have this URL:
http://127.0.0.1/~owner/personal/api/v1/index.php/tasks
I want to be able to use this:
http://127.0.0.1/~owner/personal/api/v1/tasks
Eventually, it will become this:
http://api.mydomain.com/tasks
I just can't seem to get my .htaccess rules setup correctly. This keeps getting suggested, but does nothing:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
What am I missing?
Update
I have setup my virtual hosts to use http://api.local/ instead of the previously used addresses.
Accessing http://api.local/index.php/tasks works.
Accessing http://api.local/tasks does not.
Maybe part of your problem is your development environment. You are using a local server to do this on with several subfolders deep and I think it's messing with your .htaccess depending on the location.
If your .htaccess is in the root of your website http://127.0.0.1/.htaccess then it's not going to work properly.
Make sure it's in the same directory as your index.php file and make sure /~owner/personal/api/v1/ is your document root for your dev environment as specified in your apache config file.
Then you can test out your htaccess rules and see how they work. Your current rule should be ok providing /tasks won't be a real directory in the root.
On another note,
I always suggest using your real domain name so you could see how it works as if it were in production. You can do that by modifying your HOST file on your PC and the site will only available to you and you can access via yoursite.com. This quick easy guide will show you.
Try specifying the rewrite base.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
You are using the parameters of RewriteRule backwards. You need this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*?)/index.php(.+)?$ /$1$2
This means:
if it's not a file
and it's not a directory
and it looks like / (optional), possibly some more characters, then /index.php, then possibly some more characters, go to the URL without the /index.php part.
Note that I deleted the [L] for now -- it means "if the URL matches this rule, don't apply any more rules." You say you want to keep transforming it into http://api.mydomain.com/tasks, so you shouldn't use [L].

Help with dynamic RewriteRule in .htaccess

I would like to use RewriteRules in .htaccess to achieve particular url rewriting, but can't get it right, can somoene help?
I'm trying to rewrite the path (everything between the first and last /) into one query string, and the filename into another
e.g:
http://domain.com/users/admins/testuser.html
rewrites to
http://domain.com/index.php?path=users/admins&file=testuser
and
http://domain.com/home.html
rewrites to
http://domain.com/index.php?path=&file=home
and
http://domain.com/settings/account.html
rewrites to
http://domain.com/index.php?path=settings&file=account
EDIT:
Many thanks to the first two answerers, they are both good answers however I can't figure which one to use!
Is there any benefit to parsing the path from php itself, or vice-versa?
Try this rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^((.+)/)?([^/]+)\.[^/.]+$ index.php?path=$2&file=$3
But it may be easier to use PHP’s parse_url and pathinfo for that:
$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$pathinfo = pathinfo(substr($_SERVER['REQUEST_URI_PATH'], 1));
var_dump($pathinfo);
Now you just need this rule to rewrite the request to the index.php:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^index.php$ index.php
Try this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^((\w+/)*)(\w+)\.html$ index.php?path=$1&file=$3

.htaccess rewrite rule to add a string in the middle of the URL

Using a .htaccess rewrite rule, I need to add "?q=" before the path on any URL's containing the word "imagecache"
Therefore, if the URL is:
http://mysite.com/sites/default/files/imagecache/myimage.jpg
...then it will really try:
http://mysite.com/?q=sites/default/files/imagecache/myimage.jpg
But that will ONLY happen if the URL contains "imagecache." Otherwise, it does no rewriting.
Also, this will only happen if /sites/default/files/imagecache/myimage.jpg isn't already an existing image file. I believe I can do that using:
RewriteCond %{REQUEST_FILENAME} !-f
...right? It's just the first part that I can't figure out.
Something like this?:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*imagecache.*)$ /?q=$1 [L,QSA]
RewriteRule ^mysite.com/(.*)/imagecache/(.*)$ mysite.com/?q=$1/imagecache/$2

Apache Rewrite Issue, Custom URI

I have a solution but it is one that I know is not the greatest and would better be solved with a full rewrite. Basically I have 3 rewrites that will go to the correct areas I want and do what they need to do. However in order to switch between where I need to go I had to write a URI class to strip through the url set the page and vars manually. It all works out great but the urls are a pain in the ass specially if not formatted exactly.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/bsiadmin/$ /bsiadmin/index.php [L,QSA]
RewriteRule ^/bsiadmin/(.+)/$ /bsiadmin/index.php?page=$1 [L,QSA]
RewriteRule ^/(.+)/$ /index.php?page=$1 [QSA]
So the first rule will make sure to direct everything to the directory and not the root index.php, the second rule does the same if there is a "page" specified. The last rule will take anything else and make sure it uses the root index.php and goes from there.
Example of urls:
http://mysite.test/icecream/id=2/
My custom uri class would strip this clean and set id as a $_REQUEST var.
I guess what I really want to know is how can I just rewrite a simple url such as:
http://mysite.test?page=icecream&id=2
AS
http://mysite.test/icecream/id/2/
Without any limitation on how many vars can be passed and the directory that does exist "bsiadmin" to display without me having to use a uri class to direct it.
Thanks for the help.
You can use mod_rewrite to do so:
RewriteRule ^/([^/]+)/([^/]+)/([^/]+)/(.*) /$1/$4?$2=$3 [N,QSA]
RewriteRule ^/([^/]+)/$ /bsiadmin/index.php?page=$1 [L,QSA]
But I think the best would be to use PHP for that job. Because with mod_rewrite you can only rewrite a fixed amount of URL arguments at a time (here one with every rewrite). With PHP you can parse any arbitrary number of arguments like this:
$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$segments = explode('/', $_SERVER['REQUEST_URI_PATH']);
if (count($segments) > 2) {
for ($i=4, $n=count($segments); $i<$n; $i+=2) {
$_GET[rawurledecode($segments[$i-1])] = rawurldecode($segments[$i]);
}
$_GET['page'] = rawurldecode($segments[1]);
}
Then all you need for mod_rewrite is this single rule to rewrite the requests to your index.php:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !^/bsiadmin/index\.php$ /bsiadmin/index.php [L]