0

I'm facing a problem using Headers in PHP. header('location: http:google.com'); is not working. This is my code:

if(!headers_sent()){
    header("location: http://google.com");
    exit;
}

HTML Data...

Script is exiting but header() is not working.

  • I've already checked in my php.ini for output_buffer param and it's set to 4096.
  • There are not extra lines above PHP opening tag
  • and my script is encoding in UTF-8 w/o BOM.
  • All errors are enabled but I'm getting no errors/warnings/notices. What is happening?
  • Environment: PHP 7.0.27 and NGINX.

Later attempts and debugging steps concluded:

  • header("location: http://google.com";, true, 302); made no difference
  • header("Refresh: ...") did succeed.
  • HTTP response debugging (after being asked a couple of times):

    StatusCode : 200 
    StatusDescription : OK 
    Content : <br />  <b>Notice</b>: Undefined index: HTTP_ACCEPT_LANGUAGE in ...
    RawContent : HTTP/1.1 200 OK 
    Transfer-Encoding: chunked 
    Connection: keep-alive 
    Pragma: no-cache 
    Cache-Control: no-store, no-cache, must-revalidate 
    Content-Type: text/html; charset=UTF-8 
    Date: Fri, 18 May 201... 
    Forms : {} 
    Headers : {[Transfer-Encoding, chunked], [Connection, keep-alive],
    

Unanswered still:

  • header("Status: 303 etc"); vs. header('HTTP/1.1 301 Moved Permanently'); from the duplicate

  • State of cgi.rfc2616_headers

  • PHP SAPI

  • Running the sample code outside the phar.

mario
  • 144,265
  • 20
  • 237
  • 291
ProtectedVoid
  • 1,293
  • 3
  • 17
  • 42
  • Are you sure that the second `header()` is executed? – Spoody May 18 '18 at 03:26
  • 1
    Try putting Location instead of location. I think it's case sensitive. – XerShade May 18 '18 at 03:27
  • `set_error_handler("var_dump");` and showcase the `wget -S` output for that test script. – mario May 18 '18 at 03:27
  • @XerShade I already tried it, still not working. – ProtectedVoid May 18 '18 at 03:29
  • @Mehdi I echoed a message within the if clause, and the message was displayed. That means that headers haven't been sent yet. – ProtectedVoid May 18 '18 at 03:30
  • Go to the network tab in your browser and check the response headers – Spoody May 18 '18 at 03:31
  • @Mehdi "This request has no response data available". – ProtectedVoid May 18 '18 at 03:32
  • @mario Sorry, but could you explain the steps? I've put `set_error_handler("var_dump");` above `header()`. What should I do now? – ProtectedVoid May 18 '18 at 03:34
  • @ProtectedVoid run "wget -S url-to-script" and it should get the output. – XerShade May 18 '18 at 03:35
  • If no warning shows up, might indicate an NGINX and PHP-FCGI setup issue rather (nothing can be deduced from that code sample really). Hunt for either php or nginx logs. And run `wget -S http://localhost/yatestscript.php` on the console. – mario May 18 '18 at 03:36
  • @XerShade My NGINX server is running locally in Windows. Is there `wget` equivalent I can try? – ProtectedVoid May 18 '18 at 03:40
  • @ProtectedVoid If you are using powershell try this `$client = new-object System.Net.WebClient` `$client.DownloadFile("url","file.txt")` – XerShade May 18 '18 at 03:43
  • Probable duplicate of https://stackoverflow.com/questions/8028957/how-to-fix-headers-already-sent-error-in-php and https://stackoverflow.com/questions/4150717/with-nginx-php-fpm-location-header-sometimes-ignored-by-browser-why -- Also: Powershell `Invoke-WebRequest` – mario May 18 '18 at 03:43
  • @XerShade Powershell solution worked, I'm getting two PHP 'notice'. – ProtectedVoid May 18 '18 at 03:48
  • Try adding this before the location call. `header("HTTP/1.1 307 Temporary Redirect");` – XerShade May 18 '18 at 03:50
  • @XerShade That didn't make a difference. – ProtectedVoid May 18 '18 at 03:51
  • You said you got two notices, what were they? – XerShade May 18 '18 at 03:52
  • @XerShade Both are 'undefined index' for `HTTP_ACCEPT_LANGUAGE` and `HTTP_USER_AGENT`. I'm assuming I'm getting these 'notice' because the request was sent from Powershell? As I'm getting no notice when requesting from browser. I just disabled PHP notice messages from php.ini, but still not working. – ProtectedVoid May 18 '18 at 03:54
  • Another little thing but try removing the space between the : and the h on the location line. – XerShade May 18 '18 at 03:58
  • @XerShade No luck :( – ProtectedVoid May 18 '18 at 03:59
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/171277/discussion-between-xershade-and-protectedvoid). – XerShade May 18 '18 at 04:00
  • 3
    @mario How is this a duplicate of what you said it is, he has said multiple times that there is no error, so how can you tag it as a duplicate of that error. – XerShade May 18 '18 at 04:12
  • @mario none of the answers in the other question work for me – ProtectedVoid May 18 '18 at 04:16
  • @XerShade I'll leave this as duplicate until access/error.log and the required HTTP raw debug output have been edited in. In it's current form the question is unanswerable. (Look at the answers this got so far. Elaborate debugging chat notwithstanding). Summon me when something worthwhile comes up. – mario May 18 '18 at 04:16
  • @mario I have a semi-solution that works, could you please unlock the question. – XerShade May 18 '18 at 05:36
  • @XerShade No probs. However, I would politely request someone edit the attempts and header debugging from the chat in here. Else an answer/workaround would be slightly misleading to future visitors. (Or: your answer might better fit as post on the second duplicate otherwise. Because that one contains all the necessary details to be useful/reproducible.) – mario May 18 '18 at 13:32
  • Note: this is pretty much still a duplicate of [With nginx/php-fpm, location header sometimes ignored by browser. Why?](//stackoverflow.com/q/4150717) – mario May 18 '18 at 13:47

2 Answers2

1

Right, this is not so much as a fix to the problem but a work around to get redirects working client side while you're on your development server. I wrote up a middle ware function to generate the redirect headers for you, simply add it to your code then call Redirect("URL");.

<?php

function Redirect($location, $delay=0) {
    // Check to see if the header are already sent.
    if(!headers_sent()) {
        // Check to see if we want Refresh because Location isn't working.
        if(defined('REDIRECT_ALTERNATIVE')) {
            // We want Refresh, let's go!
            header("Refresh: $delay; URL=\"$location\"");  
            exit;
        }

        // We want to do this server side, do it!
        header("Location: $location");
        exit;
    }
}

Now that you have this function all that you need to do is in a file, preferably a constants or config file, use the code define('REDIRECT_ALTERNATIVE', true); then that will enable client side redirecting, when you are done simply comment or remove that definition and it will switch back to server side.

Again this is not a solution as much as it is a work around, but after hours of testing with the OP this is what we managed to come up with.

Edit: For anyone who is wondering what the actual problem is, the OP's development server, for whatever reason, is always setting the http code to 200, even if we changed it manually, since I had no way to access his pc and debug his setup I came up with a workaround that avoids the need for his server to manage the redirects.

XerShade
  • 137
  • 9
-1

Try this.

     header("Refresh: $seconds; URL=\"$location\"");  
Nauman Moazzam
  • 158
  • 5
  • 17