简体   繁体   中英

htaccess rewriting and redirecting with get parameters

I have tried everything i could find in here. Maybe its my wamp config or maybe that the website is not in root, i have no idea. Basically some stuff worked some didnt.

What i want to achieve is remove index.php and all .php extensions altogether and force add a trailing slash / at the end.

Also i would like to pass a GET parameter after a second "/".

For Example

localhost/index.php -> localhost/
localhost/search.php -> localhost/search/
localhost/search.php?d=1 -> localhost/search/1/

My httpd-vhosts.conf :

# Virtual Hosts
#
<VirtualHost *:80>
  ServerName localhost
  ServerAlias localhost
  DocumentRoot "${INSTALL_DIR}/www"
  <Directory "${INSTALL_DIR}/www/">
    Options +Indexes +Includes +FollowSymLinks +MultiViews
    AllowOverride All
    Require local
    RewriteEngine On
    RewriteRule ^/?payday/$ /index.php [END]
    RewriteRule ^/?payday/(\w)/?$ /$1.php [END]
    RewriteRule ^/?payday/(\w)/([^/])/?$ /$1.php?param=$2 [END]
  </Directory>
</VirtualHost>

My .htaccess :

RewriteEngine On

RewriteRule ^/?payday/$ /index.php [END]
RewriteRule ^/?payday/(\w)/?$ /$1.php [END]
RewriteRule ^/?payday/(\w)/([^/])/?$ /$1.php?param=$2 [END]

The best approach to implement such a combination of things usually is to do it one by one:

RewriteRule ^/?$ /index.php [END]
RewriteRule ^/?(\w+)/?$ /$1.php [END]
RewriteRule ^/?(\w+)/(\w+)/?$ /$1.php?param=$2 [END]

You might be able to be more precise about that http GET parameter. If it always is a numerical ID as typical then use the more precise pattern ^/?(\\w)/([0-9])/?$ which will speed things up a bit.

If, as you suggest, though your question is contradictory here, if your application logic is not placed in the DOCUMENT_ROOT folder but in a subfolder, then implement specific rules and leave the dynamic configuration file (".htaccess") at top level. That prevents unexpected behavior:

RewriteRule ^/?subfolder/?$ /index.php [END]
RewriteRule ^/?subfolder/(\w+)/?$ /$1.php [END]
RewriteRule ^/?subfolder/(\w+)/(\w+)/?$ /$1.php?d=$2 [END]

In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.

This implementation will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.

And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Maybe not the answer you will hear, but a solution for nice URLs. Feel free to adapt and expand the code.

For my websites (here ct.wiimm.de) I use:

RewriteEngine on

# Rewrite base path (not really needed, but helpful on conflicts)
RewriteRule ^$ index.php [L]

# for pages with sub-path support
# -> eg.g This allows /stat/a/b/c to be send to /stat.php
RewriteRule ^((stat|tdis)/[^/.]*)/(.*) /$1.php/$3 [L]

# add .php, if not found but .php exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule .* $0.php [L]

# redirect to main index.php, if nout found
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]

And then PHP delivers all links without .php suffix.

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