how can i auto redirect a site from dirty url to clean url in php , something like
http://www.mysite.com?page=page1&action=action1
to
http://www.mysite.com/page1/action1
You have to check if it was clean request or not.
Otherwise you will fall into infinite loop
Here is an example from one of my projects:
.htaccess
RewriteEngine On
RewriteRule ^game/([0-9]+)/ /game.php?newid=$1
game.php
if (isset($_GET['id'])) {
$row = dbgetrow("SELECT * FROM games WHERE id = %s",$_GET['id']);
if ($row) {
Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location: /game/".$row['id']."/".seo_title($row['name']));
} else {
Header( "HTTP/1.1 404 Not found" );
}
exit;
}
if (isset($_GET['newid'])) $_GET['id'] = $_GET['newid'];
So, you have to verify, if it was direct "dirty" call or rewritten one.
And then redirect only if former one.
You need some code to build clean url too.
And it is also very important to show 404 instead of redirect in case url is wrong.
If you are running Apache you can use the mod_rewrite module and set the rules in a .htaccess file in your httpdocs folders or web root. I don't see any reason to invoke a PHP process to do redirection when lower level components will do the job far better.
An example from Simon Carletti:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/page\.php$
RewriteCond %{QUERY_STRING} ^id=([0-9]*)$
RewriteRule ^(.*)$ http://mydomain.site/page/%1.pdf [R=302,L]
try
header("Location: http://www.mysite.com/".$_GET['page']."/".$_GET['action']);
you should check whether the values are set before trying to redirect
Related
I wonder if it's possible to redirect 2 different domains vice versa. Suppose I have 2 domains such as www.abc.com and www.xyz.com. Now if any viewer clicks www.abc.com, it should redirect them to www.xyz.com and when any viewer will click www.xyz.com, they will be redirected to www.abc.com. Is there any feature or hosting service that can do this? I know redirection can be simply done using PHP header('Location') but once I did that, it will be redirected to the location site, there's no way to get the original site. Can anyone please help? Thanks.
Assuming that when going www.xyz.com we wants to redirect user to www.abc.com and when going to www.abc.com we wants to redirect user to www.xyz.com
By using the sessions, we can do.
<?php
//on abc.com
session_start();
if(!isset($_SESSION['abc']) || $_SESSION['abc'] != true ){
$_SESSION['xyz'] = true;
header('Location: www.xyz.com');
}
now,
<?php
//on xyz.com
session_start();
if(!isset($_SESSION['xyz']) || $_SESSION['xyz'] != true ){
$_SESSION['abc'] = true;
header('Location: www.abc.com');
}
First I would make a strong case not to do this with your client. But... using .htaccess, we can set a query string flag with the redirect to prevent an infinite redirect loop.
If the address is for www.abc.com we redirect to www.xyz.com only if the flag (signaling that we weren't already redirected) doesn't exist
This is untested, but the concept will work.
RewriteEngine On
#abc => xyz
RewriteCond %{HTTP_HOST} ^www\.abc.com
RewriteCond %{QUERY_STRING} !^flag=fromxyz$
RewriteRule ^(.*)$ www.xyz.com?flag=fromabc [L,R=301]
#xyz => abc
RewriteCond %{HTTP_HOST} ^www\.xyz.com
RewriteCond %{QUERY_STRING} !^flag=fromabc$
RewriteRule ^(.*)$ www.abc.com?flag=fromxyz [L,R=301]
You can also accomplish the same thing with php - by appending a query string to the redirect and testing for it before the header() redirect. Something like:
if ($_SERVER[HTTP_HOST] == "www.abc.com"){
if ($_SERVER[QUERY_STRING] !== "flag=fromxyz"){
header("Location: www.xyz.com?flag=fromabc.com");
die();
}
}
if ($_SERVER[HTTP_HOST] == "www.xyz.com"){
if ($_SERVER[QUERY_STRING] !== "flag=fromabc"){
header("Location: www.abc.com?flag=fromxyz.com");
die();
}
}
The .htaccess method will be more efficient as the server won't have to load a php file before redirecting.
Also, the use of $_SESSION variables is an option as mentioned by #AnimeshSahu. However, they may not be supported in all cases (e.g. Googlebot)
You can use the referer
RewriteCond %{HTTP_REFERER} !.abc.com.$
RewriteRule ^(.*)$ www.xyz.com/$1 [L,R=301]
Says if the referer is not ABC.com then redirect.
Not tested but should work as the 301 will include the referer
I want to redirect this URL:
http://example.com/main2.php?t202id=2483&mnin=pubd&t202kw=[zone]
to
example.com/newpage.php
but only if the visitor hit the URL with [zone] at the end of the URL and in case he visits a URL like this:
example.com/main2.php?t202id=2483&mnin=pubd&t202kw=XXXXXXXX
he must NOT be redirected.
If you really want to use htaccess rather than php:
RewriteEngine On
RewriteCond %{QUERY_STRING} ".*t202kw=\[zone\].*"
RewriteRule ^ http://example.com/newpage.php [R=301,L,QSD]
This is probably easier done in the PHP script than with htaccess. Something like this at/near the top of the main2.php script:
if ($_GET['t202kw'] == "[zone]") {
header("Location: /newpage.php");
http_response_code(301); // this is the HTTP code for "Moved Permanently" -- change to 302 if this redirect is only temporary
exit();
}
I have an 301 redirect form oldPage.php to newPage.php in htaccess:
RedirectMatch 301 ^/oldPage.php$ /newPage.php
Now I would like forceOldPage.php to be redirected to oldPage.php (without being redirected to newPage.php)
Is it possible? How can I do that?
First remove your .htaccess redirect and instead redirect in oldPage.php if the referer isn't forceOldPage.php.
Something like this at the top of oldPage.php is a good start, adjust and refine as required.
<?php
// If the referring page isn't "forceOldPage.php"...
if ( !strpos( $_SERVER['HTTP_REFERER'], 'forceOldPage.php' ) ) {
// ...301 redirect to "newPage.php"
header( "HTTP/1.1 301 Moved Permanently" );
header( "Location: /newPage.php" );
die();
}
?>
One possibility is to assume "force" (choose any string) will not be part of the query string on any page going to oldPage.php. Use RewriteCond and RewriteRule. Then redirect forceOldPage.php to oldPage.php?force.
RewriteEngine on
RewriteCond %{QUERY_STRING} !force
RewriteRule oldPage.php newPage.php [R=301]
RedirectMatch 301 ^/forceOldPage.php$ /oldPage.php?force
FYI: I tried using HTTP_REFERER as a way to detect if user came from forceOldPage. However, the referer is not passed to new page on redirect (in my environment at least).
I have a blog www.SITE_NAME.com which is hosted in blogger.com, Its almost 4 year old and have better search engine ranking. Most of the traffic came through Google. Now i am redesigning my site in drupal.
So i want to redirect all older links with a 301 to new pages , Since i have nearly 700 pages , i want some logic to apply (and some case i want to redirect manually) . Which is better, using Apache or php? Or any other suggestion?
Note : since my old site is in blogger.com, its path is something like this www.SITE_NAME.com/2007/08/music.html and my new path will be like www.SITE_NAME.com/DYNAMIC_PATH
if we are talking about performance, - then defiantly .htaccess/apache will be better/faster. if you wanna implement some logic on redirect, when probably it will be easier to do with php, using headers.
These scripts should be placed in the .htaccess file.
//*301 Redirect: xyz-site.com to www.xyz-site.com
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www.xyz-site.com$ [NC]
RewriteRule ^(.*)$ http://www.xyz-site.com/$1 [L,R=301]
//*301 Redirect: www.xyz-site.com to xyz-site.com
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^xyz-site.com$ [NC]
RewriteRule ^(.*)$ http://xyz-site.com/$1 [L,R=301]
//*301 Redirect: Redirecting Individual pages
Redirect 301 /previous-page.html http://www.xyz-site.com/new-page.html
Or you can use
Redirect with PHP
<?php
Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location: http://www.xyz-site.com" );
exit(0);
?>
Definitely use the 301. It lets search engines know that the site is moved permanently and should transfer any "link weighting" from the old URL to the new one. Check out this info from Google Webmasters
And this about redirecting tons of links
Sorry I can't post comments yet. If the domain is the same, you should "bild" same site structure (same permalinks) and I guess use something like this:
http://drupal.org/project/blogger_importer
Then you should not use any redirects at all.
When my client adds a page to the site, the new pagename should be appended to a RewiteRule regex. So with, for instance fwrite(), I would like PHP to change that RewiteRule regex with values retracted from the database. If this could be done, are there any pitfalls in the process?
Edit: handling in a PHP script would be the solution, if there would'nt be more to it...
First domain/index.php?page=pagename is 301 redirected to "domain/pagename"
to warn the visitor this page is permanently moved - (this is the old
PUBLIC location of the URL and should give this 301). Then requests
like "domain/pagename" (the new public location), would be
silently,internally rewritten to domain/index.php?page=pagename where
verification takes place and a 404 is given when not valid. But just
the key, the "page" part of ?page=pagename, is static and can be
verified and will give a 404 directly from within the .htaccess . Now,
requests like domain/index.php?page=crap will first nicely give a 301
like the valid domain/index.php?page=pagename does, and only when
arrived in the index.php can be identified as crap. So there is still
a need to get the pagenames from the database to inside the .htaccess.
This is a sample of the .htacces content to give some background to this problem:
ErrorDocument 404 http://localhost/testsite/404.php
RewriteEngine on
RewriteBase /testsite/
## block craprequests without extension like domain/crap > 404
# The requests domain/pagename that do not go to existing pages, will now be redirected with a 302 to index.php?page=pagename and only then give a 404 through the errorcheck in the code.
# This should be done here, with a RewriteCond regex with database content
RewriteCond %{REQUEST_URI} !404.php$
RewriteRule .* 404.php [R=404,L]
## block-direct-queries ##
RewriteCond %{QUERY_STRING} !marker=1$
RewriteCond %{QUERY_STRING} page=(.*)
RewriteRule ^.*$ %1? [R=301,L]
## strip-extensions ##
RewriteCond %{QUERY_STRING} !.
RewriteCond %{REQUEST_URI} !404.php$
RewriteRule ^([\w+%*\d*\+*\-*]+)\.(php[\s]{0,3}|htm[\s]{0,3}|html[\s]{0,3})$ $1 [R=301,L]
## put-querystring
RewriteRule ^([\w\-_]+)\/?$ index.php?page=$1&marker=1 [L]
I'm sorry to keep repeating this back to you, but there just isn't a need for storing the page name in the .htaccess. This can all be done much more simply in PHP.
The only rewrite rule you need is this:
RewriteCond %{REQUEST_URI} !^/?index\.php$
RewriteRule .* /index.php [L,QSA]
Now, in PHP, you can do something like this:
// The important point here is that $_SERVER['REQUEST_URI'] contains the actual
// path the user typed into their browser, which is what you are interested in
if (strtolower(basename(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))) === 'index.php') {
// The user directly requested index.php
if (!empty($_GET['page']) || value_of_page_is_crap()) {
// The user requested a bad page
header("{$_SERVER['SERVER_PROTOCOL']} 404 Not Found");
} else {
// Redirect to correct URL
header("{$_SERVER['SERVER_PROTOCOL']} 301 Moved Permanently");
header("Location: http://{$_SERVER['HTTP_HOST']}/{$_GET['page']}");
}
exit;
}
// The request is allowed to continue
$requestedPage = pathinfo($_SERVER['REQUEST_URI'], PATHINFO_FILENAME);
The .htaccess will route every single request blindly through PHP, where much more precise logic than mod_rewrite's clunky PCRE-based rules can be used.
The PHP script examines the URI the user typed into their address bar in the browser. If they directly requested index.php, it will check whether $_GET['page'] contains a sensible value and if it does, redirect them to the correct URL, if not respond with a 404. If the user did not request index.php directly, the script can continue. I have added an example line to show how you could extract the value of the page they requested, but how you continue on from here is up to you.
This will most likely be possible (although writing permissions may be an issue). However wouldn't it be a better way to route all requests from the client through the index.php file and let PHP handle the routing.
This way you will be maximum flexible and you don't have to do "hacky" stuff.
EDIT
All forms of redirect can be done from PHP. E.g. an example of a 301 redirect:
header ('HTTP/1.1 301 Moved Permanently');
header ('Location: http://example.com/new/path'); // note the full address
exit();
Please see the manual for more information about the use of header().