Clean URL with htaccess and PHP - php

I've done the due diligence, spending hours poring through searches and stack QA. No dice. So I finally come here to request help.
Apache HTTP Server
PHP 5.3
I have dirty urls:
.cc/store/index.php?route=checkout/cart
.cc/store/index.php?route=common/home
.cc/store/index.php?route=product/product&product_id=111
I'd like to clean them so when a user clicks on a dirty link or types a dirty url they get a clean url in the address bar:
.cc/store/cart
.cc/store/home
.cc/store/product/11
Currently I have my htaccess file in:
.cc/store/.htaccess
I know I need in htaccess:
RewriteEngine On
But is this the right path?:
RewriteRule !/index.php?route=(A-Z)/(A-Z)&(*)$ /$2/$3
Q1: Do I need to just edit the htaccess file or will I also have to write some php?
Q2: What htaccess / php code do I write to get the desired clean urls? I want to see clean urls in the address bar of my browser.
Thanks in advance.

Whatever is generating those URLs, be it PHP or simple HTML, will need to be updated to contain the new URLs. mod_rewrite simply takes the "Clean" url and translates it into the original "dirty" one so your original code can still function, with the same parameters.

This:
RewriteRule !/index.php?route=(A-Z)/(A-Z)&(*)$ /$2/$3
Isn't what you want. You're going to need 2 types of rules, ones that externally redirect the browser to the URL that you want to see, then ones that internally rewrite to the URL that your system can understand (the "dirty" ones). So something like:
RewriteEngine On
RewriteBase /store/
RewriteCond %{THE_REQUEST} \ /+store/index\.php\?route=checkout/cart
RewriteRule ^ /store/cart? [L,R]
RewriteCond %{THE_REQUEST} \ /+store/index\.php\?route=common/home
RewriteRule ^ /store/home? [L,R]
RewriteCond %{THE_REQUEST} \ /+store/index\.php\?route=product/product&product_id=([^&\ ]+)
RewriteRule ^ /store/product/%1? [L,R]
RewriteRule ^cart$ index.php?route=checkout/cart [L,QSA]
RewriteRule ^home$ index.php?route=common/home [L,QSA]
RewriteRule ^product/(.+)$ index.php?route=product/product&product_id=$1 [L,QSA]
You can't make it "wildcard" like matching because you're changing something like "X/Y" to just "Y", which means when you internally rewrite it back, the "X" part is lost forever.

Related

CMS Pages in Database .htaccess configuration

In my CMS I store all pages in a database. If you request a page currently it works like this:
Requested URI: www.xyz.com/site.html
.htaccess: mod_rewrite creates: /index.php?q=site
index.php: Looks up in Database for the entry site.
To clean up the URLs I like to have URLS like this: www.xyt.com/about/site.html or www.xyt.com/about/groups/groups.html
In my Database is an entry for every Page called owner which represents the Parent Site.
The Problem for me is that the number of 'folders' is not fixed.
So i thought I should Change www.xyt.com/about/site.php to /index.php?q=about-site in the .htaccess and than write a PHP function which finds the site site with the Parent about
What would be the RewriteRule?
I that a good way or is there an other (better) way?
Changing the foo/bar/about/site/etc.html to index.php?q=foo-bar-about-site-etc is much more difficult with mod_rewrite than it is with PHP. Just do this in php, get the $_GET['q'] variable and explode the string into an array or something using the / flags. It's also better this way because you'll know for sure that the / characters are reserved and you won't end up having to resolve stuff like /foo-bar/about/site. The rules would look something like:
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /+index\.php\?q=([^&\ ]+)
RewriteRule ^ /%1.html [L,R]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)\.html$ /index.php?q=$1 [L]

How to write an htaccess 301 Redirection rule to redirect from php to html

I have a problem (it's probably a simple one but I've never had the need to write regex)
A SEO specialist told me to make pretty URLs so I did with the .htaccess file the CMS provides.
But now he requires me to redirect the old URLs to new ones.
This doesn't work
RewriteRule ^index.php?page=kontakt$ /kontakt.html [R=301,L]
and also this (wich was supposed to redirect to the main page from the index.php file)
RewriteRule ^index.php$ / [R=301,L]
has resulted in sitename.com/?page=kontakt, so now I also have to redirect this.
How do I fix this?
RewriteRule only matches the base URL without the query string. You need an additional RewriteCond for it to work.
RewriteCond %{QUERY_STRING} ^page=kontakt$
RewriteRule ^index.php$ /kontakt.html [R=301,L]
EDIT:
Apparently query string gets preserved in this case, so you're probably getting /kontakt.html?page=kontakt
To discard original query string you need to put ? after URL.
RewriteRule ^index.php$ /kontakt.html? [R=301,L]

Which link will a spider use for search listings, the static link or the RewriteRule url?

