-4

Is there a solution for executing two headers in php? The first header is to execute a php script and the second header is to reload the current php page. If not, is there another way? With a button press, the submitGen function is called. Is there a delay that can be added between two header functions so they can run from same script?

<?php
if (isset($_POST['submitGen'])) {
    header('Location:Page2.php');
    header('Refresh: 0');
}
?>

...
<tr>
    <form action="" method="post" role="form">
        <td>
            <input type="submit" name="submitGen" class="btn btn-primary" value = "Gen">
        </td>
    </form>
</tr>
Tigran
  • 632
  • 1
  • 5
  • 21
  • What do you want to achieve? That `Location` header will already perform a redirect, and `Refresh` will reload that page a second time - what's the reason for this? – Nico Haase May 05 '20 at 08:00
  • 3
    Sounds very XY to me. – Xatenev May 05 '20 at 08:00
  • 1
    **1.)** Why you use `Refresh: 0`? Which page you want to Refresh? Refresh `Page1.php` or `Page2.php`? Note: The Page1.php will NOT refresh, cause it Redirects to Page2.php. **2.)** Do you have problems with `Redirect` via cURL? Then use `curl -L http...` – Cyborg May 06 '20 at 21:27
  • @Cyborg I want to refresh Page1 and also goto Page2. If that does not work, can we open Page2 and close Page1? –  May 08 '20 at 07:08
  • @Saif I updated my answer, I hope it helps. If any issues please let me know. – Cyborg May 08 '20 at 19:18
  • the `Location` header and the `Refresh` header are mutually exclusive. if you need a button that refresh something and redirect afterwards, use javascript to do it. – hanshenrik May 10 '20 at 09:52

8 Answers8

4

Not possible, the header function sends an HTTP response. You can only send 1 response per 1 request, that's how the HTTP protocol works (for the most part). A client requests 1 asset/document/something and the server provides 1 response for that call.

If you want to refresh the current page after the client triggers an event, consider using Javascript to perform the current page's refresh with something like location.reload() on the form submission event.

Dylan Pierce
  • 4,313
  • 3
  • 35
  • 45
  • I tried using JS as well but that event too was ignored and the header event was triggered. Could you please show me how it works? –  Apr 30 '20 at 13:52
  • 1
    Think you need to add more details on exactly the behavior you're looking to achieve, but from what I understand use `location.reload()` on the `Page2.php` page to perform the reload on the new page after the redirect. – Dylan Pierce Apr 30 '20 at 14:22
  • Basically Page2.php will only generate a PDF and close automatically. What is more important here is I want the current page to load after the button is pressed for generating the PDF. –  Apr 30 '20 at 14:31
  • Same answer, use Javascript to trigger a refresh on form submission. – Dylan Pierce Apr 30 '20 at 14:43
  • 3
    **Not possible** is wrong to say. You can set as many header as you want. Just set all header before you output any contents from the page. Its true you send only 1 response per request, but within that request you can define as many headers as you want. If they benefit you or NOT is a different question. – Cyborg May 06 '20 at 21:17
0

I would recommend a two-step workaround.

The idea is to send the redirect during the first request, and then set a session variable, so the refresh is sent during the second request.

<?php
session_start();
if(isset($_POST['submitGen']))
    {
        $_SESSION['do'] = 'refresh';
        header('Location:Page2.php');
    }
if($_SESSION['do'] == 'refresh')
    {
        unset($_SESSION['do']);
        header("Refresh: 0");
    }

?>
Xyz
  • 5,955
  • 5
  • 40
  • 58
  • Unfortunately, only Page2.php loads and the Page1.php never refreshes. –  May 08 '20 at 07:51
0

It's not really clear what Page2.php does, but consider:

1) Page2.php is server-code only - nothing to output to client:

<?php
if(isset($_POST['submitGen']))
    {
        //header('Location:Page2.php');
        //header("Refresh: 0");
        require 'Page2.php';
    }

?>

...

2) Page2.php has output that needs to be sent to client (cookies, javascript etc)

