PHP die(header): Messing up my SEO? - php

I have this bit of code at the beginning of my index.php file:
if ( !isset($_GET['cat']) )
die(header("Location: ?cat=top"));
Basically, if there is no category set, it automatically redirects to category "Top".
I have now noticed that Google added index.php, but it only displays the URL in the search results, instead of displaying the meta tags I've defined.
All the other pages are indexed perfectly fine, just not the index.php file. Any solution for this?
Thanks in advance!

PHP uses per default a 302 redirect when using header: Location.
This messes up with SEO as google doesnt swap the redirected location with the inital one. Try using
if ( !isset($_GET['cat']) ) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: ?cat=top");
die();
}
This should tell google to index the redirected location which has the meta info.

Function die is capable of printing out the text/string data, I have never seen calling a header within die.
The right approach should be:
if ( !isset($_GET['cat']) ) {
header("Location: ?cat=top");
die();
}
You can call exit; instead of die();.

I think there is no need of calling die() function. you can just call like
if ( !isset($_GET['cat']) )
header("Location: ?cat=top");

Related

Fix a redirect loop?

I have the following code in my index.php page:
<?php include("/includes/widgets.php") ?>
And in my widgets.php page:
<?php
header("Location: /");
?>
What I want to achieve with this is to redirect it if the user visits it, but allow it for including.
But I get the following error:
The webpage has a redirect loop
How can I fix/prevent the redirect loop, but still redirect the user and not the server.
Place the widgets.php file in a folder not accessible to HTTP clients. I.e on apache webserver, either put it above your document root (into it's parent) or use .htaccess file to block users from it.
e.g.
deny from all
I think I know what you need :)
Change code index file to next
define("IS_INDEX", true);
include("/includes/widgets.php"
Change code for widgets.php to next
if (!defined("IS_INDEX")) {
header("Location: /");
exit();
}
The issue is you are redirecting back to the same page, which then redirect again, and again, and again.
An easy fix would be to wrap the redirect in an if, and only redirect if they aren't already on the index page; but this is just patching what looks like an architectural problem.
Something like:
if (ltrim($_SERVER['REQUEST_URI'], '/') != 'index.php')
header('Location: index.php');
One way is to check if __FILE__, which is the file loaded, regardless of included or not matches up with the file requested which is in $_SERVER['REQUEST_URI'] (or $_SERVER['PHP_SELF']).
I use this on our development site in a page that is usually included to get the output as debugging.
if(basename($_SERVER['PHP_SELF'])===basename(__FILE__)){
//do some debugging
}
Typically you wouldn't use basename, but this is on a non-public facing development site and the file has a pretty unique name so I'm not worried about the file being included with another file with the same name or anything.
One possible way is to add a parameter to the redirection, e.g.
if (!$_REQUEST['redirect'])
header("Location: /ìndex.php?redirect=1");
That way redirection can happen only once.
Another way is to stop redirection if the user already is on the /. I´d suggest to combine both.

PHP: Best redirect technique

I'm currently using the excellent mobile detection script from: detectmobilebrowsers.mobi
This works really well however, it redirects every and any page on your main site (including any query parameters) to your mobile site's home page.
What I need is:
http://www.mydomain.com/page.php?var1=X&var2=Y
to direct to:
http://mobile.mydomain.com/page.php?var1=X&var2=Y
I have multiple pages that should redirect with the query string to their mobile versions.
What's the best way to approach this? I thought that I should:
Examine the $_SERVER['HTTP_REFERER'] for the page and query string, use a switch/case to loop through the 10 or so pages that I need matching on the main and mobile sites then change the referer URL in the mobile detection script.
Does this make sense?
I've been struggling to get the page and query... any advise and thoughts welcome.
if ($mobile_is_detected) {
header('Location: http://mobile.mydomain.com' . $_SERVER['REQUEST_URI']);
exit;
}
In addition to Andy's answer, when redirecting you should set the response status to 301.
Be careful, you may not call header() if you have printed any HTML or echoed anything before calling the function.
if ($mobile_is_detected) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://mobile.mydomain.com' . $_SERVER['REQUEST_URI']);
}
You can use $_SERVER['QUERY_STRING'] to redirect to add the query string to the redirect URL in the first place.

PHP & jQuery .load() - If you visit the .load() URL, redirect back

