3

I have a long running script after a user submits a form and I am trying to redirect them before the actual script starts executing

I tried to implement the accepted answer here How to cause a redirect to occur before php script finishes?

But I think the solution is outdated cause it does nothing

Here is the code at the top of the script once a form is submitted

set_time_limit(0);
header ( 'Connection: close' );
ob_start ();
header ( 'Content-Length: 0' );
header("Location: www.google.com");
ob_end_flush ();
flush ();
ignore_user_abort(true);

Expected Results: My Expected result is for the user to click the submit button and they are redirected to google.com meanwhile the script will continue to execute on my server

Actual Result: What is actually happening is the user just sits on the page till the script finishes execution

Deathcriw
  • 121
  • 12
  • 1
    It's also important what web server software you have and how PHP interacts with the Webserver Software (CGI, some other interface) – NineBerry Jun 12 '19 at 22:11
  • 1
    i think that's a bad approach compared with just running the script in the background and redirecting `exec('php script.php >/dev/null &'); header("Location: www.google.com");` –  Jun 12 '19 at 22:14
  • 2
    You could submit with Ajax and redirect in JavaScript after you send request. Ajax is asynchronous, so it doesn’t have to stop while waiting for a reply – Tim Morton Jun 13 '19 at 00:23
  • @Tim Morton I would but the script is around 1600 lines of uncommented code that I didnt write and I dont have 2-3 days to rewrite it so that it can be done through ajax(trust me I would much prefer to) – Deathcriw Jun 13 '19 at 05:32
  • 1
    The concept is fairly trivial-- add an onsubmit listener to intercept the form submission, do a post and redirect. You don't have to rewrite anything, just add an observer: `$(function() { $('#my-form').on("submit",function(e) { e.preventDefault(); // do your ajax and resubmit` – Tim Morton Jun 13 '19 at 13:26
  • Tried this and it doesnt work @TimMorton – Deathcriw Jun 13 '19 at 20:52
  • Have you looked at this answer: https://stackoverflow.com/a/141026/2444435 Also the answer after, regarding gzip and fcgi and such: https://stackoverflow.com/a/1773248/2444435 – jhaagsma Jun 17 '19 at 22:26
  • Put the long running job in a queue as advised by @Mohd-Samgan-Khan. Trying to make your PHP script responsible for running it after redirecting the user makes your script less portable, as you will be relying on Apache/Nginx/other and any load balancers to play ball. – Gus Jun 24 '19 at 17:36

3 Answers3

2

The safest method is to start an external application (possibly another php script with the aid of php executable) with PHP exec from your script. You can use exec($cmd . " > /dev/null &"); for background execution.

Once you send the redirect, the connection may be closed. The web server may terminate your executing PHP script, for example nginx does not support "background" commands.

Michael Chourdakis
  • 10,345
  • 3
  • 42
  • 78
2

the simplest way would be an ajax call but as you have mentioned that that's not working. I'll suggest you make a queue. you can create a table in the database and whenever the user submits the form add an entry to that table. and redirect the user as you wish. this won't take a long time.

now create a cron job with frequency as you please to read from that table and perform the desired script with data from the table. ones the script is done remove the entry from the table.

you can have some more details about the queue and how to create them from here

1
  1. You are closing the connection at 2nd line, After closing the connection, how your webserver will communicate with client??? Remove line two. or change line orders like this.

    set_time_limit(0);
    ignore_user_abort(true);
    ob_start ();
    //header ( 'Connection: close' );  //You don't need this line as you are redirecting
    header ( 'Content-Length: 0' );
    header("Location: www.google.com");
    ob_end_flush ();
    flush ();
    \*Browser will redirect at this point *\    
    ignore_user_abort(true);
    set_time_limit(0);
    \*Your Long Running Script After this line*\
    
  2. If you are redirecting to other page, you don't need to close the connection.