HTTP 302 error because of a header() - php

if I validate html or register web in any serch engine, I get 302 error.
The reason is a header() function. If I take it away, everything is fine with 200 OK status.
So the main problem is that I need this redirection for web to be multilingual.
The logic is next. When user enters the web page for the first time index.php - require_once a file with a function:
function cookies() {
if (!isset($_COOKIE["lang"])){
setcookie('lang','ukr', time()+(60*60*24*31));
header('Location: index.php');
}}
cookies();
so the user sees a page already filed with a deafault language.
If there would be no redirection from require_once file the data from mysql won't be downloaded and user won't see any text.
The question: should I leave this with HTTP 302 or rebuild the whole site/logic not to have any redirects at index page???

302 is not an error. It is the status code for "Found" (aka "The document you asked for is over here"). PHP will insert this for you automatically if you add a Location header (unless insert a status manually, but you don't want a 301 here)
This is the expected response if you are telling people to go and get a different document based on their language preferences.
It is odd to redirect from index.php to index.php though. Presumably you should just return the appropriate document directly instead of redirecting.

I got it. It's actually pretty simple.
The validators don't accept cookies. So they get stuck in a an infinite loop.
You can test this:
delete all your cookies from your computer.
Disable cookies in your browser and try loading your website.

Whenever You use header("location: .... you will get a 302, it's a status and not an error, it's telling the browser that the site has redirected the page:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Read those validators and engines and see if having the 302 is a problem for whatever you are trying to do, normally it shouldn't be.
A dirty way would be to force the header, personally I don't encourage this and don't know what side-effects could it have really, but it could be a quick workaround to trick those engines:
function cookies() {
if (!isset($_COOKIE["lang"])){
setcookie('lang','ukr', time()+(60*60*24*31));
header('Location: index.php');
header('HTTP/1.1 200 OK'); // <--- Forcing the header status
}}
cookies();

Related

Redirecting with 404 doesnt work

I havea code that should redirect in case it doesnt have some request parameter set correctly.
if(!is_numeric($_GET['id'])){
header("HTTP/1.0 404 Not Found");
header('Location: '.$url);
exit();
}
Problem is that whenever I check with Firefoxes plugin, live HTTP headers, I see 302 temporary redirect. why is that? why no 404 response is given?
It doesn't make sense to send a Location header with a 404 status code.
Location means "What you asked for is over here"
404 means "I don't have what you asked for"
The two statements are incompatible.
If you want to send a particular human readable explanation of the error, then just output it as you would for any other kind of document. You could include() it if you like. Don't try to redirect to it.
Problem is that whenever I check with Firefoxes plugin, live HTTP
headers, I see 302 temporary redirect. why is that? why no 404
response is given?
Not sure what you want to do here but following will provide your purpose.
if (! is_numeric($_GET['id'])) {
header('Location: ' . $url, true, 404);
exit();
}
You can only send ONE of the headers you are attempting as stated above.
In case of 404 - this will display the error relevant error pages as defined by you're web server config.
To do what you want... you will need to modify the server's 404 from a plain html to a php page and work out what to display from there (you can base on referrer etc).
From within the 'dynamic' 404 page, you can then do you're redirect if required.

Is it possible a Search Engine Friendly Redirct with Interface page?

I want to redirect page like: http://www.mysite.com/index.php?id=1 to http://www.mysite.com/the-real-name.htm but I don’t have the-real-name in first url then I should get it from db.
I made an interface page then I redirected page http://www.mysite.com/index.php?id=1 to it and I fetched the-real-name (with id parameter in url) from db then I redirected page to http://www.mysite.com/the-real-name.htm with PHP Header function.
Is this process search engine friendly?
Which page will be indexed with search engine crawler? Interface page or http://www.mysite.com/the-real-name.htm ?
Which is the best solution for indexing http://www.mysite.com/the-real-name.htm ?
Thanks a lot
If you want to tell the search engine that the final URL is "the URL", you need to do a permanent redirect. The HTTP status code is 301.
header('Location: http://www.mysite.com/the-real-name.htm', true, 301);
For the first redirect, you need to do a temporary redirect. The HTTP status code is 302.
header('Location: http://www.mysite.com/index.php?id=1', true, 302);
Keep in mind that it's good practice to not only send headers back for redirects, but a HTTP/HTML BODY as well that is shipping human readable information where the new location is. Redirects are not to be expected to be automatically performed by the client.
Different ways to implement
Depending on the system you work on, setting a HTTP status header with PHP might differ. The code above is for a working PHP version. Stick to latest. However, if you can not and the server integration is broken you might to push a bit the limits and force around a bit:
# Manually sending the HTTP 1/1 status line header - PHP does this nowadays, so normally not needed. But if you need it, ensure it's the first header you send.
header ('HTTP/1.1 301 Moved Permanently');
# Same here, but some CGI/FCGI+PHP implementations require you to set the Status header as well manually. Normally not needed.
header ('Status: 301');
# Set the Location header and status: (you will always need this)
header ('Location: http://www.mysite.com/the-real-name.htm', true, 301);
Always check if your script sends the correct headers by requesting it with a tool that is able to display the response headers not performing the redirect automatically, like curl:
$ curl -i "http://www.mysite.com/index.php?id=1"
Otherwise it takes a little long to wait for google to reflect the changes only for you to realize that you made some error.
When redirecting also set a 301 header and the search engines will know what to to from there.
header ('HTTP/1.1 301 Moved Permanently');
header ('Location: '.$location);
If the relationship cannot change, use a permanent redirect as hakre suggested (a 301 status code). Otherwise, if that same id value might point somewhere else in the future, use a temporary redirect.
In either case, if the canonical (official, main, primary) URL is "http://www.mysite.com/the-real-name.htm", you can tell search engines that with a canonical meta tag in the page's head section:
<link rel="canonical" href="http://www.mysite.com/the-real-name.htm" />

more than one header in chrome not working - php

Im using PHP to track the clicks of all mailto links by rewriting the mailto: to my script and then setting the header of the referring page.
Initially I just had:
header("location: mailto:email#address.com");
...but this has an undesirable effect in IE8: it opens 2 email windows. So, in my attempt to resolve that issue I am now using:
header("Status: 200");
header("location: http://mypage.com");
header("Refresh: 0; url=mailto:email#address.com");
This works fine in IE but not chrome. I threw the "status" in there hoping to solve the mystery.
Other than detecting the browser and issuing different commands, what else could one do?
A location header should be accompanied by a 30X status code (like 302), not 200.
Check this out > http://php.net/manual/en/function.header.php
Especially those two parts:
The second special case is the
"Location:" header. Not only does it
send this header back to the browser,
but it also returns a REDIRECT (302)
status code to the browser unless the
201 or a 3xx status code has already
been set.
<?php
header("Location: http://www.example.com/"); /* Redirect browser */
/* Make sure that code below does not get executed when we redirect. */
exit;
?>
You send 200 and 302 at same time, and also you didn't follow the exit; rule.
You can play with my suggestions (especially the exit; part).
!!! Note !!! There was a bug in the past that makes the Chrome not to work if header("Status: 200"); wasn't set first, but not sure if it's fixed yet.
it would probably be better to use some AJAX to handle your problem here, and if your going to use AJAX use JQuery its just easier
firstly though mailto is not a preferred method on the web any more its too clunky and relies upon the default email client of the user being set up which in most cases you cannot rely upon.
So to address that have a link that is styled to look like your button.
once you have this use JQuery to send an ajax request to a PHP script that performs the counting and then if you wish upon receipt handle the success with a redirect (I only include that because I am unsure what your redirect achieves).
Its clean quick and the user will not notice a difference apart from your site will probably experience a speed increase :) hope this helps
Header location redirects the browser, so the other headers are ignored. You should send this header always as the last one. Also it's not good idea to execute any PHP code after you send the redirect.
You probably want to do this:
On first page:
header("Status: 200");
header("location: http://mypage.com");
exit();
On the http://mypage.com:
header("Refresh: 0; url=mailto:email#address.com");
The weird thing about chrome: it accepts the following header refresh.
<meta http-equiv="refresh" content="4; url=page.php" />
<button value="go further">
I place a button below this refresh for the browsers who does not support any type of header refresh.

PHP or htaccess make dynamic url page to go 404 when item is missing in DB

Typical scenario:
DB items are displaied in page http://...?item_id=467
User one day deletes
the item
Google or a user
attempts to access http://...?item_id=467
PHP diggs into DB and sees items does not exist anymore, so now PHP must tell
Google/user that item is not existing via a 404 header and page.
According to this answer I undertstood there is no way to redirect to 404 Apache page via PHP unless sending in code the 404 header + reading and sending down to client all the contents of your default 404 page.
The probelm: I already have an Apache parsed custom 404.shtml page, so obvioulsy I would like to simply use that page.
But if i read an shtml page via PHP it won't be parsed by Apache anymore.
So what do you suggest me to do?
Is there maybe some trick I could use palying with htaccess too?
Thanks,
Hmm. Two ideas come to mind:
Redirect to the 404 page using header("Location:...") - this is not standards-compliant behaviour though. I would use that only as a last straw
Fetch and output the Apache-parsed SHTML file using file_get_contents("http://mydomain.com/404.shtml"); - also not really optimal because a request is made to the web server but, I think, acceptable in most cases.
I doubt there is anything you can do in .htaccess because the PHP script runs after any rewrite rules have already been parsed.
IF you are using apache mod_php, use virtual('/404.shtml'); to display the parsed shtml page to your user.
I was trying to do this exact same thing yesterday.
Does Pekka's file_get_contents/include result in a 404 status header being sent? Perhaps you need to do this before including the custom error page?
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
You can test using this Firefox extension.
I was looking exactly for something like you needed, so you have a page:
http://example.com/page?item_id=456
and if later you want that if item is missing you are redirected to:
http://example.com/page_not_found?item_id=456
In reality I found it is much more maintainable solution to just use the original page as 404 page.
<?php
$item = findItem( $_GET['item_id']);
if($item === false){
//show 404 page sending correct header and then include 404 message
header( $_ENV['SERVER_PROTOCOL'].' 404 Not Found', true );
// you can still use $_GET['item_id'] to customize error message
// "maybe you were looking for XXX item"
include('somepath/missingpage.php');
return;
}
//continue as usual with normal page
?>
So if item is no longer in the DB, the 404 page is showed but you can provide custom items in replace or error messages.

PHP Redirect Headers Best Practices

I'm creating a PHP CMS and have some system pages like a 404 page, a maintenance page, and an unauthorized access page. When Page A isn't found, the CMS will redirect to the 404 page; if the user doesn't have access to Page B, it will redirect to the unauthorized access page, etc.
I'd like to use the proper status code in the header of each page, but I need clarification on how to handle the header/redirect. Do I put the 404 header on Page A and then redirect to the 404 page or do I put the 404 status on the 404 page itself? Also, if the latter is the correct answer, what kind of redirect should I use to get there, a 301 or a 302?
If a user arrives on page A and that page doesn't exist, then do not redirect : just send a 404 error code from page A -- and, to be nice for your user, an HTML content indicating that the page doesn't exist.
This way, the browser (and it's even more true for crawlers ! ) will know that the page that is not found is page A, and not anything else you'd have tried to redirect to.
Same for other kind of errors, btw : if a specific URL corresponds to an error, then, the error code should be sent from that URL.
Basically, something as simple as this should be enough :
if (page not found) {
header("404 Not Found");
echo "some nice message that says the page doesn't exist";
die;
}
(Well, you could output something nicer, of course ; but you get the idea ;-) )
I'm not sure if the redirecting is the best way for doing this. Id rather use some built in functionality that is included into the project.
If the data is not found, do not redirect the user to another page, just send him an error message, like Hey, this site does not exists! Try an other one and so.
And not at the end, you should build into the code, the code-part from the answer of Pascal Martin.
I would do this into a function, and call it from a bootstrap or something with a similar behavior.
function show_error($type="404", $header = true, $die = false)
{
if($header)
header("404 Not Found");
echo file_get_contents($type.'.php');
if($die) die; //
// and so on...
}

Categories