I have this .htaccess file and I have no knowledge with mod_rewrite,
RewriteEngine On
RewriteRule ^(.+[^/])/$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{THE_REQUEST} \s/([^.]+)\.php [NC]
RewriteRule ^ /%1 [NE,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)/?$ /$1.php [L]
What I want to achieve is to have localhost/viewticket/${id} instead of localhost/viewticket.php?id=123
I have tried many .htaccess rules but none worked except this one that hides .php in my URL.
I created this one for you, just erase yours and copy this one enjoy^^
IndexIgnore */*
Options FollowSymLinks
AddDefaultCharset utf-8
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^viewticket/([^/]+)/?([^/]*)/?([^/]*)$ viewticket.php?id=$1¶m2=$2¶m3=$3 [L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)/?$ /$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . index.php [L]
</IfModule>```
Make sure you've changed your internal URLs so you are linking to /viewticket/<id>. Then add the following at the top of the root .htaccess file:
# Prevent MutliViews rewriting "viewticket" and omitting the URL parameter
Options -MultiViews
RewriteEngine On
# Redirect any direct requests to "/viewticket.php?id=<id>" to "/viewticket/<id>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^id=(\d*)
RewriteRule ^(viewticket)\.php$ /$1/%1 [R=301,L]
# Rewrite "/viewticket/<id>" to "viewticket.php?id=<id>"
RewriteRule ^(viewticket)/(\d*)$ $1.php?id=$2 [QSA,L]
If you are not expecting any query string on your "pretty" /viewticket/<id> URL then remove the QSA (Query String Append) flag in the last rule.
$1 is a backreference to the first capturing group (parenthesised subpattern) in the RewriteRule pattern. Likewise, %1 is a backreference to the first capturing group in the last matched CondPattern (RewriteCond directive).
Always test first with 302 (temporary) redirects to avoid potential caching issues and only change to a 301 (permanent) redirect when you are sure everything is working as intended. Clear your browser cache before testing.
Reference:
https://httpd.apache.org/docs/2.4/rewrite/intro.html
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule
Additional:
RewriteEngine On
RewriteRule ^(.+[^/])/$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{THE_REQUEST} \s/([^.]+)\.php [NC]
RewriteRule ^ /%1 [NE,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)/?$ /$1.php [L]
Your existing directives (that remove the trailing slash and .php extension) are not quite correct.
Your first rule that unconditionally removes the trailing slash will also "try" to remove the trailing slash from directories as well - which will conflict with mod_dir and result in a redirect loop. The negated character class [^/] (to match a non-slash character) in the middle of the regex would seem to be superfluous. This also redirects to HTTP (not HTTPS)?
The second rule that removes the .php extension would also erroneosuly match .php should it appear in the query string portion of the URL. eg. /foo?bar.php would be redirected to /foo?bar. Although the regex ([^.]+) does avoid the perhaps more common case of /foo.php?bar.php being erroneously redirected.
The third rule that appends the .php extension via an internal rewrite could potentially result in a rewrite-loop (500 Internal Server Error) if you received a request of the form /foo/bar and /foo.php exists in the root of the filesystem. Also, the (optional) trailing slash is also captured by the capturing subgroup, since the * quantifier is greedy. This would also result in a malformed rewrite, if it wasn't for the first rule that removes the trailing slash. (But since the trailing slash is removed then the optional trailing slash in this rule is redundant.)
If you still need these rules to remove the trailing slash and handle extensionless .php URLs then have these rules as follows. Make sure you are already linking to the extensionless URLs internally. These rules should follow the rule block I posted above.
# Remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
# Remove ".php" extension if present on the initial request
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)\.php$ /$1 [R=301,L]
# Append ".php" extension if request maps to a PHP file
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.*?)/?$ $1.php [L]
These directives (and your original directives for that matter) do assume the .htaccess file is located in the document root directory.
You can use the following code:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L
And if it won't works you can read this PDF file: How to remove PHP or HTML extensions with htaccess
Related
My request is quite simple. Using my current .htaccess conditions and rules as given here:
# Remove .php extension from URLS
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
# Redirect from *.php to URL without *.php
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L]
Problem is, when I pass a URL that contains *.php?param1=A¶m2=B as a parameter, it throws away "?param1=A¶m2=B"
For example:
I want to redirect to: "/views/users/login.php?redirect=/views/home.php?id=1"
Resulting in: "/views/users/login?redirect=/views/home", which throws away "?id=1", so now I can not access that parameter.
How do I rewrite my rules so that it keeps those parameters?
Any suggestions are welcome and much appreciated.
Update (2015-09-16):
Removing
RewriteRule ^(.*)\/index\.php$ $1 [R=301,L,NC]
As it is irrelevant.
You'll have to use urlencode to encode the URL into a parameter.
So when building the link or redirect, use:
redirect('views/user/login.php?redirect=' . urlencode('/views/home.php?id=1'))
btw: redirecting to a "controller" in a folder called "views" might be a bit confusing in a few month :)
Hello you just need to add the query append marker like so:
RewriteRule ^(.*)\/index\.php$ $1 [QSA,R=301,L,NC]
that is "QSA"
I have solved this issue (to some agree) using the following code:
# Enable rewrite mod.
RewriteEngine On
RewriteBase /
Options +FollowSymLinks -MultiViews
# Redirect URLs that contain *.php to extensionless php URLs.
RewriteCond %{THE_REQUEST} ^(.*)\.php
RewriteRule ^(.+)\.php$ $1 [R,L]
# Resolve *.php file for extensionless php URLs.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*)$ $1.php [NC,L,QSA]
# Resolve /views/* for URLs that do not contain views and needs it.
RewriteCond %{REQUEST_URI} ^/applications/(.*)$ [OR]
...
RewriteCond %{REQUEST_URI} ^/home [OR]
...
RewriteRule ^(.*)$ /views/$1
# Redirect URLs that contains /views/* to viewsless URLs.
RewriteCond %{THE_REQUEST} ^(.*)/views/(.*)
RewriteRule ^views(.*)$ $1 [R,L]
I'm having an issue where some of the redirects don't work without a / at the end of the URL. Additionally, sometimes I have conflicting redirects that rewrite the following redirect.
Global Rules
Options -MultiViews
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
ErrorDocument 404 /404.php
Doesn't work without slashes
RewriteRule ^(.*)launch/$ /$1products/ [R=301,L]
RewriteRule ^(.*)solutions/$ /$1products/ [R=301,L]
Example:
When I search for /launch without the last / then I end up at my 404 page.
Conflicts for second and third
RewriteRule ^(.*)products/overview/heartbeat/$ /$1products/heartbeat/ [R=301,L]
RewriteRule ^(.*)heartbeat/$ /$1products/heartbeat/ [R=301,L]
RewriteRule ^(.*)heartbeat-beta/$ /$1products/heartbeat-beta/ [R=301,L]
Example:
When I search for /heartbeat-beta/ and expect to get /products/heartbeat-beta/ my result is:
/products/products/products/products/products/products/products/products/products/products/products/products/products/products/products/products/heartbeat-beta/
Your rewrite rules are not in correct order have some suspicious regex patterns. Have it in this order:
RewriteRule ^(heartbeat(?:-beta)?)/?$ /products/$1/ [R=301,L,NC]
RewriteRule ^products/overview/(heartbeat)/?$ /products/$1/ [R=301,L,NC]
PS: To make trailing slash optional use /?$ in your regex pattern.
The target is to combine several rules:
never have a trailing slash in the URI
internally rewrite to the index.php (domain.tld/somedir/index.php) when calling domain.tld/somedir
remove file extensions, check if + '.php' exists and eventually internally rewrite to it
This is to be done in '.htaccess' as this is my only accessible .
My attempt so far
# check if *.php exists
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*[^/])/?$ $1.php [L, QSA]
# do not allow trailing slash
RewriteRule (.*)/ $1 [L, R=301]
The difficulty here is that the query 'domain.tld/somedir' normally calls the directory's index.php after having been redirected to 'domain.tld/somedir/'. However, I would like the index.php to be internally called (no 301) directly when querying 'domain.tld/somedir'.
You can use this code:
DirectoryIndex index.php
RewriteEngine On
# remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} \s(.+?)/+[?\s]
RewriteRule ^(.+?)/$ /$1 [R=301,L]
# To internally forward /dir/file to /dir/file.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f [NC]
RewriteRule ^(.+?)/?$ /$1.php [L]
There is a separate setting in apache called DirectorySlash that can be enabled/disabled. You can read more at httpd.apache.org/docs/2.2/mod/mod_dir.html#directoryslash but be sure to read the part about why this is done right below where it says "some good reasons". Also note the security issue.
I have files in my root folder. jobs.php, contact.php.
I want to be able to use .htaccess to remove the .php extension and force a trailing slash /. So that, www.domain.com/jobs/ and www.domain.com/contact/ goes to their respective pages.
Also, I want jobs.domain.com to point to www.domain.com/jobs/
<IfModule mod_rewrite.c>
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteBase /
RewriteRule ^(rosquillos)/$ $1 [L,R=301,NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
</IfModule>
This is what I've got so far, and as much as I try. I can't seem to get it to work.
Any help would be awesome.
EDIT:
I would like to rephrase my question. The existing code removes the .php extensions for me, what I really only need right now is an additional rule that points the subdomain to the correct file: ie. jobs.domain.com points to jobs.php. I can live without the trailing slash.
Your condition:
RewriteCond %{REQUEST_FILENAME}\.php -f
will fail if your URL's end with a trailing slash. But if you only have jobs and contact then you'll just want:
RewriteEngine On
# add trailing slash and redirect browser
RewriteRule ^([^/]+)$ /$1/ [L,R=301]
RewriteRule ^([^/]+)/$ /$1.php [L]
# redirect direct access to php files:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+)\.php
RewriteRule ^ /%1/ [L,R=301]
Oh and I forgot:
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.domain\.com$ [NC]
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^ /%1.php [L]
Assuming that *.domain.com has the same document root as www.domain.com.
Here's essentially what I'm trying to do:
If the URL a visitor requests points to a file or directory, show that file
Else, redirect back to the index.php file
The .htaccess file below is working great; the only issue I'm facing is that if the URL a visitor requests is a PHP file with $_GET parameters, they are taken to the index.php file instead of the file they should be going to. Any ideas on how I can fix that?
# Prevent "Index Of" pages
Options -Indexes
# Rewrite
RewriteEngine on
# Rewrite www to non-www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
# If requested resource exists as a file or directory, go to it
RewriteCond %{DOCUMENT_ROOT}/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule (.*) - [L]
# Else rewrite requests for non-existent resources to /index.php
RewriteRule (.*) /index.php?url=$1
Apache normally cuts off the query string. To append it, the qsappend flag (QSA) should be included in all your rewriteRule lines, like this:
# Prevent "Index Of" pages
Options -Indexes
# Rewrite
RewriteEngine on
# Rewrite www to non-www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L,QSA]
# If requested resource exists as a file, do not rewrite.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /index.php?url=$1 [QSA]
// EDIT: You are explicitly rewriting existing files to themselves. Just don't do that, but bail out if your URL hits an existing file. (code above edited.)
Problem
# If requested resource exists as a file or directory, go to it
RewriteCond %{DOCUMENT_ROOT}/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule (.*) - [L]
Aren't you potentially looking for a file like "somepath.php?querystring" on the filesystem, by doing this? I think that $1 includes the querystring.
So these conditions fail, and you fall through to the final rewrite rule. The user gets sent to index.php, but they lose the giveaway querystring because you're not using [QSA].
Solution
Try:
# If requested resource exists as a file or directory, go to it
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*) - [QSA,L]
Don't forget [QSA] to keep the querystring, if present.
You should add it to the final rule, too:
# Else rewrite requests for non-existent resources to /index.php
RewriteRule (.*) /index.php?url=$1 [QSA]
Suggestion
Are you sure you want to do no-op rewrites? That's a bit odd.
How about negating the logic and combining those two rules? Like so:
# If requested resource doesn't exist as a file or directory, rewrite to /index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) /index.php?url=$1 [QSA,L]
Mod_rewrite documentation. Search for QSA