简体   繁体   English

在PHP中完成处理后重定向页面

[英]Redirect page after process complete in PHP

I have some process in page. 我在页面中有一些处理。 It's downloading a file. 正在下载文件。

<?php

// getting file with CURL
        $ch = curl_init ('http://adress.com/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 complete 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. php或javascript / jquery。

Your code should be fine, and should complete the process before redirecting. 您的代码应该很好,并且应该在重定向之前完成该过程。

PHP runs in a single thread, so the next statement won't be executed until the previous one completes. PHP在单个线程中运行,因此下一个语句要等到前一个语句完成后才能执行。 This means that your header() line won't execute until fwrite() has finished writing the file. 这意味着直到fwrite()完成写入文件后,您的header()行才会执行。

In fact, setting a Location header doesn't even mean the PHP script stops. 实际上,设置Location标头甚至并不意味着PHP脚本停止。 You can test this by creating a dummy file and running unlink() on it after issuing the Location header. 您可以通过创建虚拟文件并在发出Location标头后在其上运行unlink()进行测试。 The file will still be deleted. 该文件仍将被删除。 All that Location does is sends a new location to your browser. Location所做的只是向浏览器发送一个新位置。 Your browser then retrieves the new page before the old one is done running. 然后,浏览器会在旧页面完成运行之前检索新页面。

I think set a callback when the header is complete is the best solution. 我认为在标头完成时设置回调是最好的解决方案。

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.php.net/');

// 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.net"); 
}

You can set sleep(seconds) and check if it's enough for complete 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 complete. 但是,我同意@AgentConundrum的观点,即在其他过程完成之前将不执行header()行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM