Mod_rewrite code not working

software development

#1

Greetings,

I am trying to set up something in .htaccess so that it re-writes my dynamic URLS in PHP/MySQL into something more SEO and user friendly.

I have been getting help here: http://forums.digitalpoint.com/showthread.php?t=1839007#post14408134

It seems that the code should be working but maybe something is different with Dreamhost or that I have to write it differently. Here is the .htaccess code that I have:
[php]Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([^/])/([^/])$ /type.php?denomination=$1&type=$2 [L]
RewriteRule ^([^/])/([^/])/([^/])-([^/])/([^/]*)$ /coins.php?denomination=$1&type=$2&year=$3&mint=$4&misc=$5 [L][/php]

I would like to turn:
[php]http://www.mysite.com/coins.php?denomination=Small Cents&type=Indian Head Cent&year=1878&mint=P&misc=[/php]

into:
[php]http://www.mysite.com/small-cents/indian-head-cent/1878-P/copper-nickel/[/php]

and:
[php]http://www.mysite.com/coins.php?denomination=Small Cents&type=Indian Head Cent&year=1864&mint=P&misc=Copper-Nickel[/php]

into:
[php]http://www.mysite.com/small-cents/indian-head-cent/1878-P/copper-nickel/[/php]

and:
[php]http://www.mysite.com/type.php?denomination=Small Cents&type=Indian Head Cent[/php]

into:
[php]http://www.mysite.com/small-cents/indian-head-cent/[/php]

Please let me know if you can figure this out. My current re-write code doesn’t seem to be performing anything.

Thanks


#2

Keep in mind that rewrite rules only translate URLs in one direction, and do not affect the HTML which your site outputs — if your site is still generating URLs with coins.php in them (for instance), rewrite rules won’t do anything for you.

Failing that: what, exactly, isn’t working? What happens when you try to use one of these short URLs?


#3

Hello andrewf,

When I put this code into .htaccess, it seems like nothing happens at all, as if the code wasn’t even there, nothing works.
When I go to the short URLs, there is just a 404 error and the page doesn’t exist.

I am also very new to MySQL and PHP and I am trying to build a dynamic site from the database. I have a file called coins.php and I add in the parameters (or names and attributes of coins) from the database in order to create URLs and pages. Am I supposed to be doing it a different way?


#4

Aha!

Your rewrite rules all expect there to NOT be a slash at the end of your URLs, and the URLs you’re showing here all end in a slash.

You’ll need to either use URLs without that trailing slash, or add slashes to your rewrite rules:

RewriteRule ^([^/]*)/([^/]*)/$ /type.php?denomination=$1&type=$2 [L] RewriteRule ^([^/]*)/([^/]*)/([^/]*)-([^/]*)/([^/]*)/$ /coins.php?denomination=$1&type=$2&year=$3&mint=$4&misc=$5 [L]


#5

Awesome! This seems to work if you manually type most small URLs, so that’s a breakthrough. There are still a few more problems to work out though.

Do you know how to change the URLs of the links displayed on the page? Also, if my “$misc=” field is empty, it seems that the page will not display either. For instance, if I type in:
[php]http://www.mysite.com/half-cents/liberty-cap/1794-P/high-relief/[/php]
It will work.

It will work for this as well for a coin without a misc attribute:
[php]http://www.mysite.com/half-cents/liberty-cap/1794-P/ /[/php]

But it won’t work for this:
[php]http://www.mysite.com/half-cents/liberty-cap/1794-P/[/php]


#6

You will need to change the code of those pages to output the new links? Sorry, no easy solution here.

Right. You’ll probably need to come up with a separate format for URLs to pages without a $misc… probably something like

Same as the existing coins.php rewrite rule, but without the last segment and without the misc parameter.


#7

Ok, I think I just had a major breakthrough in my thinking of how this works. I seemed to be doing everything exactly backwards.

So I should be writing search friendly URLs right into the site and link creation methods. THEN .htaccess will pick up these friendly URLs, plug them into the ugly dynamic structure set up in that file and direct me to the correct location?

I was basically creating ugly dynamic URLs first and thinking that .htaccess would re-write everything, but this is completely backwards I suppose?

[PHP]RewriteRule ^([^/])/([^/])/([^/])-([^/])/$ /coins.php?denomination=$1&type=$2&year=$3&mint=$4 [L][/PHP]

I will try this code out as well, it looks very logical to me now. Now that I am looking at this at a completely different angle, I will go in and start working on it.

I suppose I will now have to pull out things like my coin type: “Indian Head Cent”

Then use a function to strip out the spaces and capital letters to make something like this: “indian-head-cent”

Then store this into the database under an “URL” column so that my dynamic URLs know what to look for? Or probably have to create something like: “half-cents/liberty-cap/1794-p/high-relief/” to store a full URL?

Thanks


#8

Yes. This, this; a thousand times this.

The W3C has an excellent article “Cool URIs don’t change” on the design of good, lasting URLs. Good web applications design their URLs first, then write back-end code to make those URLs work, rather than vice versa (writing back-end code first, then writing URLs to make the back-end do the right thing). This forum here is, sadly, much closer to the latter, but it does serve as a decent example of how clean URLs can be added to an application which wasn’t originally written to support them. Here’s its mod_rewrite rules, for instance:

