Forum Moderators: phranque

Message Too Old, No Replies

simple mod rewrite question

I hate that I can't wrap my head around rewriting urls

         

intellivision

5:10 am on Jul 24, 2009 (gmt 0)

10+ Year Member



I've spent hours on this, and I can't get it.

example.com/product.php?product=television <- what I have
example.com/product/television <- what I want

I could put all the permutations of what I've tried here, but the server would blow up. Here's my best shot:

RewriteRule product/(.*) product.php?product=$1
RewriteRule product/(.*)/ product.php?product=$1

That doesn't do a thing. The .htaccess file is at root, as is product.php.

jdMorgan

12:53 pm on Jul 24, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The link on your page must be product/<something> for this to work.

Do you have other working RewriteRules? Are you sure mod_rewrite is enabled? Any messages in your server error log?

Also, pick either /product/<something> or /product/<something>/ as the canonical URL; Do not rewrite both forms to your script. Instead, redirect the non-canonical URL to the canonical form. Providing a rule or rules that rewrite both forms to your script creates a duplicate content problem -- two URLs competing with each other for links and ranking.

Jim

intellivision

9:35 pm on Jul 24, 2009 (gmt 0)

10+ Year Member



Thanks Jim. .htaccess does cause a 404 on the page if I put in random chars and save. No messages in error log. "ErrorDocument 404 /error.php" directive does work in the same .htaccess file.

Thanks for the tip on product/<something>. I created a product/ directory so now it's

example.com/product/product.php?product=television <- what I have
example.com/product/television <- what I want (unchanged)

RewriteRule product/product/(.*) product/product.php?product=$1
RewriteRule product/(.*)/ product.php?product=$1

are not producing anything. Or should I try RewriteCond? Should I be wrapping the paths in "^" and "$"?

jdMorgan

11:06 pm on Jul 24, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The link appearing in the HTML code of your page must be http://example.com/product/<something> for this to work.

This is a URL.

The server filesystem directory <DocumentRoot>/product/<something> need not physically exist.

If it does exists, this is a filepath.

URLs and filepaths are two different things, and each is meaningless in the other's context. Do not confuse them if you wish to understand URL-rewriting.

The basic function of a server is to translate a client-requested URL used 'out on the Web' into a filepath, used inside the server, and determined by its underlying operating system (which varies). These are two very different 'resource location systems' and are unrelated except by the action of the server.

I asked if you had other working mod_rewrite rules. You state that putting random characters into your .htaccess file caused a 404. That does not answer the question, as mod_rewrite is an Apache module and .htaccess is a file.

If you have no other working rules, then you will need to add either the second of these two lines or both of them before any other mod_rewrite directives -- it depends on your current server configuration (as pre-defined by your host), and the only way to find out is to test:


Options +FollowSymLinks
RewriteEngine on

If the required line(s) are missing, then mod_rewrite won't even execute.

Also, don't use ".*" subpatterns unless you really want to match everything, anything, or blank. Use the most-specific regular-expressions pattern possible. This will prevent unexpected operation and "mystery malfunctions," as well as avoid potentially-crippling loads on your server if you habitually use this maximally-greedy and ambiguous subpattern.

I'd code your rule as


RewriteRule ^product/([^./]+)$ product/product.php?product=$1 [L]

This prevents matches on requested URL-paths of "/product/<blank>", "/product/additional-directory/<anything>", and on "/product/product.php" -- which would otherwise match the rule again, causing an 'infinite' rewriting loop. Specifically, the requested URL-path "/product/" must be followed by one or more characters, none matching a period or a slash in order for this rule to be invoked.

Jim