I have some process in page. It's downloading a file.
<?php
// getting file with CURL
$ch = curl_init ('.csv');
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT,7500);
$rawdata=curl_exec($ch);
curl_close ($ch);
// End Curl Process
// SAVE FILE
$name = Rand(100000,1000000);
$fp = fopen('files/'.$name.'.csv','w');
fwrite($fp, $rawdata);
fclose($fp);
// END SAVE PROCESS
// REDIRECT OTHER PAGE
**header('Location: x.php');**
// END OF PAGE
?>
This is allright. But there is a problem. It redirects without plete process. I want to redirect after all processes are done. The file is empty when i redirect with that method.
What must I do? How can i redirect page after all processes are done? php or javascript/jquery.
I have some process in page. It's downloading a file.
<?php
// getting file with CURL
$ch = curl_init ('http://adress./file.csv');
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT,7500);
$rawdata=curl_exec($ch);
curl_close ($ch);
// End Curl Process
// SAVE FILE
$name = Rand(100000,1000000);
$fp = fopen('files/'.$name.'.csv','w');
fwrite($fp, $rawdata);
fclose($fp);
// END SAVE PROCESS
// REDIRECT OTHER PAGE
**header('Location: x.php');**
// END OF PAGE
?>
This is allright. But there is a problem. It redirects without plete process. I want to redirect after all processes are done. The file is empty when i redirect with that method.
What must I do? How can i redirect page after all processes are done? php or javascript/jquery.
Share Improve this question asked Aug 19, 2011 at 22:19 BenjaminBenjamin 2,1234 gold badges18 silver badges17 bronze badges 3- 4 how do you know that all processes aren't done? this code should run sequentially – Doug Molineux Commented Aug 19, 2011 at 22:22
- The problem can't be your redirect - it takes place when the file has already been written. It must be something else. Are you 1000% sure it works if you remove that header line? – Pekka Commented Aug 19, 2011 at 22:22
- Yes, it works if i don't redirect page. File is big (40-50 MB). Everything is ok about timeout. Its working if i dont redirect as i say. But i have to redirect for other process (uploading it to somewhere). – Benjamin Commented Aug 19, 2011 at 22:23
4 Answers
Reset to default 3I think set a callback when the header is plete is the best solution.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.php/');
// here is the hack - Set callback function for headers
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
curl_exec($ch);
curl_close($ch);
//Callback function for header
function read_header($ch, $string)
{
if (trim($string) == 'HTTP/1.1 200 OK')
header("location: http://www.php");
}
Your code should be fine, and should plete the process before redirecting.
PHP runs in a single thread, so the next statement won't be executed until the previous one pletes. This means that your header()
line won't execute until fwrite()
has finished writing the file.
In fact, setting a Location
header doesn't even mean the PHP script stops. You can test this by creating a dummy file and running unlink()
on it after issuing the Location
header. The file will still be deleted. All that Location
does is sends a new location to your browser. Your browser then retrieves the new page before the old one is done running.
You can set sleep(seconds) and check if it's enough for plete process.
Also you can put a simple check:
$start_size = 0;
while (1) {
$new_file_size = filesize($filename);
if ($start_size != $new_file_size) {
$start_size = $new_file_size;
sleep(30)
} else {
break;
}
}
If you aren't returning the file to the client, you can do the following:
ignore_user_abort();
header("Content-Length: 0", true, HTTP_RESPONSE_204_NO_CONTENT);
header("Connection: close", true);
flush();
This will return control back to the client and close the browser connection, but the server-side process will continue to work.
However, I agree with @AgentConundrum that the header() line won't be executed until the other processes are plete.