[code]RewriteEngine on
RewriteRule ^forum-([0-9]+).html$ forumdisplay.php?fid=$1 [L,QSA]
RewriteRule ^forum-([0-9]+)-page-([0-9]+).html$ forumdisplay.php?fid=$1&page=$2 [L,QSA]

RewriteRule ^thread-([0-9]+).html$ showthread.php?tid=$1 [L,QSA]
RewriteRule ^thread-([0-9]+)-page-([0-9]+).html$ showthread.php?tid=$1&page=$2 [L,QSA]
RewriteRule ^thread-([0-9]+)-lastpost.html$ showthread.php?tid=$1&action=lastpost [L,QSA]
RewriteRule ^thread-([0-9]+)-nextnewest.html$ showthread.php?tid=$1&action=nextnewest [L,QSA]
RewriteRule ^thread-([0-9]+)-nextoldest.html$ showthread.php?tid=$1&action=nextoldest [L,QSA]
RewriteRule ^thread-([0-9]+)-newpost.html$ showthread.php?tid=$1&action=newpost [L,QSA]
RewriteRule ^thread-([0-9]+)-post-([0-9]+).html$ showthread.php?tid=$1&pid=$2 [L,QSA]

RewriteRule ^post-([0-9]+).html$ showthread.php?pid=$1 [L,QSA]

RewriteRule ^announcement-([0-9]+).html$ announcements.php?aid=$1 [L,QSA]

RewriteRule ^user-([0-9]+).html$ member.php?action=profile&uid=$1 [L,QSA]

RewriteRule ^calendar-([0-9]+).html$ calendar.php?calendar=$1 [L,QSA]
RewriteRule ^calendar-([0-9]+)-year-([0-9]+).html$ calendar.php?action=yearview&calendar=$1&year=$2 [L,QSA]
RewriteRule ^calendar-([0-9]+)-year-([0-9]+)-month-([0-9]+).html$ calendar.php?calendar=$1&year=$2&month=$3 [L,QSA]
RewriteRule ^calendar-([0-9]+)-year-([0-9]+)-month-([0-9]+)-day-([0-9]+).html$ calendar.php?action=dayview&calendar=$1&year=$2&month=$3&day=$4 [L,QSA]
RewriteRule ^calendar-([0-9]+)-week-(n?[0-9]+).html$ calendar.php?action=weekview&calendar=$1&week=$2 [L,QSA]

RewriteRule ^event-([0-9]+).html$ calendar.php?action=event&eid=$1 [L,QSA][/code]

[quote]I suppose I will now have to pull out things like my coin type: “Indian Head Cent”

Then use a function to strip out the spaces and capital letters to make something like this: “indian-head-cent”

Then store this into the database under an “URL” column so that my dynamic URLs know what to look for? Or probably have to create something like: “half-cents/liberty-cap/1794-p/high-relief/” to store a full URL?[/quote]
That’s one approach that I’ve seen some sites take. It certainly works.


#9

I have been extremely successful in getting most of the URLs re-written!

The only thing I keep getting snagged on right now is the “misc” field. Some URLs have this field and others don’t. Right now, I have this in my .htaccess code related to this part:
[PHP]
RewriteRule ^coins/([^/])/([^/])/([^/])-([^/])/$ /coins.php?demurl=$1&typeurl=$2&year=$3&mint=$4 [L]
RewriteRule ^coins/([^/])/([^/])/([^/])-([^/])/([^/]*)/$ /coins.php?demurl=$1&typeurl=$2&year=$3&mint=$4&miscurl=$5 [L]
[/PHP]

I have URLs like this:
[PHP]
1794 P - (high relief)
1794 P
[/PHP]

Something very strange happens here. The bottom URL is missing the misc attribute, but something is passing the variable “high-relief” and the page itself is displaying information meant for the first URL.

BUT, if I have my links set up like this where the “misc” fielded URL is on the bottom and not on top:
[PHP]
1794 P
1794 P - (high relief)
[/PHP]
Then everything seems to work as it should. I’m not sure if this is the .htaccess or something else in my code. Here is the code I am using to search the database before displaying the data on the target page:

[PHP]
$sql = “SELECT * FROM coins WHERE demurl LIKE '”.$demurl."%’ AND typeurl LIKE ‘".$typeurl."%’ AND year LIKE ‘".$year."%’ AND mint LIKE ‘".$mint."%’ AND miscurl LIKE ‘".$miscurl."%’";
[/PHP]
All of these variables should be singling out a unique row in the table and it works for everything else except for this small issue. Let me know if you see anything.

ADDITIONAL INFORMATION

I found one other error in my site with URLs like this:
[php]http://www.mysite.com/coins/proof-sets/1937-P/[/php]
The only difference here is that my (coin type) is NULL in the database because the “proof sets” is a denomination that is too general to make another subtype out of, so I left it empty. Here is what my full URL structure would normally look like with variables:
[php]http://www.mysite.com/coins/(denomination)/(coin type)/(year)-(mintmark)/(misc)/[/php]

So there seems to be problems when the (misc) or (coin type) needs to be removed since these are not needed and left empty in the table.


#10

I think I will just place the coin id right after “/coins/” or at the end of the URL to make things easier. It works so far, but now I have to be careful when adding new things to the spreadsheet where I want them (so it looks organized for me) and database with a unique ID so all my URLs don’t go 404 on me. I’m sure an extra id number in my URL won’t hurt the SEO too much.

Thanks for the help andrewf. Either way, most of the URLs are SEO’d, which was something I couldn’t do a week ago!