mod_rewrite with multiple query strings? - apache

I'm trying to cleanup some URLs on my blog, so I've decided to look into mod_rewrite. I haven't a clue what I'm doing though, so I was hoping I could get some help :P I have links like http://kn3rdmeister.com/blog/post.php?y=2012&m=07&d=04&id=4. Although it works, and people still get the content I want them to have, I don't like them having to look at all the query strings. I want to turn the above link into http://kn3rdmeister.com/blog/2012/07/04/4.php.
This is what my .htaccess looks like right now.
RewriteEngine On
RewriteCond %{QUERY_STRING} ^y=([0-9){4})&m=([0-9]{2})&d=([0-9]{2})&id=([0-9]*)$
RewriteRule ^/blog/post\.php$ http://kn3rdmeister.com/blog/%1/%2/%3/%4.php? [L]
Like I said, I'm absolutely clueless :D

If you're using apache 2.0 or higher, you're going to need to remove the leading slash (the prefix) if these rules are in an .htaccess file, so that your regular expression looks like this:
# also note this needs to be a "]"--v
RewriteCond %{QUERY_STRING} ^y=([0-9]{4})&m=([0-9]{2})&d=([0-9]{2})&id=([0-9]*)$
RewriteRule ^blog/post\.php$ http://kn3rdmeister.com/blog/%1/%2/%3/%4.php? [L]
This is going to make it so when someone puts http://kn3rdmeister.com/blog/post.php?y=2012&m=07&d=04&id=4 in their browser's URL address bar, their browser will get redirected to http://kn3rdmeister.com/blog/2012/07/04/4.php and the new URL will appear in their address bar.
I assume you've got something setup on your server to handle a request like blog/2012/07/04/4.php.

At first you should define your URLs!!!
Like:
/blog shows front page
/blog/1234 shows post 1234
/blog/date/2012 shows posts by year
/blog/date/2012/06 shows posts by year and month
/blog/date/2012/06/01 shows posts by year and month and day
and so on...
First option is to rewrite each of your defined URLs to index.php. Your index.php has only to handle the submitted GET parameters.
### Do only if rewrite is installed
<IfModule mod_rewrite.c>
### Start rewrite and set basedir
RewriteEngine on
RewriteBase /
### Rewrite only if no file link or dir exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
### Rewrite frontpage
RewriteRule ^blog$ /index.php?action=showfront [L,QSA]
### Rewrite post
RewriteRule ^blog/([0-9]+)$ /index.php?action=showpost_by_id&id=$1 [L,QSA]
### Rewrite posts by date
RewriteRule ^blog/date/([0-9]{4})$ /index.php?action=showposts_by_date&year=$1 [L,QSA]
RewriteRule ^blog/date/([0-9]{4})/([0-9]{2})$ /index.php?action=showposts_by_date&year=$1&month=$2 [L,QSA]
RewriteRule ^blog/date/([0-9]{4})/([0-9]{2})/([0-9]{2})$ /index.php?action=showposts_by_date&year=$1&month=$2&day=$3 [L,QSA]
### Rewrite posts by tag
RewriteRule ^blog/tag/([a-zA-Z0-9_-]+)$ /index.php?action=showposts_by_tag&tag=$1 [L,QSA]
</IfModule>
Test in index.php with:
print_r($_GET);
print_r($_POST);
The second option is to rewrite all URLs and your index.php needs to handle all possible URLs. So at first it needs something like a router that splits the incoming URL in parts and then send the requested page or an error-page. I would try this at first as the bloody school.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ index.php%{REQUEST_URI} [L]
</IfModule>
Test in index.php with:
print_r(explode('/', ltrim($_SERVER['PATH_INFO'], '/')));
print_r($_GET);
print_r($_POST);
The third option is to use a PHP framework. A framework may help you to write your code quite fast. It delivers you many base-classes like a router. (f.e. ZendFramework, Flow3, Kohana, Symfony, CodeIgniter, CakePHP, yii and others). This will make you more advanced.
The fourth and laziest option is to use a ready made software like Wordpress.

Related

Using .HTACCESS Rewrite Rule