<?php
if(isset($_POST['submitGen']))
    {
        header('Location:Page2.php?autoreturn=true');
        //Catch the autoreturn argument in Page2.php
        //die die die always after a header location..
        die();
    }

?>
Teson
  • 6,644
  • 8
  • 46
  • 69
  • Basically Page2.php executes zipping the files and downloading the zip. –  May 08 '20 at 08:48
  • @Saif Well, that's your problem right there. You never explained that fully from the beginning, so it was never clear that you wanted the output of `Page2.php` to be sent to the user. In this case do you even want to reload `Page1.php` at all? Why not just have the button link directly to `Page2.php` and be done with it? – kmoser May 11 '20 at 19:11
  • Many larger sites uses an iframe to kick in the download. So in your case, if successful upload, return page1.php with an iframe-link to page2.php that solves the download. The actual zipping would probably be carried out by page1.php on post. Please upvote answer. – Teson May 12 '20 at 06:27
  • @kmoser yes you are right. I thought it would not make any difference since the main problem was to open 2nd Page and reload 1st page at same time. –  May 12 '20 at 07:08
  • @Saif But why would you want to reload `Page1.php` if all you're going to do is redirect them to `Page2.php` immediately afterwards? – kmoser May 12 '20 at 08:29
0

When the form is submitted, run a Javascript function that fetches Page2.php and reloads when it's done.

Here's a proof-of-concept that I just tested on my server and works exactly as you asked for. When the user clicks the submit button, Javascript loads Page2.php in the background and then reloads Page1.php:

Page1.php:

<script>
function do_submit() {
        fetch('Page2.php')
        .then(function() {
                console.log('Got Page2.php! Reloading...');
                location.reload()
        })
        .catch(function() {
                console.log('Page2.php failed')
        });

        return false;
}
</script>

<table>
<tr>
<form action="" method="post" role="form" onsubmit="return do_submit()">
<td>
    <input type="submit" name="submitGen" class="btn btn-primary" value = "Gen">
</td>
</form>
</tr>
</table>

Page2.php:

$fp = fopen( 'log.txt', 'a' );
if ( $fp ) {
        fwrite( $fp, date("Y-m-d h:i:si\n") );
        fclose($fp);
        echo "Done!\n";
} else {
        echo "Error opening file\n";
}

Note that log.txt must be writable by the web server, otherwise the script won't be able to open it for writing.

