Sorry in advance for non technical terms; but keep in mind I really tried a lot to find a solution before posting here.
Under webroot folder i've 2 websites; these are the entry points:
/frontend/web/index.php
/backend/web/index.php
My goal is
Access /frontend/web/index.php opening http://domain.tld
Access /backend/web/index.php opening http://domain.tld/something
This is my webroot/.htaccess
RewriteCond %{REQUEST_URI} !^something
RewriteRule ^(.*)$ frontend/web/$1 [L]
RewriteRule ^(.*)/something$ backend/web/$1 [L]
In this way, domain.tld/ is opening /frontend/web (GOOD), but also domain.tld/something is pointing to frontend/web/index.php instead of backend/web/index.php
The leading slash is removed from the URI when used to match rules in an htaccess file. That means this regex:
^(.*)/something$
will never match a URI that looks like:
something/...
Try changing the regex to:
RewriteRule ^something(.*)$ backend/web$1 [L]
Related
I want to set a rule in .htaccess if I enter in the url www.mydomain.com/compare.php set 'public_html' as root otherwise anything come in the url set root as 'public' folder.
RewriteRule ^(?!compare-source.php).*)$ public/$1 [L]
I want to achieve following result.
if url is www.mydomain.com/compare.php hit following file.
public_html/compare.php
if urls are www.mydomain.com/ OR www.mydomain.com/home etc hit following file.
public_html/public/index.php
I am weak in regex and in these apache rules always :-( can someone give me the solution with good description?
Your answers are welcome, please can you describe how this crazy things work in detail. Thanks.
Try:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/public
RewriteRule ^((?!compare\.php).*)$ /public/$1 [L]
The RewriteEngine directive enables or disables the runtime rewriting engine.
The RewriteCond directive defines a rule condition. The following Rule is only used if this condition is met; In our case, if REQUEST_URI (the path component of the requested URL) does not (because of !) begin (because of ^) with /public. We need this condition because we don't want to rewrite already rewritten URL - that would cause loop and Internal error 500.
Finally, the RewriteRule will match regex Pattern (^((?!compare\.php).*)$) against part of the URL after the hostname and port, and without the leading slash. If the pattern is matched, the Substitution (public/$1) will replace the original URL-path.
In plain language, if URL path does not begin with compare.php (because of ?!), pick everything (.*) between beginning (^) and end ($) and place it in variable $1. Then replace the original URL path with /public/$1.
#Anubhava's answer is also correct, he just placed both conditions in RewriteRule, and also it could be written even more readable as:
RewriteCond %{REQUEST_URI} !^/public
RewriteCond %{REQUEST_URI} !^/compare\.php
RewriteRule ^(.*)$ /public/$1 [L]
You can use this .htaccess in site root:
RewriteEngine On
# route /home/ or /home to /
RewriteRule ^home/?$ / [L,NC]
# if not compare-source.php or public/* then route to /public/*
RewriteRule ^(?!public/|compare-source\.php$).*)$ public/$1 [L,NC]
I want to remove all client request querystrings whatsoever, no exceptions.
I have tried everything I can find, and everything I know about regular expressions, and this task puzzles me. I have been able to achieve removal of the query strings, but now all requests have the full file path prepended to the working directory upon rewrite and redirect.
Examples: there is no http in these because stackoverflow won't let me post URLs.
I access the file: /localhost/testing/dogs/pups.txt
Yes, pups.txt exists and lives right there.
Server returns this to browser: /localhost/home/user/public_html/testing/dogs/pups.txt
If I access it with a query string appended:
/localhost/testing/dogs/pups.txt?bark=woof
I get the same output to the browser:
/localhost/home/gost/public_html/testing/dogs/pups.txt
So I know the query string is being nixed, while the full root path is being added to the hypertext address.
How do I tell mod_rewrite to keep the relative path of the existing files, so that this prepending of the full file path stops, and accurately cause it to rewrite internally and externally so that no query string ever makes it to php-land?
Here is the current .htaccess file. It resides in directory /home/user/public_html/testing. Where deployed online, it is NOT possible to put it in the root web directory, the obvious move that would instantly resolve this problem.
# These are commented out on purpose because they kill access to the server.
# The weird rules for regex in Apache configurations is baffling me. This
# does remove all QUERY_STRING characters, but, it then rewrites by
# prepending the web root path to the current directory, causing error 404.
# RewriteCond %{QUERY_STRING} ^
# RewriteRule (.*) $1? [R=301,L]
# These rules work fine. Whatever does not end with a media or document
# extension gets sent to index.php
RewriteRule ^.*\.(gif|jpe?g|png|txt|svg|pdf|rtf|odt|doc|docx)$ - [L]
RewriteRule ^.*\.(tex|epub|mobi|csv|ods|xls|swf|flv)$ - [L]
RewriteRule ^ index.php [L]
Change this RewriteCond %{QUERY_STRING} ^ to this RewriteCond %{QUERY_STRING} .
and add the directory to the rule since you can't use rewritebase. So it should look like this
RewriteCond %{QUERY_STRING} .
RewriteRule (.*) /testing/$1? [R=301,L]
I can't accept my own answer for two days, so if anyone wants to add logic about mod_rewrite for future questioners, have at it. Per Panama Jack's advice, this .htaccess file does the job and this question is answered.
RewriteEngine On
RewriteCond %{QUERY_STRING} .
RewriteRule (.*) /testing/$1? [R=301,L]
RewriteRule ^.*\.(gif|jpe?g|png|txt|svg|pdf|rtf|odt|doc|docx)$ - [L]
RewriteRule ^.*\.(tex|epub|mobi|csv|ods|xls|mm|)$ - [L]
RewriteRule ^ test.php [L]
We've switched servers and for whatever reason, our htaccess file isn't behaving the same way as it was on the other. I'm going to be the first to admit that I'm not an htaccess superuser, and I have no doubt the answer's probably looking me in the face, but literally an entire Saturday of searches hasn't fixed this. I have this filesystem:
When the domain is /category/subcategory/product/
It should rewrite to /category/product-details.php?p=product&s=subcategory
When the domain is /category/subcategory/
It should rewrite to /category-product-list.php?slug=subcategory
This seems simple enough, here's the same code we had been using for years. Note, we've commented out the first two RewriteRules regarding slashes and there was no change in behavior.
RewriteEngine On
RewriteBase /
# if folder does not end with a slash redirect to with slash
RewriteRule ^([-a-zA-Z0-9]+)$ /$1/ [L,NC,R=301]
#if it does not end with a slash e.g. rock-jewelry/some-piece, add the slash
RewriteRule ^([-a-zA-Z0-9]+/[-a-zA-Z0-9]+)$ /$1/ [L,NC,R=301]
RewriteRule ^category/([^/]+)/([^/]+)/?$ category/product-details.php?p=$2s=$1 [L,QSA]
RewriteRule ^category/([^/]+)/?$ category-product-list.php?slug=$1 [L,QSA]
When the domain is /category/subcategory/product/
It rewrites to /category-product-list.php?slug=product-details.php&p=product&s=subcategory
When the domain is /category/subcategory/
It correctly rewrites to /category-product-list.php?slug=subcategory
/category/ is an actual folder, and the only thing in it is product-details.php, there is no index.php file, the htaccess is supposed to rewrite to category-product-list if they're trying to access the index.
If we remove the category-product-list.php rule, the product-details.php rule DOES work. But isn't the L directive supposed to stop at the first rule? Why is the second still running? And how can I write a better way to accomplish this goal? Thank you very much, I'm pretty beat down on this problem at this point.
I have the same problem as you to understand the why of this loop... But it's like that.
You can add that before the last RewriteRule:
RewriteCond %{REQUEST_FILENAME} !-f
Or if you don't use dot in subcategory, you can use final RewriteRule:
RewriteRule ^category/([^./]+)/?$ category-product-list.php?slug=$1 [L,QSA]
I'm having issues with apaches mod_rewrite. I'm wanting to make clean urls with my php application but it doesn't seem to give the results i'm expecting.
I'm using this code in my .htaccess file:
RewriteEngine on
RewriteRule ^project/([0-9]{4})/([0-9]{2})$ /project/index.php?q=$1&r=$2 [L]
RewriteRule ^project/([0-9]{4})$ /project/index.php?q=$1 [L]
To make it so when I view, http://localhost/user/project/system, it would be the equivelant of viewing http://localhost/user/project/index.php?q=system
Instead of getting any results I just get a typical 404 error.
I've also just checked to see if mod_rewrite works by replace my .htaccess code with this:
Options +FollowSymLinks
RewriteEngine On
RewriteRule (.*) http://www.stackoverflow.com
And it properly redirects me here, so mod_rewrite is definitely working.
The root path to my project is /home/user/public_html/project
The the url used to view my project is http://localhost/user/project
If anymore information is required let me know.
Thanks
If your .htaccess file is indeed located in the project/ subdirectory already, then don't mention it in the RewriteRule again. Remove it:
RewriteRule ^([0-9]{4})/([0-9]{2})$ /project/index.php?q=$1&r=$2 [L]
# no "project/" here
Rules always pertain to the current local filename mapping.
Else experiment with a RewriteBase.
You have [0-9]{4} in your regex which will only match numbers of 4 digits. "system", however, is not a number of 4 digits, and therefore does not match.
You can use something like [^/]+ instead.
RewriteRule ([^/]+)/([0-9]{2})$ /index.php?q=$1&r=$2 [L]
RewriteRule ([^/]+)$ /index.php?q=$1 [L]
Don't know if the second parameter should be a number with 2 digits or not.
Edit: I also added "user" at the beginning now.
Edit2: Okay, I thought you were in the root htdocs with your htaccess. So remove "project" and "user" if you are in "project" with the .htaccess.
You probably mean
RewriteRule ^/project/([0-9]{4})/([0-9]{2})$ /project/index.php?q=$1&r=$2 [L]
RewriteRule ^/project/([0-9]{4})$ /project/index.php?q=$1 [L]
The '^project' means "start of line is 'project'" but the start is a '/project', so you need to include the starting slash (i.e. '^/project...').
Sorry, missed the system bit (and the user bit). Was concentrating on the slash.
RewriteRule ^/user/project/([a-zA-Z0-9]*)/([a-zA-Z0-9]*)$ /user/project/index.php?q=$1&r=$2 [L]
RewriteRule ^/user/project/([a-zA-Z0-9]*)$ /user/project/index.php?q=$1 [L]
Should have you right.
In my page I have a login folder. When I enter into domain.com/login/ it takes me correctly to the folder. When I write domain.com/login it also opens the page but the url changes into domain.com/login/?cname=login
My other main link is like domain.com/company and works correctly. However if i write domain.com/company/ it sais object not found.
How can I fix these?
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/$
RewriteCond %{REQUEST_URI} !^/domain.com/index.(php|html?)
# domain.com/login
RewriteRule ^/login?$ /domain.com/login/index.php
# domain.com/abc
RewriteRule ^([a-z0-9]+)?$ /domain.com/profile/company-profile.php?cname=$1 [NC,L]
It sound like you want to have domain.com/login/ or domain.com/login take you to the login folder.
The rule below will ensure that all of your folders end with a trailing slash and thus make domain.com/login work.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://domain.com/$1/ [L,R=301]
The next rule below will allow domain.com/company/ to work. In combination with the rule above, it will also ensure that domain.com/company continues to work.
RewriteRule ^company/$ profile/company-profile.php?cname=company [NC,L]
You should delete your other rules as they are incorrect.
Edit
Based on your last response modify the last rule to be
RewriteCond %{REQUEST_URI} !=/login/ [NC]
RewriteRule ^([a-z0-9]+)/$ profile/company-profile.php?cname=$1 [NC,L]
i.e. for all URI's except login do the rewrite company rule.
Make sure that you understand that any # of RewriteCond's only apply to the very next RewriteRule. I don't understand why you're matching against REQUEST_URI with a RewriteCond, rather than just matching it as part of the RewriteRule.
I also don't understand exactly what you're trying to accomplish with the ^/login?$ RewriteRule. I'm guessing the '?' needs to be escaped - otherwise, you're literally asking it to match against "/login" or "/logi".
Due to complications from the above concerns, I'm guessing your "domain.com/login" request is being handled by the 2nd RewriteRule which contains the "cname=", though I'm confused why you then don't see the "company-profile.php" as well (assuming maybe just an oversight in your question)?
After considering the above and trying to simplify this a little, I'm guessing everything should fall into place. If not, please comment back, and we'll see what we can do.