in a project i have .htaccess files in many Subdirectories.
here is an example Structure:
project/.htaccess
project/admin/.htaccess
project/admin/pdf/.htaccess
in the last one i successfully use the following:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /project/admin/pdf/
RewriteRule ^([pdf\.actions]+)$ pdf.out.actions.php [QSA]
this works fine, if the Project Folder is placed directly in the root directory.
all other subdirs have same htaccess logic, now if the user needs to put the project in any other directory rather than root, he/she has to change all RewriteBase in all htaccess Files in all subdirectories of the project.
my question: how to rewrite my htaccess content, so i get the same result as mentioned above but with "dynamic" base or without Base...etc?
i tried somany things without success.
i removed the line RewriteBase /project/admin/pdf/ and tested it, i get site not found...etc!
any Idea?
thanks
You can try adding something like this to the top of your rules:
RewriteCond %{ENV:URI} ^$
RewriteRule ^(.*)$ - [ENV=URI:$1]
RewriteCond %{ENV:BASE} ^$
RewriteCond %{ENV:URI}::%{REQUEST_URI} ^(.*)::(.*?)\1$
RewriteRule ^ - [ENV=BASE:%2]
And then instead of using RewriteBase, you'll have to include the BASE environment variable everywhere. For example:
RewriteRule ^([pdf\.actions]+)$ %{ENV:BASE}/pdf.out.actions.php [QSA]
The conditions do a couple of things, but both rules change nothing in the URI and only add environment variables.
The first condition is necessary because it grabs the requested URI before anything is done to it, and stores it. This is important because the (.*) grouping in the rule has the base stripped off. We want the unaltered URI with the base stripped off. So the URI environment variable is the URI with the base stripped off.
The second condition is necessary because it compares the URI environment variable with the %{REQUEST_URI}, which is the entire URI, including the base. That comparison yields us the part that was stripped off, or the base, and that'll be stored in the BASE environment variable.
The conditions which match against ^$ is simply ensuring that this is the first time through the rules (meaning neither of the environment variables have been set). The rewrite engine will loop so we only want to set these the first time.
EDIT: actually, now that I'm looking at it, you could probably leave the first one out:
RewriteCond %{ENV:BASE} ^$
RewriteCond $1::%{REQUEST_URI} ^(.*)::(.*?)\1$
RewriteRule ^(.*)$ - [ENV=BASE:%2]
Using the $1 backreference which matches the rule, noting that the rule itself is partly evaluated (pattern applied) before any of the conditions are checked.
Related
I am trying to change:
example.com/profile.php?id=abcdefgh
To simply:
example.com/abcdefgh
I searched here on StackOverflow and I understood that I need to do something with my .htaccess, I tried this code:
RewriteEngine On
RewriteRule ^([^/]*)$ /profile.php?id=$1 [L]
But it seems nothing changes, when type this URL (example.com/profile.php?id=abcdefgh) it doesn't get rewritten.
P.S. I don't know if the above code is right, i tried it because where I got it from had a similar problem to mine.
This should work.
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ profile.php?id=$1 [QSA,L]
You should be requesting the "pretty" URL, ie. /abcdefgh. Your mod_rewrite directive in .htaccess then internally rewrites this to the "real" URL that actually handles the request (ie. /profile.php?id=$1). That directive is expecting a URL of the form /abcdefgh. However, in its current state I should expect a rewrite loop:
Request /abcdefgh
Request is rewritten to /profile.php?id=abcdefgh.
Processing starts over...
Request is rewritten to /profile.php?id=profile.php (because the regex ^([^/]*)$ matches the profile.php part of the rewritten URL.
GOTO #3
In this example you can avoid the rewrite loop by simply making the RewriteRule pattern (regex) more restrictive. eg. Include a dot (.) in the negated character class (assuming your new "pretty" URLs do not contain a dot).
For example:
RewriteRule ^([^/.]+)$ /profile.php?id=$1 [L]
You then need to actually change the URLs on your website to the new "pretty" URLs.
However, if you are currently getting a 404 then maybe this directive isn't being processed at all? Are .htaccess files enabled? Do you have other directives in your .htaccess file?
UPDATE: in the id the only characters allowed are A-Z
In that case you should be more specific with the regex and match just the characters required. This helps to avoid conflicts and avoids the need for filesystem checks (to some extent) - which are relatively "expensive". Note, however, that you've stated "A-Z" but your example includes lowercase letters. For the sake of argument I'll assume the id can include a-z and A-Z.
So, this now becomes:
RewriteRule ^([a-z]+)$ /profile.php?id=$1 [NC,L]
No other filesystem checks (preceding RewriteCond directives) are necessary. The NC (nocase) makes the regex match case-insensitive.
There is no need to check that the request does not map to a file (with a preceding condition), since the regex ^([a-z]+)$ could never match a file (that includes a file extension).
There is also no need to check that the request does not map to a directory, unless you are requesting directories in the document root directly - which is probably "unlikely". However, therein lies an inherent conflict with this URL structure. If you needed to be able to access a directory then those directory names become invalid IDs - so you would need other checks elsewhere in your system to ensure no IDs were generated that map to physical directories in the document root.
My directories are like:
http://www.mydomain.com/macbook-computer
http://www.mydomain.com/sony-computer
http://www.mydomain.com/lenovo-computer
I want to make that, if a user type computers/macbook-computer like:
http://www.mydomain.com/computers/macbook-computer
I want to display page which is : http://www.mydomain.com/macbook-computer.
My restrictions are:
1. User must type /computers (segment 1)
2. String coming from computers/ must end with "computer". (segment 2)
How can I make this achieve in my .htaccess file?
You may try this:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/computers/([^-]+)-computer/? [NC]
RewriteRule .* %1-computer? [R=301,L]
Redirects permanently
http://www.mydomain.com/computers/anyname-computer with or without trailing slash.
To:
http://www.mydomain.com/anyname-computer
Strings computers and computer are assumed to be fixed, while anything is assumed to be variable.
The incoming URL structure has to be kept for the rule-set to work: First folder /computers followed by /anyname-computer.
For silent mapping, remove R=301 from [R=301,L]
You need a rewrite rule in your .htaccess file, and a little regular expression magic. Something like this should do the trick
RewriteRule ^computers/macbook-computer$ http://www.mydomain.com/macbook-computer
Here's a nice online tool for checking rewrite rules
http://htaccess.madewithlove.be/
I have the following code in my .htaccess.
RewriteEngine On
RewriteRule ^/(\w+)/?$ /?user=$1
I'm trying to rewrite
http://domain.com/?user=username into http://domain.com/username. Unfortunately this code doesn't rewrite anything. Please help
Note:
I checked phpinfo() and mod_rewrite is loaded.
Update
I need to get username from url like http://facebook.com/username. But this code rewrites every folder in root folder, so my /css folder become http://domain.com/css/?u=common. How to allow this code works only for http://domain.com/index.php
The mistake you are doing is the use of / in the beginning of the line ^/(\w+)/?$
rewrite rules strips off the / from the beginning of the pattern to be matched in .htaccess and directory context.
Try doing this:
RewriteEngine On
RewriteRule ^(\w+)/?$ /?user=$1
From RewriteRule Directive docs :
What is matched?
In VirtualHost context, The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html").
In Directory and htaccess context, the Pattern will initially be matched against the filesystem path, after removing the prefix that lead the server to the current RewriteRule (e.g. "app1/index.html" or "index.html" depending on where the directives are defined).
If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively.
Edit: Answer updated as per OP's request:
Add this :
RewriteEngine On
#do nothig if URL is trying to access the folder CSS.
RewriteRule *css/* - [L]
#checks where the URL is a valid file/folder.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(\w+)/?$ /?user=$1
I think that you are doing it the right way round, but explained it the wrong way round!
Is the problem that you don't need the initial / as the URL passed to test doesn't include it!?
I suspect it should be RewriteRule ^(\w+)/?$ /?u=$1
Also, be careful you don't end up with a loop!
I am using this rule to rewrite the link
RewriteEngine On
RewriteRule ^(.*)/(.*) show_cv.php?email=$1
It is working fine like if I write this url with last slash
www.mysite.com/letschat_2008#yahoo.com/ ----> index.php?email=letschat_2008#yahoo.com
But when I remove the last slash from the link www.mysite.com/letschat_2008#yahoo.com/ it shows error 404.
I wish the URL Rewrite rule would work for both with slash and without slash (/)
www.mysite.com/letschat_2008#yahoo.com/ ----> index.php?email=letschat_2008#yahoo.com
www.mysite.com/letschat_2008#yahoo.com ----> index.php?email=letschat_2008#yahoo.com
Your rules are looping, you need to make sure you are rewriting an email address, and add some conditions so that the rule doesn't get applied if it's accessing an existing resource:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9_\-\#\.]+)/?$ /show_cv.php?email=$1 [L]
You should then be using the following rule:
RewriteRule ^(.*)/? show_cv.php?email=$1
I assume you note these rules in a .htaccess file, not in the server configuration when looking at your description ?
Rethink if you don-t want to put this into the server configuration. Apart from the usage of .htaccess files being harder to debug using rewrite rules in those files is more complex than in the server configuration. This is documented in mod_rewrites docs.
The reason for the behaviour is the different content of REQUEST_URI in both cases. Have a try checking this directly and you will see the problem. The whole part "letschat_2008#yahoo.com" is simply missing in that variable in case 2 (no "/"). To get this working you must use an additional rewriteCondition (also documented...). Something like these untested lines:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/(.+)&
RewriteRule - show_cv.php?email=%1
(note the '%' instead of a '$' in the last line)
I need a little help figuring out what the following URL rewrite rule means. I can understant the first three lines, but I got stuck with the index.php/$1 part. What does exactly the / means in this rule? The only thing I would always expect to see after a file name would be a query-string separator (?). This is the first time I am seeing the / as a separator. What does it exactly mean?
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [PT,L]
</IfModule>
The <IfModule mod_rewrite.c>...</IfModule> block ensures that everything contained within that block is taken only into account if the mod_rewrite module is loaded. Otherwise you will either face a server error or all requests for URL rewriting will be ignored.
The following two lines are conditions for the RewriteRule line which follows them. It means that the RewriteRule will be evaluated only if these two conditions are met.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
These lines simply state that rewriting (RewriteRule line) will occur only if there are no existing files or folders on the server which match the URI. If they do exist then they will be served instead, unless there is some other directive that prevents it, otherwise rewriting will occur.
The last line will do the actual rewriting. It will take whatever is following the website domain name and append it to a rewritten request which will begin with index.php/.
Here is an example.
Lets say you make a request for example.com/example-page.html.
If there is no existing file or folder in the virtual hosts root folder named example-page.html the rewrite rule at the end will rewrite the request to look like example.com/index.php/example-page.html.
The main reason why applications rewrite requests like this is to ensure that they have a single point of entry, often called a bootstrap, which is considered to be a good practice from the security standpoint and also offers more granular control of requests.
Here is in my opinion a very good beginner friendly tutorial for mod_rewrite.
It's just rewritting the url name.
For example, this url:
http://www.example.com/something/else
Will be the same as:
http://www.example.com/index.php/something/else