I am a novice at Apache redirectives but have learned how to process clean urls that are generated by PHP on my site, which are working perfectly.
I have been researching this question and cannot seem to find a simple, straight answer.
My question is will a crawler/spider/bot use the link php shows on my site: example.com\Shoes\Running\Men or will they use the RewriteRule url: example.com\subsubcat_lookup.php?c=$1&s=$2&ss=$3 as the one that will end up showing in the search engines? (See my .htaccess below)
Also I have seen the PT|passthrough flag used like in the following example: Apache.org - Redirecting and Remapping with mod_rewrite
Is that something I should be using in my case?
Thanks so much for any clarification on this subject.
My .htaccess file:
RewriteEngine on
# do not do anything if already existing file, symbolic link or directory
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
# redirect clean url (/category) for processing
RewriteRule ^([^/]+)$ ./cat_lookup.php?c=$1 [L,B]
RewriteRule ^([^/]+)/$ ./cat_lookup.php?c=$1 [L,B]
# redirect clean url (/category/subcategory) for processing
RewriteRule ^([^/]+)/([^/]+)$ ./subcat_lookup.php?c=$1&s=$2 [L,B]
RewriteRule ^([^/]+)/([^/]+)/$ ./subcat_lookup.php?c=$1&s=$2 [L,B]
# redirect clean url (/category/subcategory/subsubcategory) for processing
RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ ./subsubcat_lookup.php?c=$1&s=$2&ss=$3 [L,B]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ ./subsubcat_lookup.php?c=$1&s=$2&ss=$3 [L,B]
My question is will a crawler/spider/bot use the link php shows on my site: example.com\Shoes\Running\Men or will they use the RewriteRule url: example.com\subsubcat_lookup.php?c=$1&s=$2&ss=$3 as the one that will end up showing in the search engines?
Since this rewriting happens internally on your server (unless you are using explicit redirects) – how you any spider even come to know these internal URLs …?
Spiders follow links they find on the web – and if only example.com/Shoes/Running/Men is linked in your pages, where would they find the other version?
Anyway, to make sure the “right” URLs get listed – add a link element with rel=canonical and give the URL you want to be used there. http://en.wikipedia.org/wiki/Canonical_link_element
This depends on crawler implementation. For example, I can write a crawler which stores the original URL (not the one given by .htaccess using rewriting) then uncleaned URL's will be stored in my DB otherwise the clean URL will be stored. As far as I know, crawlers like google etc store the clean (rewritten) URL's. You can try using apache nutch to see what the default behavior of most crawlers is.

Pretty URLs only partially working correctly

With a bit of help from people here at Stackoverflow I've managed to put together a .htaccess file that permits 'pretty URLs'. This is great if a user types the 'pretty URL' directly into the address bar as the conversion works exactly as I would like it to do, but if a user clicks a link within my site that generates a dynamic link, the 'ugly URL' remains and the conversion doesn't take place. Is there something I need to add to the .htaccess file to get this to work, or do I need to code up some PHP to force the conversion for links?
My .htaccess file is set-up as follows:
Options -Multiviews
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^mysite\.com$
RewriteRule ^(.*) http://mysite.com/$1 [R=301,L]
RewriteRule ^episode/(0|[1-9]\d{0,2})$ /episode.php?episode=$1 [L,QSA]
(Converts http://mysite.com/episode.php?episode=31 to http://mysite.com/episode/31.)
Just append this rule in the end to force pretty URL in browser:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+episode\.php\?episode=(\d+) [NC]
RewriteRule ^ episode/%1? [R=302,L]
Once working change R=302 to R=301.

Guidance on URL rewrite and construction

I am about to attempt writing of a photo sharing script and a script/rewrite that transforms numbers into descriptive names. I have a vague idea on how to go about doing this, so I was looking for some general comments/guidance.
Issue 1: I need to have a URL source for a photo which is stored above my root directory. I plan on appending the photo name (which is stored in my database) to my url as a query string, such as: www.mywebsite.com/getphoto.php?12_3.jpg and then writing a php script (getphoto.php) which takes the portion after the '?' and gets that photo from above the root.
Does this make sense and would there be any things to consider?
Issue 2: I want to transform a number at the end of my URL to a descriptive name (ie typing in facebook.com/4 displays facebook.com/zuck). I am not really sure the best way to go about doing this and was hoping for some guidance to get going in the right direction.
Thanks!
For Issue 1: a simple rewrite can handle that, you need to use the [QSA] flag. Something like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^.*\.(jpeg|jpg|gif|png|bmp)$
RewriteRule ^(.+)$ /getphoto.php?photo=$1 [L,QSA]
This will rewrite behind the scenes the url http://mywebsite.com/12_3.jpg to http://mywebsite.com/getphoto.php?photo=12_3.jpg Note that the 3rd rewrite condition wants the URI to end with an image extension, you may not need it.
For Issue 2, it depends on how something like "4" maps to "zuck". If you are going to hardcode them into your apache config, you can use a RewriteCond:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/4$
RewriteRule ^.*$ /zuck [L]
RewriteCond %{REQUEST_URI} ^/5$
RewriteRule ^.*$ /mark [L]
etc. (or replace [L] with [R,L] to redirect instead of rewrite, or alternatively just use Redirect)
Redirect /4 /zuck
Redirect /5 /mark
etc.
If the mapping is stored in a database, your going to need to do this dynamically, perhaps as a php script to do a redirect, utilizing something similar to Issue 1. The rewrite rule would rewrite to something like /redirect.php?id=$1 and your redirect.php script would take the id and do a database lookup to see where to redirect the browser.

Categories