Call Another PHP Script and Return Control to User Before the Other Script Completes

Can a PHP script start another PHP script and exit?

Here's how to do it. You tell the browser to read in the first N characters of output and then close the connection, while your script keeps running until it's done.

<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(); // optional
ob_start();
echo ('Text the user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Will not work
flush(); // Unless both are called !

// At this point, the browser has closed connection to the web server

// Do processing here
include('other_script.php');

echo('Text user will never see');
?>

How do you conditionally call one php script from another with parameters

To pass control to a new script, you could use the header function. using this approach, you'd have to ensure that no other output is being generated by the first script prior to passing control, otherwise header will throw an error.

if($test){
$var = 5;

header('Location: http://www.example.com/2.php?var=' . $var);
}

Then...

2.php
<?php
$varFrom1 = $_GET['var'];

Alternatively, I recommend using the include statement which lets you bring in another file and execute the functions contained therein

include '2.php';

$variable = "something";

if($test){
functionIn2($variable);
}

You can reference it here: http://php.net/manual/en/function.include.php

php script that calls itself when it is finished - indefinately

Seems like you're running into cron job issues. I would instead turn your script into a daemon, that way it can run perpetually without fear of overlaps or finishing too fast.

Here's a tutorial how to do it.

http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/

Continue PHP execution after sending HTTP response

Have the script that handles the initial request create an entry in a processing queue, and then immediately return. Then, create a separate process (via cron maybe) that regularly runs whatever jobs are pending in the queue.

PHP: Running Multiple Scripts at the Same Time for the Same Client

Without more info there are a few possibilities here, but I suspect that the issue is your session. When a script that uses the session file start, PHP will lock the session file until session_write_close() is called or the script completes. While the session is locked any other files that access the session will be unable to do anything until the first script is done and writes/closes the session file (so the ajax calls have to wait until the session file is released). Try writing the session as soon as you've done validation, etc on the first script and subsequent scripts should be able to start.

Here's a quick and dirty approach:

The "Landing" page:

This is the page that the user is going to click the download link

<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
$(document).ready(function(e) {
//Every 500ms check monitoring script to see what the progress is
$('#large_file_link').click(function(){
window.p_progress_checker = setInterval( function(){
$.get( "monitor.php", function( data ) {
$( ".download_status" ).html( data +'% complete' );
//we it's done or aborted we stop the interval
if (parseInt(data) >= 100 || data=='ABORTED'){
clearInterval(window.p_progress_checker);
}
//if it's aborted we display that
if (data=='ABORTED'){
$( ".download_status" ).html( data );
$( ".download_status" ).css('color','red').css('font-weight','bold');
}
})
}, 500);
});
});
</script>
</head>
<body>
<div class="download_status"><!-- GETS POPULATED BY AJAX CALL --></div>
<p><a href="download.php" id="large_file_link">Start downloading large file</a></p>
</body>
</html>

The "File Uploader"

This is the PHP script that serves the large file... it breaks it into chunks and after sending each chunk it closes the session so the session becomes available to other scripts. Also notice that I've added a ignore_user_abort/connection_aborted handler so that it can take a special action should the connection be terminated. This is the section that actually deals with the session_write_close() issue, so focus on this script.

<?php
/*Ignore user abort so we can catch it with connection_aborted*/
ignore_user_abort(true);

function send_file_to_user($filename) {

//Set the appropriate headers:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($filename));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));

$chunksize = 10*(1024); // how many bytes per chunk (i.e. 10K per chunk)
$buffer = '';
$already_transferred =0;
$file_size = filesize( $filename );
$handle = fopen($filename, 'rb');
if ($handle === false) {
return false;
}
while (!feof($handle)) {
/*if we're using a session variable to commnicate just open the session
when sending a chunk and then close the session again so that other
scripts which have request the session are able to access it*/
session_start();

//see if the user has aborted the connection, if so, set the status
if (connection_aborted()) {
$_SESSION['file_progress'] = "ABORTED";
return;
}

//otherwise send the next packet...
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();

//now update the session variable with our progress
$already_transferred += strlen($buffer);
$percent_complete = round( ($already_transferred / $file_size) * 100);
$_SESSION['file_progress'] = $percent_complete;

/*now close the session again so any scripts which need the session
can use it before the next chunk is sent*/
session_write_close();
}
$status = fclose($handle);
return $status;
}

send_file_to_user( 'large_example_file.pdf');
?>

The "File Monitor"

This is a script that is called via Ajax and is in charge of reporting progress back to the Landing Page.

<?
session_start();
echo $_SESSION['file_progress'];
?>


Related Topics



Leave a reply



Submit