I tested this on my web server and it does exactly what you asked for: it executes Page2.php (as evidenced by the date/time written to log.txt, and then reloads Page1.php in the browser.

kmoser
  • 8,780
  • 3
  • 24
  • 40
  • Page1.php refreshes but unfortunately Page2.php never opens/loads. –  May 08 '20 at 08:32
  • Did you include the `onsubmit="return do_submit()"` attribute in your `
    ` tag?
    – kmoser May 08 '20 at 15:12
  • Yes ofc I did that yet it does not run twice. –  May 09 '20 at 10:28
  • I'm guessing you have a problem with Page2.php (either a syntax error or a logic error) because I just built a complete proof-of-concept that I tested and which works. I'll update my answer to show my code. Hopefully it'll help you. – kmoser May 09 '20 at 17:01
  • If this doesn't work for you, please let me know if you can load your `Page2.php` from a browser directly by typing the URL, and whether that works, i.e. if that causes `Page2.php` to execute. If not, I suspect that's your problem. – kmoser May 09 '20 at 17:11
0

Probably no way to send two headers as mentioned above, but.

If you need to reload after Page2.php shown and there is no Javascript/user input on Page2.php, you can just add

echo "<script>location.reload()</script>";

at the end of the Page2.php - it's a js code which will reload the page when reached. Works even in IE, but needs JS to be enabled.

RollingHog
  • 121
  • 7
0

Have the form load its contents into an <iframe>. Use JS to detect when the <iframe> has loaded, and then reload the main page:

<form action="" method="post" role="form" onsubmit="return doIt()">
  <input type="submit" name="submitGen" class="btn btn-primary" value = "Gen">
</form>

<iframe id="dest" src=""></iframe>

The script to handle form submit:

function doId() {
  var iframe = document.getElementById('dest')
  iframe.addEventListener('load', function() {
    location.reload(); // reload current page
  })
  iframe.src = 'Page2.php'
  return false; // Prevent form from submitting
}
kmoser
  • 8,780
  • 3
  • 24
  • 40
0

There's one way you can send that you can do two task in a single header as

header("Refresh:0;url=Page2.php");

Here what happens is the page that you are currently on gets refreshed first and then the second part of the header is been done which redirects you to the another webpage as mentioned.

Note: It is not a good idea to send multiple header() to the webpage because if they are are of the same type only the last mentioned header will be executed.

Kunal Raut
  • 2,495
  • 2
  • 9
  • 25
-1

This IS the correct way to set multiple headers for 1 request:

<?php
    if(isset($_GET['submit'])) {
        header("Location:Page2.php");
        header("Refresh:0");
    }
?>           

Note: In this sample we are redirecting to Page2.php due to that the Refresh:0 is useless!

Saying useless does not mean that Page1.php will not output the header: Refresh:0.

NEVER USE: Location + Refresh for same request unless you know what you are doing.


Page1 will output both headers but you will not notice any difference from a regular web browser.

If you debug in Chrome you will see this code sets both Headers for Page1: enter image description here


Is there a solution for executing two headers in php?

Yes, as shown below you can set as many header as you like:

<?php
    if(isset($_GET['submit'])) {

        if(isset($_GET['count'])) {
            if($_GET['count'] === '5') {
                header("Location:Page2.php");
            } else {
                sleep(1); // HERE Instead of SLEEP run your magic code!
                $count = $_GET['count'] + 1;
                header("Location:Page1.php?submit=1&count=$count");
            }
        } else {
            header("Location:Page1.php?submit=1&count=1");
        }
    }

    header("Connection:Close");
    header("Content-Type:Unknown Cyborg Coding");
    header("Keep-Alive:timeout=60, max=300");
    header("X-Powered-By:Cyborg-Powered MAGIC Servers");
    header("Language:Chineeeeese");
    header("Bots:Are my Friends!");
    header("Hacks:Are COOL!");
    header("Knowledge:Is GOOD!");
    header("StackOverflow:Is GOOD");
    header("Refresh:5"); // This header will be SET but will not make any difference since we use Location Redirect!
    // Refresh Header AND Location Header SHOULD NOT be set for same request unless you KNOW what you are doing. 

    echo "This lines will never been seen UNLESS you use cURL or other approch to DISABLE FOLLOW-REDIRECTS!<br/>\n";
    echo "Enjoy Coding!";
?>

Again, Header Refresh here will not make any difference. But after 5 Reloads of Page1 it will redirect to Page2!

See this headers and requests:

enter image description here


The first header is to execute a php script and the second header is to reload the current php page.

For that you dont need to set 2 header, but if you want to reload Page1 multiple times till you get some results from other script, and thereafter go to Page2 when results are success from script then just change the if conditions in code above.

Code Sample:

<?php
    if(isset($_GET['submit'])) {
        $results = shell_exec("curl -k 'https://api4.eu'"); // here set the script you want.
        if (strpos($results, 'Realtime API Exchange') !== false) { header("Location:Page2.php"); }
        else { sleep(3); header("Location:Page1.php?submit=1"); }
    }
?>

Or better avoid sleep and use:

<?php
    if(isset($_GET['submit'])) {
        $results = shell_exec("curl -k 'https://api4.eu'"); // here set the script you want.
        if (strpos($results, 'Realtime API Exchange') !== false) { header("Location:Page2.php"); }
        else { header("Refresh:3"); }
    }
?>
Cyborg
  • 1,437
  • 19
  • 40
  • Please add some further explanation to your answer, such that others can learn from it. As this looks like the original code, what makes you think that everything works fine? Saif hadn't posted this question if the original code would do what it should – Nico Haase May 05 '20 at 10:16
  • @NicoHaase I update answer, and added few more samples. Hope it helps. About headers ask anything you want and I will try to help. – Cyborg May 08 '20 at 19:27