I'm trying to rewrite URLs for my dynamically generated PHP site.
I load new templates into index.php by using the following GET:
localhost/dmk/?req=signin
localhost/dmk/?req=useraccount
I want these links to appear as:
localhost/dmk/signin
localhost/dmk/useraccount
But for the life of me I cannot figure out how to do this. Everything I try either produces a 500 Internal Server Error, or has no effect at all.
I must be missing the point of RewriteRule.
You should read some documentation in this direction. I know it's a bit frustrating at first to write the rules, but it gets easier. You need to learn regular expressions to write the rules (you can start here: http://www.regular-expressions.info/)
As for the rules you need, they go like this:
RewriteEngine On
RewriteRule ^signin$ index.php?req=signin [L,QSA]
RewriteRule ^useraccount$ index.php?req=useraccount [L,QSA]
or
RewriteRule ^(signin|useraccount)$ index.php?res=$1 [L,QSA]
You can paste the rules you have used, maybe someone will explain you what you did wrong.
Try this
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d # not a dir
RewriteCond %{REQUEST_FILENAME} !-f # not a file
RewriteRule ^dmk/(.+)$ dmk/?req=$1 [NC,QSA,L]
This would redirect any URL like /dmk/page that does not conflict with an existing file or directory to /dmk/?req=page. I'm assuming your index.php is in /dmk directory.

htaccess mod_rewrite RewriteRule

I am trying to set up an .htaccess file to convert an incoming link like:
http://domain.com/root/TopNav/SubNav/SEO-friendly-file-name-p#
into this:
http://domain.com/root/index.php?t=TopNav&s=SubNav&l=SEO-friendly-file-name&p=#
where p# is the page id and TopNav/SubNav represent the navigation menu path to the file
I have been able to get it to work in all cases except for when there are arguments after the .php (it does the mod rewrite, but loses the parameters). Originally, I was hoping to have the .htaccess parse the url string so that it was ready for the script to use, but at this point I would be happy with any solution that takes the incoming url and dumps it as a string onto root/index.php.
here's what I currently have in the .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(.*)/(.*)\.php index.php?s=$1&p=$2 [L]
RewriteRule ^(.*)/ index.php?p=$1&s=$1 [L]
</IfModule>
ErrorDocument 404 /404.php
Any thoughts on what I might be doing wrong? Suggestions of a better way to get this done?
Thanks
** someone suggested changing the [L] to [L,QSA] and that seems to have worked. Thanks, whoever suggested that...
With a URU that looks like this: /TopNav/SubNav/SEO-friendly-file-name-p# you've got 4 groupings you need:
TopNav
SubNav
SEO-friendly-file-name
#
So you need to craft your regex so that it captures these 4 things in one go.
Try:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/(.+?)-p([0-9]+)$ index.php?t=$1&s=$2&l=$3&p=$4 [L,QSA]
This would go in the htaccess file in your /root directory

Mediawiki Subdirectory Installation

Possible Duplicate: MediaWiki on SubDirectory and SubDomain (However doesn't have an answer, nor any replies offering help)
Alright, I'm trying to configure MediaWiki to be installed to a sub-directory. I previously had it installed to a primary domain on http://www.example.com/ with a mod_rewrite using a Short URL of /wiki/Main_Title.
As a note, I'm also on HostGator shared hosting which has special rules for short urls.
My directory structure is as such:
/ (site root; location of .htaccess)
/wiki/ (mediawiki root; location of LocalSettings.php)
Here's what I tried,
.htaccess:
RewriteEngine on
RewriteBase /
RewriteRule ^(.*)\&(.*)$ $1\%26$2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^wiki/(.+)$ ./wiki/index.php?title=$1 [PT,L,QSA]
/wiki/LocalSettings.php:
## The URL base path to the directory containing the wiki;
## defaults for all runtime URL paths are based off of this.
## For more information on customizing the URLs please see:
## http://www.mediawiki.org/wiki/Manual:Short_URL
##
$wgScriptPath = "/wiki";
$wgScriptExtension = ".php";
$wgArticlePath = "$wgScriptPath/$1";
However, I do not get anything. I simply get a 403/Forbidden error; no 500 Internal Server Error, just a 403 - url http://www.example.com/. It's as if there's nothing being done. I've banged my head against the wall trying to figure this out. Any help is appreciated.
Thanks in advance!
What is the purpose of
RewriteRule ^(.*)\&(.*)$ $1\%26$2
You've lost me entirely on this one. Any URI with a second parameter will loop indefinitely and generate a 500 status return.
If you read the Rewrite documentation:
What is matched?
...If you wish to match against the ... query string, use a RewriteCond with the ... %{QUERY_STRING} variables
The & is normally part of the query parameter. It can appear in the RewriteRule pattern in the case of malformed URI (e.g. fred&q=1). By default, mod_rewrite will treat this as fred?q=1, but this converts it to the escaped %26 variant so this would be passed as a title fred&q=1 to MW (which is an invalid MW title by the way). I think that you should get rid of it or at least understand what you are trying to do here.
The last line should be
RewriteRule ^wiki/(.+) wiki/index.php?title=$1 [PT,L,QSA]
and keep the RewriteBase otherwise mod_rewrite can get confused.
This should work OK:-)
You're on the right track... if you're on a shared environment, then try this:
RewriteEngine on
# Comment to force base to be the subdir:
# RewriteBase /
RewriteRule ^(.*)\&(.*)$ $1\%26$2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^wiki/(.+)$ ./wiki/index.php?title=$1 [PT,L,QSA]
Two hints:
If you're not in a hosted environment (= if it's your own server and you can modify the virtual hosts, not only the .htaccess files), try to use the RewriteLog directive: it helps you to track down such problems:
# Trace:
# (!) file gets big quickly, remove in prod environments:
RewriteLog "/web/logs/mywebsite.rewrite.log"
RewriteLogLevel 9
RewriteEngine On
My favorite tool to check for regexp:
http://www.quanetic.com/Regex (don't forget to choose ereg(POSIX) instead of preg(PCRE)!)
My ticket to HostGator resolved the issue, albeit un-helpfully. I was hoping for a single .htaccess solution, rather than a double .htaccess redirect/rewrite. However, here's my solution.
/:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^.*$ http://www.example.com/wiki/
/wiki/:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?title=$1 [L,QSA]
I tried different solutions and what worked for me was changing .htaccess in mediawiki subfolder to
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wikifolder/index.php [L]
</IfModule>

