RewriteRule help (simple)

I would like to know the correct RewriteRule to rewrite this:

mysite.net/photo/big-house

to:

mysite.net/photo/photo.php?ph=big-house

This seems so simple, and I have other rewrite rules almost the same which work perfectly, but I can’t get this one to work.

The closest I’ve come is

RewriteRule photo/(.*)$ photo/photo.php?ph=$1

RewriteRule photo\\/(.*)$ photo/photo.php?ph=$1

but they don’t work. Many close variants do work, but as soon as the rule gets that slash after “photo/”, the pattern is not recognized (the file opens as if there were no rewrite rule). Thus, this works (accessing another directory):

RewriteRule photo bigphoto

But these don’t work:

RewriteRule photo/ bigphoto/

RewriteRule photo\\/ bigphoto/

I must be missing something totally simple – and will be grateful for clarification.

Thank you.

Is there a photo.php in the root directory of your site?
If so, add Options -MultiViews to your .htaccess

If there isn’t a photo.php in the root directory, we’ll take it from there :slight_smile:

There is no photo.php in the root directory. The root directory contains photo/ which contains photo.php, which is that directory’s index (photo/.htaccess has DirectoryIndex photo.php).

I wasn’t familiar with Options -MultiViews (so have briefly read up on it) and have now written it into (root) /.htaccess. That hasn’t helped.

I had had this RewriteRule in photo/.htaccess but have moved it to (root) /.htaccess. That hasn’t helped.

When photo.php is called by the URL with the GET data (entered in full form into the browser address bar), it handles the GET and displays correctly. The problem is in the RewriteRule.

What seems odd is that I have a similar folder, also in the root directory, that uses this exact setup for handling simplified URL/GET calls, and it works perfectly.

I appreciate the help.

Okay, 't was worth a shot :slight_smile:

Could you please post your complete .htaccess? Maybe there’s something conflicting with your photos rule?

Also, you should probably change that rule to


RewriteRule [COLOR="#FF0000"][B]^[/B][/COLOR]photo/(.*)$ photo/photo.php?ph=$1

i.e., the URL should start with “photo”, as opposed to anywhere in the URL, which is the case without the ^

Andante,

Your problem is with the (.*) regex.

Nothing personal, here comes Standard Rant #1:

[rant #1][indent]The use of “lazy regex,” specifically the :kaioken: EVERYTHING :kaioken: atom, (.*), and its close relatives, is the NUMBER ONE coding error of newbies BECAUSE it is “greedy.” Unless you provide an “exit” from your redirection, you will ALWAYS end up in a loop![/indent][/rant #1]

Solution: Either use a RewriteCond to exclude photo.php from your RewriteRule OR get specific about what you want to redirect!

Regards,

DK

This is all very helpful. Clearly I’m too “noo” to be posting at this site and will do rigorous study before returning. Thank you.

Andante,

Don’t get disheartened! The folks here are all very helpful.

What I meant with my “Solution” was:

RewriteEngine on
RewriteCond %{REQUEST_URI} !photo\\.php
RewriteRule photo/(.*)$ photo/photo.php?ph=$1 [L]

where the exclusion is NOT photo.php

OR

RewriteEngine on
RewriteRule photo/([^.]*)$ photo/photo.php?ph=$1 [L]

where you’re excluding the dot character from the atom created as $1.

Which solution you choose will depend upon the content that you have after photo/ and both methods effectively fail to match index.php so there will be no loop.

I refer you to the tutorial Article linked in my signature as it’s helped many members for the last five or six years.

Regards,

DK

This has been very helpful. I wasn’t disheartened, just noting that proper study should precede query posting.

Further effort led to this solution:

RewriteRule ^([a-z|0-9|\\-]*)$ index.php?ph=$1

The vacuum-all “everything atom” was indeed the problem.

Using index.php instead of photo.php and a DirectoryIndex seemed to help, if only to clarify.

As well, the suggestion of possible conflict from elsewhere in the htaccess prompted an overdue tidy-up of old code.

All much appreciated. Thank you.

Andante,

One additional pointer then which could save some headaches if your index.php does not allow a null value of ph: The * metacharacter means ZERO or more whereas the + means ONE or more. In most cases, you’d want to have at least one of your characters for the value of ph.

A second point is that the | pipes in a character range definition are not only not necessary but may cause problems. Further, the - has dual meaning as it’s part of a character range definition ( [a-c] means a, b, or c are acceptable) OR, if the first (or last - there’s some debate about that), mod_rewrite is smart enough to understand that it’s not part of a character range.

So, as a result, I would translate your code to:

[code[RewriteRule ^([-a-z0-9]+)$ index.php?ph=$1 [L]


Please note that the Last flag IS important otherwise it will be ANDed with any further mod_rewrite code in your .htaccess!

Of course, if you'd read my (signature-linked) tutorial Article, you would have learned all about mod_rewrite and be correcting others with code similar to yours. ;(

Regards,

DK

DK,

Thank you. The index.php GET-handler indeed includes an if-null option supplying a random choice from an array. In fact that’s the default option, as the GET-specified choice is mainly for follow-up page calls.

The [L] flag had been set (also [NC]), though to focus the point in question I had omitted it from the post. Thank you for emphasizing it. (This code is in a sub-directory containing just that one file (index.php), and it’s only line in that htaccess, so the [L] flag had seemed optional.)

The pipes notation seems to work in both my local and remote servers though for best robustness I will heed your caution and emend the code accordingly.

Alas I had not yet studied thoroughly your excellent article, as I’ve been using an ample range of good guides, and will add your article to my list for careful reading. Of course if we were all to master the available sources, forums like this would not exist. Seeking clarification of persistently baffling points can be a reasonable thing to do.

Your responses are much appreciated as my aim is not only to create pages that seem to work but to learn to write accurate code. Early in C-application-writing days I adopted the habit of making every possible mistake deliberately and repeatedly, to insure maximum thoroughness of understanding. So knowing that something might not work someday even when it seems to work today is part of this thoroughness principle.