I am using pretty url for my project and it is working fine.
http://testurl.com/user/12345
I am using .htaccess for redirection.
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \s/user\.php\?id=([0-9]+)\s [NC]
RewriteRule ^ user/%1? [R=301,L]
RewriteCond %{THE_REQUEST} \s/user\.php\?id=([0-9]+)&name=([^&\s]+)\s [NC]
RewriteRule ^ user/%1/%2? [R=301,L]
RewriteRule ^user/([0-9]+)/?$ user.php?id=$1 [L]
RewriteRule ^user/([0-9]+)/([^/]+)$ user.php?id=$1&name=$2 [L]
Today i found if i change the link in browser like this http://testurl.com/user.php then page is also loading i want to show error message (Alert) if someone directly trying to access
The best way is to add your error or redirect in the user.php without id query string.
But you also can add (after RewriteBase /):
RewriteCond %{THE_REQUEST} \s/user\.php\s [NC]
RewriteRule ^ - [F]
You might as well solve your problem through code reorganization. I did this in one of my projects, and it has worked well.
1. When you create a pretty URL, move the according file into another directory
So, in this case, you had the URL example.com/user.php?id=123 visible externally. Now, you want a pretty URL for it, e.g. example.com/user/123.
On file level, before you had
- user.php
I suggest you move that to another directory, where all scripts live which are accessed by pretty URL only:
- rewrites/
|- user.php
2. Create redirects for your old URL to your new URL, externally
The same as you did above.
RewriteCond %{THE_REQUEST} \s/user\.php\?id=([0-9]+)\s [NC]
RewriteRule ^ user/%1? [R=301,L]
RewriteCond %{THE_REQUEST} \s/user\.php\?id=([0-9]+)&name=([^&\s]+)\s [NC]
RewriteRule ^ user/%1/%2? [R=301,L]
3. Rewrite the new, pretty URL to moved script, internally
The same as you did above, with difference that the directory name rewrites is added.
RewriteRule ^user/([0-9]+)/?$ rewrites/user.php?id=$1 [L]
RewriteRule ^user/([0-9]+)/([^/]+)$ rewrites/user.php?id=$1&name=$2 [L]
4. example.com/user.php now fails with a 404
Because /user.php does not exist anymore in the file system, it automatically fails with a 404 if called without params.
5. Benefits
This approach might sound like additional work for nothing, but these are the benefits making it worthwile in my opinion:
You do not need an additional .htaccess rule for error handling
You get better code organization
You get better overview of what is already accessible with pretty URL
Related
Part 1 takes care of making example.com/fr behave like example.com?lang=fr, or example.com/fr/some-page.php like example.com/some.page.php?lang=fr etc.
Part 2, which I'm currently working on not working well yet, is to obtain a new GET param for other pages called page, in this case if there's login in the url.
Problem: It seems like part of the page loads twice when going to for example example.com/login or example.com/fr/login.
Maybe un-necessary details here but for instance it says Facebook Pixel Error: Duplicate Pixel ID:, and similar errors for other tags I use like Mixpanel, and then my JS just stops working. That's all I can say about the problems I see on my side. Best chance seems to be about looking for flagrant errors in the htaccess rules.
What should be fixed in the rules so the end goal of having the GET param page and lang work fine?
RewriteEngine On
# Part 1
RewriteCond %{THE_REQUEST} \s/+[^?]*\?lang=([^\s&]+)\s [NC]
RewriteRule ^ /%2/%1? [R=301,L,NE]
RewriteCond %{REQUEST_URI} !^/js/
RewriteRule ^([a-z]{2})(?:/([^/]+))?$ $2?lang=$1 [NC,L,QSA]
# Part 2 (this is the part I am adding, which isn't fully working well yet)
# anything looking flagrantly wrong? If for example we are on `example.com/fr/login`,
# according to rules in this htaccess file we should have 2 GET params, `lang` and `page`.
RewriteCond %{REQUEST_URI} login
RewriteRule .* index.php?page=login
# adding more pages the same way
RewriteCond %{REQUEST_URI} signup
RewriteRule .* index.php?page=signup
You can use the following rule as your Part1
RewriteEngine on
RewriteRule ^(en|fr)/login/?$ /index.php?page=login [L]
RewriteCond %{THE_REQUEST} \?lang=([^&]+)\sHTTP
RewriteRule ^ /%1%{REQUEST_URI}? [L,R]
RewriteRule ^(en|fr)/?(.*\.php)?$ /$2?lang=$1 [L]
I have an issue writing some regex to go inside my htaccess file.
Basically, my site has been setup so that index.php and all other site files are not in the root (public_html) directory but instead are in http://fitnessquiz.co.uk/fitnessquiz.co.uk/
Initially I tried the following in my public_html folder:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^fitnessquiz.co.uk$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www.fitnessquiz.co.uk$
RewriteCond %{REQUEST_URI} !fitnessquiz.co.uk/
RewriteRule (.*) /fitnessquiz.co.uk/$1 [L]
which correctly navigates to my homepage and displays the url correctly but then when I click any link I get a "no input file specified" message. So then I tried replacing with:
RewriteCond %{REQUEST_URI} !^/fitnessquiz.co.uk/
RewriteRule ^(.*)$ /fitnessquiz.co.uk/$1 [L,R=301]
After which the site works but every url looks like this:
http://fitnessquiz.co.uk/fitnessquiz.co.uk/someotherfolder/etc.php
I've tried various htaccess regex solutions listed elsewhere on here but none seem to work, how do I accomplish both of these things i.e. redirect to /fitnessquiz.co.uk for every url but hide the duplicate url name/folder. Im on a shared server so don't have permissions to change any server/apache settings directly.
According to this answer by nuked on a previous post you could try:
RewriteCond %{THE_REQUEST} ^GET\ /fitnessquiz.co.uk/
RewriteCond %{HTTP_HOST} ^(www\.)?fitnessquiz.co.uk$
RewriteRule ^fitnessquiz.co.uk/(.*) /$1 [L,R=301]
RewriteCond %{HTTP_HOST} ^(www\.)?fitnessquiz.co.uk$
RewriteRule !^fitnessquiz.co.uk/ fitnessquiz.co.uk%{REQUEST_URI} [L]
This set of rules worked for me on a very similar situation. I had employed the same cure, (re-direct if calling the folder and hide after re-writing it) but I never got the order right on my own. Thus I kept seeing the page not found errors too. Below is my attempt to explain the actions, for my own learning, hopefully others too.
RewriteCond %{THE_REQUEST} ^GET\ /fitnessquiz.co.uk/
Is asking the question, does THE_REQUEST contain the subfolder you need to hide?
RewriteCond %{HTTP_HOST} ^(www\.)?fitnessquiz.co.uk$
Checks if the request is for the correct host.
RewriteRule ^fitnessquiz.co.uk/(.*) /$1 [L,R=301]
Rewrite the URL as one without the subfolder and call the new link in the redirected browser. Note:
L : Last step. Stop processing other rules
R=301 : After re-writing, redirect the browser to the new URL.
When the page is redirected it has no subfolder so the first RewriteRule is skipped. And then
RewriteCond %{HTTP_HOST} ^(www\.)?fitnessquiz.co.uk$
checks if calling the right host. And then
RewriteRule !^fitnessquiz.co.uk/ fitnessquiz.co.uk%{REQUEST_URI} [L]
rewrites the url that has not the subfolder to use the correct subfolder without redirecting the page, and while hiding actual subfolder from the browser. Again note:
L : Last step. Stop processing other rules
I am having a little issue forcing the .php file extension to be removed in the URL.
I am successfully able to remove .php file extension if user:
#Remove PHP if original request is /foo/bar.php
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule ^(.*)\.php(\?.*)?$ $1$2 [R=301,L]
My goal is to get it also to remove the extension if:
# Remove PHP if original request is /foo.php/bar
I ask because right now a user can go to the URL and type http://www.site.com/contact.php/about and it will render my about page. My goal is force the removal of the .php and render:
http://www.site.com/contact/about
I was hoping to take the code I have above and add it to but I can not figure it out.
TIA
It looks like you got the removing part, but you're missing the internally rewriting part. What you have attempts to remove the php out of the URL and redirects the client to a URL without it. But your condition isn't matching requests, change it to:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ .*\.php.*$
RewriteRule ^(.*)\.php(.*)?$ /$1$2 [R=301,L]
Then you need to internally rewrite it back (don't redirect browser). So in the same htaccess file, add:
RewriteCond %{REQUEST_URI} ^/([^/]+)(.*)$
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^([^/]+)(.*)$ /$1.php$2 [L]
the following .htaccess gives me the requested parameters, you can get "page"
AddDefaultCharset utf-8
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .* - [L]
DirectoryIndex index.php
RewriteRule ^([a-zA-Z0-9_-]{3,20})/([^/]+)/([^/]+)?$ index\.php?page=$1&s=$2&o=$3 [L]
RewriteRule ^([a-zA-Z0-9_-]{3,20})/([^/]+)?$ index\.php?page=$1&s=$2 [L]
RewriteRule ^([a-zA-Z0-9_-]{3,20})/?$ index\.php?page=$1 [L]
RewriteRule ^([a-zA-Z0-9_-]{3,20})?$ index\.php?page=$1 [L]
ErrorDocument 404 /404
Get "page" parameter and then call it like this
include('inc/'.$_REQUEST['page'].'.php');
and remember to remove .php ext from your links
Replace your tow lines with this single one : (you have an error in your rule, that's why it is not detecting .php in the middle and you don't need the rewrite condition)
RewriteRule ^(.+)\.php(/.*)?$ /$1$2 [L,R=301]
My solution for these problems is to basically avoid using complex rewrite rules and do URL routing from the php side, via a simple front controller.
Write the following .htaccess file at the root of your website:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]
Then write an index.php file in the same directory.
In the index.php file, you can still get the whole URL information, and choose a PHP file to include based on this.
<?php
// urldecode and get rid of the query string, $_GET is still available
$url = urldecode(preg_replace('/\\?(.*)$/', '', $_SERVER['REQUEST_URI']));
if ($url == '/contact/about') {
include 'contact.php';
}
That example is extremely basic, and I am probably ignoring subtleties of your website's architecture, but this approach is much more viable in the long run, because you can really map any URL of your liking to PHP scripts without having to endure the complexity of mod_rewrite.
This is the pattern that has been adopted by virtually every existing PHP framework (at least the MVC ones).
An minimalist example of this approach can be found in the Slim micro framework: http://www.slimframework.com/
I've been struggling with my mod_rewrite for a while now and I thought I'd cracked it…
My CMS generates blog post URLs with post.php?s= and I've been trying to remove this part of the URL so that they're nice and user friendly. Here's my mod_rewrite:
<ifModule mod_rewrite.c>
DirectoryIndex index.php index.html
ErrorDocument 404 http://tempertemper.net/error.php
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^www.tempertemper\.net$
RewriteCond %{REQUEST_URI} !cron.php
RewriteRule ^(.*)$ http://tempertemper.net/$1 [R=301,L]
RewriteCond %{QUERY_STRING} ^s=(.+)$
RewriteRule post.php /%1? [R=301,L]
RewriteRule ^resources /archive? [R=301,L]
RewriteCond %{REQUEST_URI} !post.php
RewriteRule ^([a-zA-Z0-9_-]+)$ post.php?s=$1
</ifModule>
Unfortunately, It seems to be directing all pages that aren't found to the blank post.php page instead of the error.php page.
My site is here: http://tempertemper.net and here's a URL that doesn't exist http://tempertemper.net/this-url-does-not-exist
It should take you to http://tempertemper.net/error
Thanks for taking a look :)
Because you are redirecting all paths which fit the [a-zA-Z0-9_-]+ pattern, this will simply send to your post.php script the query string s=this-url-does-not-exist. So it's up to your PHP script post.php to check whether this-is-not-a-url exists or not, as Apache cannot possibly know what blog post ID values are valid and which are not.
As a side note, I'd recommend using /blog/2012-08-24-whatever as the path you give to visitors, rather than /2012-08-24-whatever. That way you can reserve paths for other functions, such as /images without having to write a new exception in your .htaccess file every time you need to create a new utility path.
I read this .htaccess rewrite to redirect root URL to subdirectory and i'm trying to achieve the same things.
The solution with most up votes was:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
RewriteRule ^$ store [L]
Now, looking at the comments it seems to be working good.
The problem is that I'd like not to hardcode any path (as instead provided above "www.example.com"). I'd like that my .htaccess inside projectname/ redirects to projectname/public/ despite what the real server host is. So that if I put projectname/ inside the root server of www.pinco.com it redirects to www.pinco.com/projectname/public/ but it shows www.pinco.com/projectname/.
How can I achieve that?
The example you found is actually doing two different things.
# This is actually just redirecting all http://example.com/somepage/
# to http://www.example.com/somepage/, to ensure all URLs have the www.
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
The second rewrite is what will help you achieve what you're trying to do.
# This redirect all requests for http://example.com -> http://example.com/newdir
# If you are looking to redirect the request, so the URL contains directory name,
# you can change the [L] to [R=301,L]
RewriteRule ^$ /newdir [L]
# If your concerned about direct access to a particular page without the sub-dir
# you will want to add something like this
RewriteCond %{REQUEST_URI} !^/newdir
RewriteRule (.*) /newdir$1 [R=301,L]
So, in that case, you won't have to be concerned with domain that the application is running on.
try to add this line, and :
RewriteBase /projectname
And you stay inside the project.