Technical Solution
To manage the ZIP files we will use the functions that PHP itself incorporates.
To try to explain the developed code clearly, I will explain the 2 functionalities separately:
Extract Data (create ZIP file)
The application shows this interface:
In the interface of the LIST page, select the records that you want to export and press the "Export User" button, at that moment the code is executed:
`<?php
@ini_set("display_errors","1");
@ini_set("display_startup_errors","1");
// Delete all ile temporal
function deleteAllFilesToDirectory(string $directory){
$dir = $directory;
if(file_exists($dir)){
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ( $ri as $file ) {
$file->isDir() ? rmdir($file) : unlink($file);
// if ( $file->isDir()) { echo "dir.: ".$file."\n"; } else { echo "file: ".$file."\n"; }
}
}
}
require_once(DIR."/../include/dbcommon.php");
$ids_arr = $_SESSION['ids']; // Recupera los ID seleccionados
$content_arr = array();
$list_id = implode(',',$ids_arr);
$sql = "SELECT * FROM zip_user WHERE ID IN($list_id)";
$rs = DB::Query($sql);
while( $data = $rs->fetchAssoc() ) // Load all record in Array
{
$data['image'] = base64_encode($data['image']);
$content_arr[] = $data;
}
$temp_directory = tempnam(sys_get_temp_dir(), 'exp');
unlink($temp_directory); // Elimino fichero temporal
$temp_directory =strreplace('.','',$temp_directory); // Quito "." en Windows
$temp_zip = str_replace('_tmp','',$temp_directory).".zip"; // Name file ZIP
mkdir($temp_directory,0700); // directorio de exportación
$temp_directory_image = $temp_directory."/image";
mkdir($temp_directory_image,0700); // directorio de imágenes
$error = error_get_last();
// Create images all record select
foreach ($content_arr as &$record) {
$ext_file = explode('.',$record['filename']);
$id = $record['id'];
$temp_file = $temp_directoryimage."/image$id.".$ext_file[1];
$fp = fopen($temp_file , 'wb');
fwrite($fp, base64_decode($record['image']));
fclose($fp);
}
// Create file CSV
$tmp_csv = $temp_directory."/export.csv";
$csv_arr = array();
$csv_arr[] = array('id','name','addDate','precio','filename');
// Format
$decimal = new \NumberFormatter("es-ES", \NumberFormatter::DECIMAL);
$decimal->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, 2);
$decimal->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, 2); // by default some locales got max 2 fraction digits
$entero = new \NumberFormatter("es-ES", \NumberFormatter::DECIMAL);
$entero->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, 0);
$entero->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, 0);
//
foreach ($content_arr as &$record) {
$csv_arr[] = array($record['id'],$record['name'],date_format(date_create($record['addDate']),"d/m/Y"),
$decimal->format($record['precio']),$record['filename']);
}
$fp = fopen($tmp_csv, 'w');
foreach ($csv_arr as $line) { // Write file CSV
fputcsv($fp, $line);
}
fclose($fp);
// Create zip file
$zip = new ZipArchive();
if ($zip->open($temp_zip, ZipArchive::CREATE)!==TRUE) {
exit("cannot open <$temp_zip>\n");
}
$zip->addFile($temp_directory."/export.csv","export.csv");
$options = array('add_path' => 'image/', 'remove_all_path' => TRUE);
$zip->addGlob($temp_directory_image.'/.', GLOB_BRACE, $options);
$zip->close();
// Download zip
$content_zip = file_get_contents($temp_zip);
deleteAllFilesToDirectory($temp_directory); // Delete All file temporal
rmdir($temp_directory);
unlink($temp_zip); // delete file zip
header("Content-Disposition: attachment; filename= export.zip");
header('Content-Type: application/zip');
echo $content_zip;`And the “export.zip” file is created, which contains an “export.csv” file (with the information of the records minus the images) and the “images” directory that contains the user image files (the file identification is does with the value of the ID field).