PHP - header() redirect: Firebug logs 404 - why? - php

I am using a PHP redirect in one of my projects. I do it like this:
header( 'Location: http://domain.net/?cig=warn&onum=' . $onum . '&cnum=' . $cnum . '&c=' . $c . '#Form' );
So you see, it's a normal use of PHP's header() function where some variables are included in the URL.
It's working, but testing the page with Firebug, I get this error in the console:
"NetworkError: 404 Not Found - http://domain.net/?cig=warn&onum=12&cnum=73&c=ui#Form"
Is there actually something wrong with the way I do it or is this just Firebug being picky because of all the parameters and the anchor?

Since this page lives within a WordPress environment, you must force a 200 status code by manually setting it before your headers get sent (using the WordPress status_header() function):
<?php
// This must appear before any output is sent!
status_header(200);
?>
You'll have to pull in the WordPress functions to get at this, obviously. The problem is that WordPress is intercepting the request before your page has a chance to process it. It cannot locate the "page" and sets a 404 response code, which is what eventually gets sent back out.
When I've had to pull in the WordPress functions in the past, I've done so by including these two lines on the page:
define('WP_USE_THEMES', false);
require_once("/path/to/my/site/wp-blog-header.php");
Now, that said, the pages I've done this with in the past have had the same look and feel as the ones in my WordPress installation. There may be a better way to pull in the functions alone; you'd have to consult the WordPress documentation to find out (I don't know if there is). How to do it properly might be a good question for the WordPress StackExchange site.

Related

Locate redirect in production script

I have inherited working on a very large php website. We're running into some issues where certain pages are causing strange redirects. I'm looking for some ideas to help find these redirects in the php code.
We are not hosting the site so we do not have shell access. Originally I was going to hook into a shutdown function or a destructor and log the call stack, but the call stack looks to only contain the exit function. Next I was looking for ways to override the php 'header' function (through namespaces most likely) but this would involve adding the namespace to too many files.
Are there any php techniques, short of placing die statements everywhere or downloading all of the source code and running grep over it, that would allow finding which redirect in the code is being triggered?
First
Avoid debugging on a live production site whenever possible. If you must, then I would set up "gates" to prevent other people from seeing your tests. You can do this by checking for an IP address or a custom GET variable. The following are two PHP examples.
if ($_SERVER["REMOTE_ADDR"] == "xxx.xxx.xxx.xxx") {
// Run Your Code Here
}
or
if (!empty($_GET["my_custom_get_var"])) {
// Run Your Code Here
}
Technique 1 - PHP Specific
Sometimes the easiest way to find something or test if something is working is to try to break it. In this case, for a PHP redirect to be successful (which uses the PHP header function), it requires that no header information was sent to the browser before making the call. So first, see if you can trigger the dreaded headers already sent warning by outputting anything ahead of that call. If you can trigger that warning you should be able to get the line number and file of where the redirect is occurring. From there you can debug_backtrace() to find the culprit of the redirect.
If output buffering is on, you will want to disable that temporarily or flush it for your test.
Technique 2 - WordPress Specific
I thought I would also throw in a WordPress solution in case you are working on a very large WordPress site. As long as the code / plug-in that is causing the redirect is using WordPress's core then you should be able to tap into their hook system. The following would be a test you could run from the "functions.php" file in the active template / theme - which should show you the stack trace leading up to the redirect.
function my_custom_function ($location, $status) {
print_r(debug_backtrace());
exit;
}
add_filter("wp_redirect", "my_custom_function" , 10, 2);

Getting 302 redirects when testing website on pingdoms and others

I am not able to identify how and where it is happening. When i run a test on pingdom, every 3 out of 5 times it will show in the result that my website www.filliplingua.com is redirected to "/". I am giving the link to the reults below:
http://tools.pingdom.com/fpt/#!/bpgda9/www.filliplingua.com
It is a joomla website. I even reset my .htaccess. And turned off redirect plugin in joomla and cleared all kinds of caches. Still it is showing. Can u please help me find out how to solve is.
If the redirect is originating from PHP it's programmed with the header() function, and that function will throw a warning if the output has already started, because the first output will send the HTTP headers.
PHP Manual about header():
Remember that header() must be called before any actual output is
sent, either by normal HTML tags, blank lines in a file, or from PHP.
It is a very common error to read code with include, or require,
functions, or another file access function, and have spaces or empty
lines that are output before header() is called. The same problem
exists when using a single PHP/HTML file.
So what you can do in index.php is start the file with any output, like echo "here";
and this will trigger a warning when the script is trying to redirect, the redirect will fail, and in the error description (in the log or on the page, depending on your error-reporting settings) you will be able to see what file the redirect originates from. From there, you will probably figure out why it tries to redirect.
Good luck!

Jquery Get returning 404 Error but still returns answer

I have this piece of code
$.get('/proc.php?proc=get_color', function(data){
$('#offer_color').html(data);
});
that is hosted on an https. Now when I request this page its saying 404 Error in the console but in the Firebug console it returns what its suppose to for example "DATA IS OK".
Does anyone have any idea why it says 404 error while in fact its returning its value from the remote php file?
It is not allowing me to do anything with the result as its displaying "Error" when I alert it.
In the proc file
include('wp-blog-header.php');
global $db;
echo 'Data is Ok'
I need the WP things to connect to the WP Database
Sounds like your script, proc.php, or one that it includes is setting a 404 header. I see from your comments that you calling in a WordPress file - perhaps this is trying to resolve the supplied URL, failing and then issuing a 404 header before your code in proc.php is even evaluated.
After a quick search on Google it looks like this common problem and there are a couple of blog posts out there that deal with working around the issue:
Fixing false 404 headers on external pages including wp-blog-header.php
Wordpress Forum
It looks like the answer is to replace according to a post on the Wordpress Forums:
include('wp-blog-header.php');
with:
include('wp-load.php');
require_once("/wp-config.php");$wp->init();
$wp->parse_request();
$wp->query_posts();
$wp->register_globals();
$wp->send_headers();
This solved it

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 after execution of code

I have a php page that takes in a bunch of url parameters and sends out an email. I am trying to have this page call another web page using the same url parameters, after the mail is sent. If I do the following, will my email be sent reliably? Is a redirect what I really want to do?
Update: Thanks for the tips. As you can see by my use of the +, I don't know any php. After reading all the answers so far I have come up with this:
Random code to send email...
file_get_contents('http://www.othersite.com/' . $_SERVER["REQUEST_URI"]. "?". $_SERVER["QUERY_STRING"]);
I believe this should initiate a GET on the other site with all the current parameters, which is exactly what I want. This way I don't have to deal with redirects. Any problems to this solution?
Update 2: Since my url was https, file_get_contents caused me some problems. There are ways to get around this but I just used header for a redirect and all worked well. Thanks everyone!
The question raised in the other answers whether your basic approach is really what you want is valid - check that first. Anyway, if it really is what you want to do (Is your target URL really identical to the one you're on?) you can indeed use
header('Location: http://www.othersite.com/' . $_SERVER["REQUEST_URI"]);
Just note the use of . to concatenate the string instead of +, you can't do that in PHP.
To do it really properly, you could use http_build_url to build a full valid URL from the current GET array. Code from the manual, modified a bit:
<?php
echo http_build_url("http://user#www.example.com/pub/index.php",
$_GET,
HTTP_URL_STRIP_AUTH | HTTP_URL_JOIN_PATH | HTTP_URL_JOIN_QUERY
);
?>
The header location call will be only called after the mail code so it won't affect your email.
Don't forget to call exit() after your header location call.
Also the string concat operator is not + it's . (dot).
if its the same application, why dont you call the same functions ?
if you want you could do file_get_contents .. instead of a redirect for the same effect.
If you just want to hit that page why not use file_get_contents
$data = file_get_contents('http://www.othersite.com/' . $_SERVER["REQUEST_URI"]);
echo $data;
The benefit with this is you don't have to physically go to the other site if you don't want to, equally if you control the script on the other site you could return a true or false in the HTML which could be checked upon return.
For full compliance (sometimes Chrome will not work with just a Location: header)
header( "HTTP/1.0 302 Found" );
header( "Status: 302" ); # this is for chrome compliance
header( "Location: http://www.othersite.com/' . $_SERVER["REQUEST_URI"] );
Another option is to echo the HTML tag:
<meta http-equiv="Refresh" content="1;url=http://www.othersite.com/<?php echo $_SERVER['REQUEST_URI']; ?>">
This allows you to set a delay time for redirecting (usually 1s), which is good in some situations so that the user doesn't become confused by a flash of content. You can put a 'Stand by while we redirect you' message or similar.

Categories