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.
Related
I created my website with some files in htdocs folder, such as: .htaccess, web.php ... In past, I used an old URL structure for my website: old.php?id=12. Then, I have used a new one: new/12, by using this simple .htaccess:
RewriteEngine On
RewriteRule "^new/([0-9]+)/?$" "/old.php?$1"
And now, I do not want any user can access my website with old URL structure. Could you show me: How to rewrite URL and return 404 for original links?
Try this:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^new/(\d+)*$ ./old.php?id=$1
The best solution, especially for SEO, is to make a redirect 301:
RewriteEngine on
# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} \s/+old\.php\?id=(\d+) [NC]
RewriteRule ^ /new/%1? [R=301,L,NE]
# internal forward from pretty URL to actual one
RewriteRule ^new/(\d+)/?$ /old.php?id=$1 [L,QSA,NC]
To get a real 404 effortlessly, the simplest is to change your hidden page name to new.php (also in htaccess) and delete the old.php page.
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
I have a website that was updated. I want to make the old urls work, I want to redirect some of them, so links from google search still work, and rewrite the url for other urls, using .htaccess.
For example:
one rewrite is a.com/services to a.com/consultancy
one redirect is a.com/services/a/b to a.com/consultancy
One extra comlpication: the site sends every request to /index.php because the URLs are not to physical files, but the index.php script does internal routing, using the requested path, to serve the right content.
I'm not sure if I can do a rewrite (services->consultancy) an then another rewrite (consultancy->index.php) in the same htaccess.
Trying this, I'm getting an internal server error 500 for any URL:
RewriteEngine On
#NEW
RewriteCond %{REQUEST_URI} ^services$ [NC]
RewriteRule ^services$ consultancy [L]
#LEGACY
RewriteRule (.*) ./index.php
Also tried the Redirect 301 directive but had no luck, the same error 500.
Any ideas of how to mix rewrites, redirects and the final rewrite to index.php?
Thanks!
Update
For the combination of redirect and rewrite I realized some of the rules are a little different than my original question, and those might be causing problems, here is an example:
# Redirect to show "consultancy" in the URL
RewriteRule ^services/a/b?$ consultancy [QSA,R,L,NC]
# If "consultancy" is in the URL, change it to the real path
# "consultancy" is an alias of the path that should be processed by index.php
RewriteRule ^consultancy/?$ en/consultoria [NC]
# Should get the "en/consultoria" path
RewriteRule ^ ./index.php [L]
The problem with the previous example is that I get the redirect "services/a/b" -> "consultancy" OK, but the rewrite "consultancy" -> "en/consultoria" is not done.
Any ideas?
You can use:
RewriteEngine On
#rewrite
RewriteRule ^services/?$ consultancy [L,NC]
#redirect
RewriteRule ^services/a/b/?$ consultancy [L,NC,R=302]
#LEGACY
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
I have the following .htaccess file:
RewriteEngine on
Options +FollowSymLinks
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule (.*)$ ./page.php?name=$1
I also have about 20 different static addressess I want to do a 301 redirect to.
It should look something like:
Redirect 301 http://www.example.com/category.php?id=3 http://www.example.com/books
Redirect 301 http://www.example.com/articles.php?id=124 http://www.example.com/birds
I tried every method and failed.
Can somebody help me?
I'm guessing your after a set of SEO friendly URL's for those in your redirect examples, if this is the case then you don't want a browser redirect, instead you want an Internal Redirect or Alias e.g.
RewriteRule ^/?books /category.php?id=3 [L]
RewriteRule ^/?birds /articles.php?id=124 [L]
If you have many rules and have access to the httpd.conf you may want to consider a rewrite map file and rule.
Per your comment BELOW, if you want to force users/crawlers to the new URL structure then you'll need an additional set of Rewrite rules in the file (not redirects) e.g.
RewriteCond %{THE_REQUEST} /category\.php [NC]
RewriteCond %{QUERY_STRING} ^id=3 [NC]
RewriteRule ^.* http://%{HTTP_HOST}/books? [R=301,L]
FYI: The Apache mod_rewrite documentation is worth a read if your unclear as to what the above rules do, or if you want something a little more abstract consider the following post.
Dear folks,
Imagine a One Page Site
RewriteCond %{HTTP_HOST} ^1pagesite.org$
RewriteRule ^$ 1pagesite.php [L]
Currently, the home page does present the 1pagesite.php correctly.
However, when another file is requested say, test.php which is on the server indeed, that test.php is shown!, while I would like to point ALL and ANY trafic towards 1pagesite.php for the time being. How to make this happen sothat no other file or folder/file or anything after this domain is presented and everything is directed towards 1pagesite.php?
Thanks very much for hints and suggestions to solve this puzzle. Cheers, Sam
RewriteRule ^.*(html|php)$ 1pagesite.php [L]
Note: This redirects only request to .html and .php pages
Can you try this rule:
RewriteCond %{HTTP_HOST} ^1pagesite.org$ [NC]
RewriteCond %{REQUEST_URI} !1pagesite.php$
RewriteRule \.(php|html)$ /1pagesite.php [R=302,L]
to redirect only php and html pages to 1pagesite.php
Your redirection only match ^$ that is to say only the root page (empty string).
RewriteCond %{HTTP_HOST} ^1pagesite.org$
RewriteRule ^.*$ 1pagesite.php [L]
So every request will be redirected to 1pagesite.php page (images, css, ... as Sander said).
If you need to filter some content you can add a
RewriteCond %{REQUEST_FILENAME} !^.*\.(css|jpg)$
to enable .css and .jpg file from your / directory to be served. This can be customized for other subdirecories files etc...