Rewrites 2 folders deep

Hi

Bit new to mod rewrites, but realising it’s power and very cool. I can get rewrites working when the actual file is in the root but not working when in subfolders.

What I’m trying to do:-
I want the URL mydomain.com/groundcare/hire/mowers/ to go to the page at mydomain.com/groundcare/hire/show.php?cat=mowers

I’ve tried the following but just get 404 page not found.
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^groundcare/hire/(.*)/$ groundcare/hire/show.php?cat=$1 [L]

I’ve been trying and going round in circles and I’m sure it’s something simple so if anyone could point me in the right direction it would be greatly appreciated.

Many thanks!

I tried this on my local machine, and it worked perfectly fine. There must be something else significant in your htaccess or your file structure that’s causing the problem.

Hi

Thanks for response. I’ve re-uploaded and I’m not getting a 404 any longer, but it’s not passing the category correctly. If I try to echo out $_GET[‘cat’] on the page it says “show.php” rather than the actual category. So it is almost working, just not quite as intended. Is it something stupid I’ve missed?

Forgot to say the .htaccess file is situated in the root - just encase you need the info and the other pages are in a folder at mydomain.com/groundcare/hire/

Many thanks for responding so quickly - much appreciated

I’m sorry to have to give the same answer, but on my local machine, this works perfectly fine. There must be something else significant happening in your htaccess or elsewhere that we haven’t seen. You’ll probably have to post your entire htaccess if you want us to be able to spot the problem.

Hi

My entire htaccess (3 lines) is as follows:-

Options +FollowSymLinks
RewriteEngine on
RewriteRule ^groundcare/hire/(.*)$ groundcare/hire/show.php?cat=$1 [L]

When I’m on the page at mydomain.com/groundcare/hire/ (which is the file mydomain.com/groundcare/hire/index.php) I click a link on the page such as mydomain.com/groundcare/hire/compact-tractors and it goes to this URL which should be mydomain.com/groundcare/hire/show.php?cat=compact-tractors and the pag shows but when I echo out the $_GET[‘cat’] variable using PHP it shows that $_GET[‘cat’] is show.php.

Hope that makes sense. Many thanks again for responding so quickly, much appreciated.

There’s a small but significant difference between this rewrite rule and the one from your original post: the trailing slash. Using your latest rule, here’s what happens:

First, groundcare/hire/mowers/ is rewritten to groundcare/hire/show.php?cat=mowers/. Then, because the internal URL changed, Apache re-processes it, which means once again cycling through the rewrite rules, where groundcare/hire/show.php?cat=mowers/ is rewritten to groundcare/hire/show.php?cat=show.php. In the rewrite rule from your original post, this wouldn’t happen because show.php doesn’t end in a slash, and thus wouldn’t match.

Here’s what is probably the best way to handle this:

# Apply the next rewrite rule only if this condition passes
# The condition is that the request must not be for a real file, such as show.php
RewriteCond %{REQUEST_FILENAME} !-f

# Your rewrite rule, but with an optional trailing slash
# And I removed the "last" flag, because it probably isn't necessary
# And I added the "query string append" flag so that
# you can still use other query parameters that are passed in the URL
RewriteRule ^groundcare/hire/(.*?)/?$ groundcare/hire/show.php?cat=$1 [QSA]

That is because you are in a loop now.
mydomain.com/groundcare/hire/compact-tractors and mydomain.com/groundcare/hire/show.php?cat=compact-tactors are matching your rewrite rule.

mydomain.com/groundcare/hire/compact-tractors is being redirected to mydomain.com/groundcare/hire/show.php?cat=compact-tactors, but then the rewrite rule is picking up mydomain.com/groundcare/hire/show.php?cat=compact-tactors and redirecting that to mydomain.com/groundcare/hire/show.php?cat=show.php

You need to add a RewriteCond %{REQUEST_FILENAME} !-f

Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^groundcare/hire/(.*)$ groundcare/hire/show.php?cat=$1 [L]
Edit:

Not wanting to start a rant, but this is why dklynn and I strongly disagree with the use of (.*), as it is easy to create this scenario using it, much harder to create it using a proper range of acceptable characters to capture, such as, ([a-zA-Z0-9-]+)

Hi

Thanks so much Jeff - that works perfectly. Also, thanks for the detailed explanation, that makes sense. Sorry for the difference in the post, I was playing round in between the first post and previous one to try and get it working. Have added lines as you suggested and all is working as expected now.

Thanks again for such a prompt response. Certainly quickest response I’ve had on a forum in a long time, think I’ll stick with site point in the future:-)

Enjoy the rest of your day!

That’s what rewrite conditions are for.

Nonetheless, everyone is entitled to their opinion. My biggest problem with dklynn’s rants are that 1) he seems to berate users for using (.*), even when they use it correctly, and 2) he doesn’t acknowledge that his opinion is contrary to the official documentation, which makes it all the worse when he scolds users for using solutions that the documentation says is actually the correct approach.

Agreed.

I understand :slight_smile:

… and I will continue to recommend that newbies (especially) learn some regex so they don’t end up in these ridiculous loopy situations.

Regards,

DK