简体   繁体   中英

PHP - Extract large ZIP file asynchronously

I'm struggling with this problem for the last few days so maybe somebody could help me with this. I'm developing a large app that has to extract one ~200MB ZIP file containing about 3-4GB of CSV files.

For that I've written a jQuery plugin that was supposed to show something to the user while the ZIP is extracting, and to handle timeouts. But once the extraction process has started, the Ajax cannot send "has it finished yet?" requests to the server, as they also time out. So my question is - is there a way to start the ZIP extraction asynchronously and then check the progress?

I'm building this app on CodeIgniter framework and the zip extraction function looks like this:

public function unpack_zip ($zip_file) {
    // First we check the database to see if the extraction process has already started
    $extracting_file = $this->db->select('value')->from('setting')->where(array('type' => 0, 'key' => 'tube_extractng'))->get()->result_array();

    if (!!$extracting_file[0]['value']) return 'Already extracting!';

    // Next we create a strimg containing path to the zip file.
    $source_file = $this->install_assets_dir . 'zip' . DIRECTORY_SEPARATOR . $zip_file;

    $zip = new ZipArchive;

    if ($zip->open($source_file) === TRUE) {
            // If the zip was open sucessfully we tell the database that extraction is in progress, this stays "true" until the process completes
        $this->db->update('setting', array('value' => true), array('type' => 0, 'key' => 'tube_extractng'));

        set_time_limit(600); // The timeout long enough to extract an extra large file
        $zip->extractTo($this->install_assets_dir . 'csv' . DIRECTORY_SEPARATOR);
        $zip->close();

        rename($source_file, preg_replace('/\.zip$/', '.extracted$0', $source_file)); // Renaming the extracted zip by adding ".extracted" before the extension
        $this->db->update('setting', array('value' => false), array('type' => 0, 'key' => 'tube_extractng')); // And, of course tell the database that the process is done.
        return TRUE;
    }

    return FALSE;

}

The problem is - once the process starts the server is unresponsive until the extraction is complete. Unresponsive server = no responses to "are you still extracting?" Ajax calls.

After digging into it more and more I found out where the issue was. I'm using WT-NMP and my PHP was set to 1 PHP-CGI server, which in effect blocks all other requests when one is in progress. Setting that number to 2 already started giving responses to the "are you done?" ajax requests. The thing now works as it was imagined.

So for anybody else with similar problem - first check the number of PHP CGI servers you're running. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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