简体   繁体   中英

.htaccess redirect a url to PHP using RewriteRule

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?

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]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM