htacces 2 variables issues

99封情书 提交于 2021-01-04 05:40:55

问题


BEFORE I installed SSL things were working perfectly!! Here is the code I have in my root webserver .htaccess file:

Options +MultiViews
RewriteEngine On
RewriteCond %{HTTP_HOST} andrea\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://andrea.com/$1 [R,L]

RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]

It works and it does exactly what I want it to do. So if I go to for example:

www.andrea.com/account

it accesses "www.andrea.com/account.php". Which is what I want. I do however have a folder in root called "products". There is another ".htaccess" file in that folder and I don't know which of these 2 must be changed to make the following thing below work.

When you go to this url: http:____/products/view/Hello/Goodbye

I want it to access "view.php" in the 'products' folder and in that php file I could do this:

$id = $_GET["id"];    //      This would have "Hello"
$cat = $_GET["cat"];    //   This would have "Goodbye"

And this works well when I use this htaccess in the "products" folder:

RewriteEngine on
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

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

RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=$1&cat=$2

The problem with this code above is, if I go to: http:____/products/Hello/Goodbye

I want it to access the "index.php" that is in "products" folder. But instead it goes to "view.php" instead!! It's like the htaccess code above forced all to go to view.php (which should only be done if I have the "view/____" in the url. I want the url above to go to "index.php" in the "products" folder and in that file I should be able to access ID and CAT variables.

Any ideas of what to change in my .htaccess file? Sorry I spent over 2 hours I don't understand a single line at the bottom of my code but it doesn't work :/


回答1:


You can use the following rule to rewrite /products/Hello/Goodbye to /products/index.php .

RewriteRule ^Hello/GoodBye/?$ /product/index.php?id=hello&cat=Goodbye  [L,NC]

Here is your complete /product/.htaccess .

RewriteEngine on
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
#rewrite /products/Hello/GoodBye to /products/index.php
RewriteRule ^Hello/GoodBye/?$ /products/index.php?id=Hello&cat=Goodbye  [L,NC]
###################
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=$1&cat=$2



回答2:


 Options +MultiViews

First off, you should disable MultiViews. In my answer to your earlier question, my suggestion to use MultiViews was strictly an "alternative" method in the context of your question. You cannot use both methods (mod_rewrite and MultiViews) to work with extensionless URLs. And since you are now wanting to do more things and pass parameters, MultiViews will only create conflicts. (MultiViews will likely "win" and no parameters get passed.)

Also, do you specifically need the additional .htaccess file in the /products subdirectory? It will be (arguably) easier to have a single .htaccess file in the document root. This will avoid having to repeat the HTTP to HTTPS redirect (although you've not actually included an HTTP to HTTPS redirect in the subdirectory .htaccess file?).

# /products/.htaccess
RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=$1&cat=$2

This directive matches both view/Hello/Goodbye and Hello/Goodbye, which explains why everything is being written to your view.php script. However, it's not actually doing what you say either - which is puzzling. If you request /products/view/Hello/Goodbye then it will rewrite the request to /products/view.php?id=view&cat=Hello/Goodbye - which is not the intention (unless MutliViews is enabled, in which case no parameters will be passed at all).

You need to actually check for views in the requested URL-path before attempting to rewrite to views.php. And if views is not present then rewrite to index.php instead. This "conditional branching" can be achieved by simply arranging the directives in the order of "more specific" rules first.

For example, in your root .htaccess file try the following. (And remove the /products/.htaccess file altogether.)

# Ensure that MultiViews is disabled
Options -MultiViews

RewriteEngine On

# HTTP to HTTPS canonical redirect
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule (.*) https://example.com/$1 [R=301,L]

# Abort early if the request already maps to (or looks like) a file or directory
RewriteCond %{REQUEST_URI} \.\w{2,4}$ [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

# 1. Rewrite "/products/view/<id>/<cat>" to "/products/view.php?id=<id>&cat=<cat>
RewriteRule ^(products/view)/([^/]*)/?(.*) $1.php?id=$2&cat=$3 [L]

# 2. Rewrite "/products/<id>/<cat>" to "/products/index.php?id=<id>&cat=<cat>
RewriteRule ^(products)/([^/]*)/?(.*) $1/index.php?id=$2&cat=$3 [L]

# 3. Extensionless URLs for other requests
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]

The order of the 3 rules above is important. The most specific rule is first. Including the L flag to prevent further (unnecessary) processing.

Note that, as per your original directives, for a request of the form /products/view/Hello/Goodbye (or /products/Hello/Goodbye), the Hello/Goodbye part is entirely optional and will naturally result in the id and cat URL parameters being set, but empty.

Also, as per your original directives, a request of the form /products/view/Hello/Goodbye/foo/bar/baz will result in the cat URL parameter being set to Goodbye/foo/bar/baz (anything that follows the initial path segment).

You do not necessarily need to check that a request maps to a file or directory (which is relatively expensive) if you make your regex more specific and only match what you need to match. For example, your regex /([^/]*)/?(.*) currently match pretty much anything. But if your <id> and <cat> variables can only consist of lowercase letters (for example) then this could avoid the need for the filesystem checks.

Other notes:

  • Do you need to check the hostname in the HTTP to HTTPS redirect? Do you host multiple domains? Otherwise the condition that checks against the HTTP_HOST server variable is not required.


来源:https://stackoverflow.com/questions/65015896/htacces-2-variables-issues

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!