1

Trying to setup .htaccess so I can redirect a url like http://example.com/io/abc123 to http://example.com/io/io.php?id=abc123. But, for some reason, the RewriteRule does not work as I expect.

I want to keep this redirection local without messing up the root .htaccess file, and so I create a new .htaccess file inside the io subdirectory. (Doing the equivalent in the root directory gives the same outcome, so it's not that).

Directory structure:

www
 |
 +--io
    |
    +-- .htaccess
    \-- io.php

.htaccess file:

RewriteEngine on
RewriteRule ^(.*)$ io.php?id=$1

io.php file:

<?php
  echo "Hello World" . "\n";
  echo "REQUEST_URI=[" . $_SERVER['REQUEST_URI'] . "]\n";
  echo "PHP_SELF=[" . $_SERVER['PHP_SELF'] . "]\n";
  echo "QUERY_STRING=[" . $_SERVER['QUERY_STRING'] . "]\n";
  $id = $_GET['id'];
  echo "id='" . $id . "'\n";
  ?>

OUTPUT

Hello World
REQUEST_URI=[/io/abc123]
PHP_SELF=[/io/io.php]
QUERY_STRING=[id=io.php]
id='io.php'

For reasons I don't understand, instead of the expected query_string id=abc123 this results in id=io.php.

It's obviously getting the rewrite correct to the target file io.php, but fails to substitute the abc123 into the id parameter using $1.

What am I doing wrong?

1 Answer 1

2

For reasons I don't understand, instead of the expected query_string id=abc123 this results in id=io.php

Reason is that your rule is executing twice since there is no pre-condition to not to rewrite for existing files and directories.

  1. First time it matches abc123 and rewrites to io.php?id=abc123
  2. Now our REQUEST_URI has become io.php. mod_rewrite runs in a loop unless there is no executing rule or else if source and target URIs are same. So second time it matches io.php (since our pattern is .*) and it gets rewritten to io.php?id=io.php.

mod_rewrite engine stops here because source and target URIs are same.

To fix this issue, you should use:

RewriteEngine On

# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ io.php?id=$1 [L,QSA]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.