I am using jQuery load, to load some data from an external file like this:
$("#div1").load("test.php");
Now this works fine but I want users not to be able to visit test.php. In case they type in the URL test.php, get redirected to index.php
I tried this:
I inserted in my index: <? $fromIndex = true; ?> and this in my test.php file:
<?
$fromIndex = true;
if(!isset($fromIndex) || !$fromIndex) {
header("Location: index.php");
exit();
}
?>
The redirection works great if you visit test.php but the load doesn't work from index.php.
EDIT: Note: I wouldn't mind changing the test.php to .xml ? Or anything else that would help. The content I'm loading is few <option>'s
Can someone help me please?
Thanks alot
There's not really a way for you to prevent a user visiting a URL directly, and yet still allow AJAX access to that same URL. A simple way to dissuade them, though, would be to either A) send the response back as a JSON object (which makes it pretty useless when accessed directly), or B) append a GET parameter to the URL and perform your redirect when that parameter is absent.
$("#div1").load("test.php?ajax=1");
and
<?
if( !isset( $_GET['ajax'] ) || $_GET['ajax']!=1 ) {
header( "Location: index.php" );
exit();
}
?>
jQuery's AJAX functions all send a X-Requested-With header with the contents XMLHttpRequest. You can use this to do what you want, but don't use it as an anti-abuse feature - it's trivially defeated. It should only be used to be helpful to users who stumble across the URL, or to present them with a helpful error page instead of say, a JSON feed.

Setting a variable and using header()

I'm developing a custom content management script, and I'm working on page redirection.
The code below compares the URL code to the URL for the a certain page ID in the database, and if the two URLs are not the same, the user is redirected.
However, I want to add a variable, so that we can check if the page has been redirected or not. It isn't working.
if (isset ( $_GET ['id'] ) && $rawdata) {
if ($_SERVER ["REQUEST_URI"] != $rawdata ['htmltitle']) {
header ( "HTTP/1.1 301 Moved Permanently" );
header ( "Location: http://${_SERVER['SERVER_NAME']}:${_SERVER["SERVER_PORT"]}${rawdata['htmltitle']}" );
$redirected = true;
;
}
}
if ($redirected == true) {
print_redirect_nonexpected ();
}
function print_redirect_nonexpected (){
echo "<!-- REDIRECTED _ NOT _ EXPECTED ? -->";
}
The function isn't being run, so no echoing.
Any ideas what I'm doing wrong here?
Use this:
header ( "Location: http://".$_SERVER['SERVER_NAME'].$_SERVER['SERVER_PORT'].$rawdata['htmltitle']);
If $rawdata['htmltitle'] is full URL of your page, use this:
header ( "Location: http://".$rawdata['htmltitle']);
And also adding die() after header() is good.
When you send a Location: header, the user-agent stops loading the current page and loads whatever page you tell it to load, so you'll never see the output.
However, your code may* continue to execute in the background, so usually you want to follow your header() with an exit; to prevent unwanted behavior.
* Depends on server configuration and on ignore_user_abort.
Also, header("Location: /{$rawdata['htmltitle']}"); will suffice. Since you are redirecting to the same server, an absolute path suffices. Don't overcomplicate your redirects for nothing with $_SERVER variables.
As soon as the Location header is sent the browser will abort the current operation and fetch the page at the redirected location. This means that for all intents and purposes a location ('header: example.com') will have essentially the same effect as a die (). You can override this behaviour by using output buffering, or you can move the header() calls to lower down in your script. However you can't move them to after the print_redirect_unexpected call, as sending any output to the browser will cause all headers to be sent as well and you won't be able to send any more.
So basically, you need to turn on output buffering.

PHP 301 Redirect Idea

I posted this earlier
301 Redirect of Static HTML to Dynamic PHP Page
But have a new idea, and am wondering if there are any issues why I should NOT do this...
If someone tries to go to a dead page on our site like:
(domain)/somepage.html
That now exists here:
(domain)/dynamic.php?id=1
It fails and goes to a custom Error 404 page (/404.php)
If I look at the $_SERVER['REDIRECT_URL'] variable, I can see where they were trying to go. My idea is to add an include at the top of the 404.php page to check this value, and if it's in my list of items to redirect, then to use PHP to do the 301.
Something like this...
// -- php include at top of 404.php page
switch(trim($_SERVER['REDIRECT_URL'])){
case "/oldpage.html" : $location = "/dynamic.php?id=1"; break;
case "/oldpage2.html" : $location = "/dynamic.php?id=2"; break;
}
if(isset($location) && trim($location) != ''){
header ('HTTP/1.1 301 Moved Permanently');
header ('Location: '.$location);
exit(0);
}
// -- end of php include
This gives me a single point to enter in all the links I see in the google webmaster tools that are in blog entries, etc. that are now dead.
Thanks
Well, yes. 301, accompanied by a Location header, is the proper response for a request that you can positively identify as being moved.

Categories