URL Rewriting using .htaccess

To change the URL /mobiles.php?id=5 to /mobiles/5
The content of .htaccess file is as follows:
Options +FollowSymlinks
RewriteEngine on
RewriteRule /mobiles/$1 ^/mobiles.php?id=([0-9]+)$
But still it is showing /mobiles.php?id=5 in the address bar. Please help. Is there anything else needs to be added in the .htaccess file?
Note:
mod_rewrite module is enabled
I have restarted Apache server after making changes to the .htaccess
file
.htaccess file is in htdocs folder of Apache.
I am using Windows + PHP + Apache + MySQL
This works for me:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^mobiles/([0-9]+)$ mobiles.php?id=$1&rew [L]
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^mobiles.php$ /mobiles/%1? [R,L]
If you see this line:
RewriteRule ^mobiles/([0-9]+)$ mobiles.php?id=$1&rew [L]
I have added rew variable in the query string to prevent Apache to fall in an infinite loop
When Apache execute this line:
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
Is to make sure that url has not been rewritten for Apache
If your only concern is that the old url stays in the address bar, and you want this not to happen, try adding an [R] at the end.
RewriteRule ^/mobiles.php?id=([0-9]+)$ /mobiles/$1 [R]
Did you actually see the correct page?
By the way, the rewrite rules generally go the other way. I would be expecting to see something like:
RewriteRule ^/mobiles/([0-9]+)$ /mobiles.php?id=$1
Is your concern one of making sure a URL with query parameters does not show up in the address bar?
If I understand correctly, you want
Internally redirect /mobiles/5 to /mobiles.php?id=5
Also redirect the browser TO /mobiles/5 if a user navigates to /mobiles.php?id=5
For this you need 2 rules one to internally rewrite the URL for 1st case and 2nd for browser redirection.
You can do it like this:
RewriteEngine on
# for internal rewrite
RewriteRule ^/?mobiles/([0-9]+)/?$ /mobiles.php?id=$1 [L]
# for browser redirect
RewriteRule ^/?mobiles\.php\?id=([0-9]+)$ /mobiles/$1/ [R,L]
You are doing the opposite, should be:
RewriteRule ^/something/mobiles/([0-9]+)$ /something/mobiles.php?id=$1

Url rewriting mod_rewrite

I have the url such as:
page.com/content.php?xname=p&yname=q&zid=1
I want to rewrite this url using apache mod_rewrite into something like:
page.com/p/q/
note there should not be 'zid' parameter in renamed url. I know expressions are passed as GET into the original url.
Is it possible to rename as above. If yes, How to achieve this?
This one works fine for me and will rewrite request for /p/q/ to /content.php?xname=p&yname=q&zid=1.
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/$ content.php?xname=$1&yname=$2&zid=1 [QSA,L]
This rule is to be placed in .htaccess in website root folder. If placed elsewhere some small tweaking may be required.
It will not rewrite if requested URL is a real file or folder (I'm sure you do not want to rewrite images or some other pages -- I had to add such condition since I do not know what is your website structure is).
RewriteRule ^content\.php\?xname=(p)&yname=(q)&zid=1$ /$1/$2 [R]
Instead of p and q you can try expressions like [a-Z0-9_-]+ to match identifiers.
There's an online testing tool here: http://civilolydnad.se/projects/rewriterule/
RewriteEngine On
RewriteRule ^/[a-z0-9]+/[a-z0-9]+/$ content.php?xname=$1&yname=$2 [L]