Тут пришлось провозиться пол ночи, для решения достаточно типовой задачи. Выдача результат работы скрипта в виде zip файла и отдача его клиенту с последующим удалением. Оказалось, этот случай практически не освящен в мануалах.

Собрал по частям следующее решение

        $name_ = $_FILES['fileZip']['name'];

        $name = urlencode($name_);

 

            var oReq = new XMLHttpRequest();
            oReq.open("GET", "<?php echo $_SERVER["REQUEST_URI"]."?file=$name"; ?>", true);
            oReq.responseType = "arraybuffer";

            oReq.onload = function(oEvent) {
                var blob = new Blob([oReq.response], {type: "application/zip"});
                var link = document.createElement('a');
                    link.setAttribute("type", "hidden");
                    link.href = window.URL.createObjectURL(blob);
                    link.download = '<?php echo $name_;?>';
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
            };

            oReq.send();

Серверная часть примерна следующая:

/*
 * Выдача ZIP файла
 */
function file_force_download($file) {
    if (file_exists($file)) {
        // сбрасываем буфер вывода PHP, чтобы избежать переполнения памяти выделенной под скрипт
        // если этого не сделать файл будет читаться в память полностью!
        if (ob_get_level()) {
            ob_end_clean();
        }
        // заставляем браузер показать окно сохранения файла
        header('Content-Description: File Transfer');
        header('Content-Type: application/zip');
        header('Content-Disposition: attachment; filename=' . basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));
        // читаем файл и отправляем его пользователю
        readfile($file);
        exit;
    }
}

Функции архивирования

define('DS', DIRECTORY_SEPARATOR);

/*
 * Рекурсивная архивация файлов
 */
function addFileRecursion($zip, $dir, $start = '')

{

	if (empty($start)) {

		$start = $dir;

	}



	if ($objs = glob($dir . '/*')) {

		foreach($objs as $obj) {

			if (is_dir($obj)) {

				addFileRecursion($zip, $obj, $start);

			} else {

				$zip->addFile($obj, str_replace($start . '/', '', $obj));

			}

		}

	}

}
/*
 * Заархивировать директорию
 */
function archiveDirectory($dir,$zipFileNameWithPath ) {
    $zip = new ZipArchive();

    $zip->open($zipFileNameWithPath, ZipArchive::CREATE|ZipArchive::OVERWRITE);

    addFileRecursion($zip, $dir);

    $zip->close();
}

Ну и операции с файлом:

// если есть запрос на отдачу файла
if(isset($_GET['file']) && $_GET['file'])
{
    // определяем имя
    $filename = urldecode($_GET['file']);
    
    // прибавляем к нему адрес временной папки
    $tmpfname = sys_get_temp_dir().DS.$filename;
    
    // архивируем временную папку
    archiveDirectory(__DIR__.DS.'tmp',$tmpfname);
    
    // Отдаем файл
    file_force_download($tmpfname);

    // завершаем скрипт (Машу каслом не испортишь)
    exit();

}