Removing file extension with Rewrite in .htaccess - apache

I am currently trying to do some url rewriting. I have made some progress but I can't seem to get this to remove the file extension.
The url it outputs current looks like:
article-install-apache-on-linux.php
I would like it to look like:
article-install-apache-on-linux/
RewriteEngine on
RewriteRule ^article-(.*).php$ ./article_show_friendly.php?url=$1

Just remove the .php from the first part and add an optional slash /?. Also, change (.*) to (.+) to ensure 1 or more characters.
RewriteRule ^article-(.+)/?$ /article_show_friendly.php?url=$1 [L]
Also added the L flag on the end to ensure rewriting stops at that point.

Related

Windows 10 Xampp Apache - htaccess rewriterule not working

I am using apache XAMPP on Windows 10 and am trying to get htaccess working. I have this so far...
RewriteEngine On
RewriteRule ^noexist/?$ /folder/
I want someone to go to
www.mysite.com/noexist/test.php -> www.mysite.com/folder/test.php
But I still want the URL to be www.mysite.com/noexist/test.php
I am just getting a 404, where am I going wrong? I have confirmed the htaccess file is being loaded by putting invalid code in and it throws an error so I am certain the file is being used.
RewriteRule ^noexist/?$ /folder/
The regex ^noexist/?$ matches noexist or noexist/ only, so /noexist/test.php is ignored by this rule. It also only rewrites to /folder/ only.
In other words, this rewrites /noexist (or /noexist/) to /folder/ only.
To rewrite /noexist/<something> to /folder/<something> then you need to capture the <something> part and pass this through to the target URL (i.e the substitution string). For example:
RewriteRule ^noexist/(.*) /folder/$1 [L]
The $1 backreference in the substitution string contains the URL-path captured by the parenthesised subpattern (ie. (.*)) in the RewriteRule pattern.
Don't forget the L (last) flag. (This is important if you have other directives later in the file.)
Note that this rewrite is unconditional, regardless of whether /folder/<something> exists or not. If you want to check that /folder/<something> exists before rewriting then add an additional condition. For example:
RewriteCond %{DOCUMENT_ROOT}/folder/$1 -f
RewriteRule ^noexist/(.*) /folder/$1 [L]
This assumes your .htaccess file is located in the document root.

Rewrite pages with a certain url to another htaccess

What I need to do it rewrite a url from one thing to another eg:
http://www.domain.com/page_one/blah //to
http://www.domain.com/page_two/blah
I've tried a few script I've found around the internet but I'm terrible with .htaccess and can never understand or get it right.
If you want to change only this specific url, use this:
RewriteEngine On
RewriteRule ^page_one/blah?$ http://www.domain.com/page_two/bla [L]
If you want to change the url for every file into the "page_one"-folder, this will help you:
RewriteEngine On
RewriteRule ^page_one/([^/]+)$ http://www.domain.com/page_two/$1 [L]
The RewriteEngine On activates the RewriteEnigine, so that you are able to use RewriteRules.
The ([^/]+) in the second solution means "every file, but no folders (the slash is excluded)". This is stored in $1 and used to create the new url.
Edit
[L] stops the script from using the other rules (if you have some)

.htaccess mod_rewrite linking to wrong page

I have in my .htaccess the following code:
RewriteEngine On
RewriteRule ^/?([^/\.]+)/?$ $1.php [L]
RewriteRule ^/?([^/\.]+).php$ $1/ [R,L]
RewriteRule ^/?([^/\.]+)/?$ $1.php [L] is working fine. What this is doing is taking a url like http://www.example.com/whatever and making it read the page as http://www.example.com/whatever.php.
However, what I'd like to be able to do is take a url like http://www.example.com/whatever.php and automatically send it to http://www.example.com/whatever, hence the second line of the code. However, this isn't working. What its doing now, is as soon as it comes across a link ending in .php, the url becomes http://localhost/C:/Sites/page/whatever/, and pulling a 403: Forbidden page.
All I want to know is what I can to so that http://www.example.com/whatever.php will be read as http://www.example.com/whatever, and that if http://www.example.com/whatever.php is entered into the URL bar, it will automatically redirect to http://www.example.com/whatever.
Does that make any sense?
EDIT
Ok, so it appears I wasn't all too clear.. basically, I want /whatever/ to read as whatever.php while the URL still stays as /whatever/, right? However, if the URL was /whatever.php, I want it to actually redirect the users URL to /whatever/, and then once again read it as whatever.php. Is this possible?
If you're rules are inside an .htaccess file, you can omit the leading slash when you match against a URI:
RewriteRule ^([^/\.]+)/?$ /$1.php [L]
Also note that a leading slash is included in the target (/$1.php), this makes sure /whatever/ gets rewritten to /whatever.php. When you redirect, if you are missing this leading slash, apache prepends the document root to it. Thus /whatever.php gets redirected to the document root C:/Sites/page/whatever/. Even if you include the leading slash, this will never work because you're going to cause a redirect loop:
Enter "http://www.example.com/whatever.php" in your address bar
apache redirects you to "http://www.example.com/whatever/"
apache gets the URI whatever/ and applies the first rule and the URI gets rewritten to /whatever.php
The URI gets put through the rewrite engine again
the URI /whatever.php matches the second rule and redirects the browser to "http://www.example.com/whatever/"
repeat steps 3-5
You need to add a condition that the actual request is for /whatever.php:
RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /([^/\.]+)\.php
RewriteRule ^ /%2/ [R,L]
So altogether, you'll have:
RewriteEngine On
RewriteRule ^([^/\.]+)/?$ /$1.php [L]
RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /([^/\.]+)\.php
RewriteRule ^ /%2/ [R,L]
You're making a relative path substitution in a per-directory context (.htaccess is a per-directory context). This requires RewriteBase. Per-directory rewrites are done in a later stage of processing, when URLs have been mapped to paths. But the rewrite must produce a URL, which is processed again. I think without the RewriteBase to supply the URL prefix, you end up with a filesystem prefix instead of the URL. That may be why you're getting the C:/Sites thing. Try RewriteBase. But after a correct RewriteBase to specify the correct URL prefix to be tacked in front to the relative rewritten part, I'm afraid you will have the rewrite loop, because you're rewriting whatever.php to whatever; and whatever to whatever.php.
Reference: http://httpd.apache.org/docs/current/rewrite/tech.html

