htaccess将多查询字符串重写为路径

How would i go about changing the query string

file.php?id=number&string=some-words

into this

file/number/some-words/

I know this has been asked a million times before, but I've looked at a number of solutions on here and they were all single query based (as in just ?something and not ?something&something-else).

Also once rewritten, does the php still read the original page query-string when using $_GET or $_REQUEST etc... even though it now appears as a path?

Any help is appreciated.

Thanks.

RewriteRule takes a regular expression which can be as complicated as you want it followed by the real URL that will load your file. You put parenthesis around the parts you want to capture in the regex and can reference those with $1 for first group, $2 for second group and so on in the URL part. For example:

RewriteRule ^(\w+)/(\d+)/(.*)$ index.php?file=$1&id=$2&words=$3

This would match 3 groups:

  1. letters/numbers up to the first slash
  2. some numbers up to the second slash
  3. anything after that including additional slashes

And those can be referenced by $1, $2, $3 as seen in the second part with index.php.

The only issue with this though is that if you are missing any one part, the pattern in the rule won't match. So you either need to have a separate rule for each variant:

#matches all 3 parts
RewriteRule ^(\w+)/(\d+)/(.*)$ index.php?file=$1&id=$2&words=$3
#matches the first 2 parts
RewriteRule ^(\w+)/(\d+)$ index.php?file=$1&id=$2
#matches just the first part
RewriteRule ^(\w+)$ index.php?file=$1
#matches everything else
RewriteRule ^.*$ index.php

Or you can do what is usually called bootstrapping which is where you use a single RewriteRule to redirect everything to a single php file like so:

RewriteRule ^(.*)$ index.php

And then you can just use php to determine what the different parts are. Inside php there is a built in server variable $_SERVER['REQUEST_URI'] that will give you the URI part of the url which is everything after the domain and first slash including any query string parameters. This is based on the URL that the user requested and not the one rewritten by apache. You can explode('/', $_SERVER['REQUEST_URI']) to get the individual parts and do whatever you want with them.

You can place your code in Apache .htaccess files. This could look something like this:

Options +FollowSymLinks
RewriteEngine On

RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f

RewriteRule ^users/(\d+)*$ ./profile.php?id=$1
RewriteRule ^threads/(\d+)*$ ./thread.php?id=$1

RewriteRule ^search/(.*)$ ./search.php?query=$1

Or you can use only htaccess and php:

htaccess

Options +FollowSymLinks
RewriteEngine On

RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f

RewriteRule ^.*$ ./index.php

PHP

    <?php
  #remove the directory path we don't want
  $request  = str_replace("/envato/pretty/php/", "", $_SERVER['REQUEST_URI']);

  #split the path by '/'
  $params     = split("/", $request);
?>

And it will still read the original page query-string.