Question

Strange problem with Apache and mod_rewrite rule

Hello to all,

I have apache installed on ubuntu, the re-written module is configured correctly, but one of the rules insists not work.

.htaccess

<IfModule mod_rewrite.c>
    RewriteEngine On
        RewriteRule ^test/([a-z0-9-]+)/([a-z0-9-]+)-([a-z0-9-]+)/?$ /cidade.php?cod=$3 [NC]
        RewriteRule ^cidade/([a-z0-9-]+)/([a-z0-9-]+)-([a-z0-9-]+)/?$ /cidade.php?cod=$3 [NC]
</IfModule>


cidade.php
<?php 
print_r($_GET);
?>

The url /test/el-monte-cl/587-369451/ print: Array ( [cod] => 369451 ). Its ok. But /cidade/el-monte-cl/587-369451/ print: Array ( )

The rules are identical, only changes the prefix (city / test). Maybe someone can tell me a solution?

thank you


Submit an answer


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

KFSys
Site Moderator
Site Moderator badge
May 23, 2023

For anyone stumbling upon an old topic. The issue you are facing could be related to the order in which the rules are evaluated by Apache’s mod_rewrite module. By default, mod_rewrite stops processing rules once it finds a match. In your case, the first rule matches the URL /cidade/el-monte-cl/587-369451/, and the rewriting process stops at that point.

To solve this, you can use the [L] flag (last) in the first rule, which tells mod_rewrite to stop processing rules and immediately apply the current rule if a match is found. Then, you can place the more specific rule for /cidade/ before the more general rule for /test/. Here’s the updated .htaccess file:

<IfModule mod_rewrite.c>
    RewriteEngine On

    RewriteRule ^cidade/([a-z0-9-]+)/([a-z0-9-]+)-([a-z0-9-]+)/?$ /cidade.php?cod=$3 [NC,L]
    RewriteRule ^test/([a-z0-9-]+)/([a-z0-9-]+)-([a-z0-9-]+)/?$ /cidade.php?cod=$3 [NC]
</IfModule>

With this modification, the more specific rule for /cidade/ will be evaluated first and the rewriting process will stop if a match is found. This ensures that URLs matching /cidade/ will be processed correctly.

Make sure to save the updated .htaccess file and restart Apache for the changes to take effect.

I suspect the problem is not in the .htaccess at all, but rather somewhere in the PHP code or usage. Is it possible what’s being printed moves around a whole lot so the ‘369451’ that referenced it once is not quite right any more only a bit later?

The “flags” in .htaccess can be confusing because they’re so highly abbreviated yet don’t all follow the exact same pattern. [N] is “next”, [C] is “chain”, [NC] is “no case” (i.e. ignore the case of each letter when making this test), etc. Next and Chain together would be [N,C].

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
June 15, 2013

It’s because of the [C] flag: <br> <br>The [C] or [chain] flag indicates that the RewriteRule is chained to the next rule. That is, if the rule matches, then it is processed as usual and control moves on to the next rule. However, if it does not match, then the next rule, and any other rules that are chained together, will be skipped. <br> <br>The two rules are chained, the first one doesn’t match so it skips the rest of the chain which would be the second one in this case. <br> <br>Remove the C flag from both rules and it should work. You don’t need the N flag, so get rid of that one too. <br>

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel