-
Description of the problemHi, One thing I need help with, however, is when I want to serve a larger ZIP to users. When they start downloading the zip file and cancel the downloading process at some point, the script remains running on the server. As a result, the page becomes unresponsive and slow until the script finishes. Therefore, the effects are only visible to me when I add a sufficient amount of files (here images) to my zip. In my testing script below, I added 3 different images to my zip, each image 750 times. In total, the zip contains 2250 files making up ~5.5 GB. I use the error_log to keep track of whether the script is still running. As a matter of fact, the log keeps getting updated until all files are processed no matter when the user cancels the download either by stopping the download or closing the browser window. What I want to add to the for-loop is something like: if (connection_status() != 0) {
$zip->finish();
exit;
} However, my error-log suggests that the connection_status doesn't change. So I couldn't find a way to stop my PHP script from executing / streaming once the user cancels the downloading process. Is there any way I can achieve this? Thanks for any advice! Example code<?php
session_start(); //necessary for is_access_granted()
require_once('zipstream/autoload.php');
ob_end_clean();
ob_end_flush();
// Get request argument
$postid = isset($_GET[ 'request' ]) ? $_GET[ 'request' ] : null;
// Define filter such that input must be positive integer
$filter_options = array('options' => array('min_range' => 0));
// For security reasons, proceed only if input is set as positive integer
if (!filter_var($postid, FILTER_VALIDATE_INT, $filter_options) === false) {
serve_zip_download($postid);
}
function serve_zip_download($postid) {
// Check if images are allowed to be downloaded by the user.
if (is_access_granted($postid)) {
// Set options for ZipStream
$options = new ZipStream\Option\Archive();
$options->setSendHttpHeaders(true);
// Create a new zipstream object
$zip = new ZipStream\ZipStream('MyZIP.zip', $options);
// Get all images
$all_images = get_all_images($postid);
//iterate over all images
foreach ($all_images as $currentImage) {
$filepath = get_full_filepath($currentImage);
// Create folders in ZIP named according to category and add file
for ($i = 1; $i <= 750; $i++) {
error_log('Connection-Status: ' . $i . connection_status());
$filename = get_category($currentImage) . '/' . $i . basename($filepath);
$zip->addFileFromPath($filename, $filepath);
}
}
// Finish ZipStream and exit
$zip->finish();
exit;
}
} Informations
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Hi, I still can‘t find a way of identifying whether the user is still downloading during execution of the script. As the connection status returns normal at all times, the script runs until completion no matter what. As a side note: I found a comprehensive explanation here: Even though this is not terminating the script upon user cancellation, which would still be interesting to save resources, perhaps this is helpful to someone else. Cheers |
Beta Was this translation helpful? Give feedback.
Hi,
I still can‘t find a way of identifying whether the user is still downloading during execution of the script. As the connection status returns normal at all times, the script runs until completion no matter what.
As a side note:
The main issue that made my server unresponsive is the session handling. I open / resume the session with session_start() in order to check if the user is logged in (is_access_granted). This locks the session file until the end of the script which is why other attempts of using the downloader-script are delayed. To prevent this from happening, I simply use session_write_close() directly after the login status is determined such that the file lock is lifted and…