htaccess rewrite drive me nuts

I want to use a rather simple rewrite, something like this:
RewriteRule monitor.html index.php/\?first_category_id=B008 [NC,L]
But it doesn't work as expected, goes to like index.php/monitor.html (which kicks in symfony's routing and returns a 404 error but this is a different story)
However if i include full url like:
RewriteRule monitor.html http://example.com/index.php/\?first_category_id=B008 [NC,L]
it responses the correct content, but this looks like a full redirect, the rewrited url is revealed in the browser. And thats not transparent nor easily deployable.
What am i missing here?
the rest of the htaccess file if it matters:
RewriteCond %{REQUEST_URI} \..+$
RewriteRule .* - [L]
RewriteRule ^(.*)$ index.php [QSA,L]
Your rule is outputting a relative path and you're in a per-directory context. You need RewriteBase. In a per-directory context, rewriting is being done on expanded filesystem paths, not on the original URL's. But the results of the expansion are converted to a URL again! RewriteBase supplies the prefix needed to do that. Without it, the URL is naively made out of the same filesystem prefix that was stripped prior to the substitution and you end up with for instance http://example.com/var/www/docroot/blah... which is nonsense. Either RewriteBase or put out an absolute, beginning with a slash.
Also, you should anchor the match:
RewriteRule ^monitor.html$ ...
Otherwise the rule will potentially match somewhere in the middle of the path and just that matching part will be replaced with the substitution! You don't want to match and translate amonitor.htmly/foobar, right, and convert just the monitor.html part to a the index.php stuff.
You should not escape the question mark in the substitution. It's not a regexp! Just index.php/?etc not index.php/\?etc (Could that backslash be what is screwing up, causing `index.php/monitor.html'?)

apache rewrite url for codeigniter

I need to build app and i'm using codeigniter for this.
Company sends me a link in format that cant be changed from their side
Link is like:
someurl.com/sms.php?phone=12345678&msg=msg15&code=777&country=cc&oper=someoper& mssid=1234567892&notcharged=0&date=2011-12-26+23%3A31%3A27&keyword=msg&created=2011-12-26+23%3A31%3A26
How can i rewrite it with .htaccess so the codeigniter gets link in segmented format like
someurl.com/sms/myfunction/12345678/msg15/777/cc/someoper/1234567892/0/2011-12-26+23%3A31%3A27/msg/2011-12-26+23%3A31%3A26
Thanks
Edit.
Spent some hours and tried something like this:
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^phone\=([^&]+)\&msg\=([^&]+)\&code\=([^&]+)\&country\=([^&]+)\&oper\=([^&]+)\&mssid\=([^&]+)\&date\=([^&]+)\&keyword\=([^&]+)$
RewriteRule ^test\.php$ /sms/doParse/%1/%2/%3/%4/%5/%6/%7/%8 [R,L]
And then typing url like this:
http://test.airtel.lv/test.php?phone=12345678&msg=msg15&code=777&country=cc&oper=someoper&mssid=1234567892&date=2011-12-26+23%3A31%3A27&keyword=msg
I got this:
http://test.airtel.lv/sms/doParse/12345678/msg15/777/cc/someoper/1234567892/2011-12-26+23%253A31%253A27/msg?phone=12345678&msg=msg15&code=777&country=cc&oper=someoper&mssid=1234567892&date=2011-12-26+23%253A31%253A27&keyword=msg
Why returned url has GET params in the ending ?
And one more question, if that company will change and add extra param to link, the rewriting will be broken ? Then how can it be more universal ?
Try this placing this in your .htaccess file in an appropriate place in your document root:
RewriteEngine on
RewriteRule ^sms.php$ /sms/myfunction/ [L]
RewriteCond %{QUERY_STRING} ^[^=]+=([^&]+)&?(.*)
RewriteRule ^sms/myfunction/(.*)$ /sms/myfunction/$1/%1?%2 [L]
The first RewriteRule changes the /sms.php part of the URI to /sms/myfunction/ and the second rule will append each value in your query string into its own part of the path. So a url like this: http://someurl/sms.php?a=1&b=2&c=3&d=4&e=5&f=6&g=7&h=8&i=9 will have the URI internally rewritten to /sms/myfunction/1/2/3/4/5/6/7/8/9. There's no checks on what the variable names are in the query string, only the value is extracted and appended to the URI path.
If you put that code in your server or vhost config (instead of an htaccess file) add a / in front of the sms in each of the rules so it says ^/sms because rules in the htaccess have the leading slash stripped off when matching against the URI.
just handle the GETs in your controller. it's okay, GET isnt evil.
parse_str($_SERVER['QUERY_STRING'], $_GET);
then you can have a simpler rewrite to handle the special route