This topic is locked

Guide 54 - Use of ZIP files to transport content

3/20/2023 8:03:44 AM
PHPRunner Tips and Tricks
fhumanes author

On many occasions, in my work, we have had to transfer a large volume of information from one system to another (both computers being disconnected) so we have no choice but to obtain files and move them from one machine to another.
Normally it was not information from a single TXT type file, but rather there were several and they could also have information in binary format.
So, to move them we used the ZIP format, as a container and compressor of the information.
To illustrate the functionality, I have defined a case where the users are created and by selecting them, their data and images are extracted in a ZIP file and how, through that ZIP file, an incremental load of the data is done in the system. destination. To simplify the example I have included the 2 functions in the same PHPRunner application .
I think there are many more cases where this example can be applied. The important thing is to know that through simple programming, this is possible with PHPRunner.
Objective
Gain knowledge of how to export data (text, numbers, dates and binary) and save it in a ZIP file to deliver to a user or to apply to another application.
And how we can load data stored in ZIP files, in our database.
DEMO : https://fhumanes.com/zip_manager
If you are interested in this topic, keep reading the article at this link

fhumanes author 3/20/2023

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:
img alt
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).

fhumanes author 3/20/2023

Import Data (read ZIP file)
The application shows this interface:
img alt
The information from the "status" field is used to find out if the file is applied (loaded) and if there are incidents in the loading process, it will be reported in the "comment" field.
To execute the import process, you must press the "Import User" button (it is only available in records where the "status" is with the value "0".
The code that is executed is:
`<?php
// $data = $button->getCurrentRecord(); // this in code by button

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

$comment = '';

// Create temporal files and Dir.
$temp_directory = tempnam(sys_get_temp_dir(), 'imp');
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";
$temp_csv = $temp_directory."/export.csv"; // Name file CSV

// Create Zip file
$fpz = fopen($temp_zip, 'w');
fwrite($fpz,$data['archive']);
fclose($fpz);

// Extract ZIP file
$za = new ZipArchive();
$za->open($temp_zip);
$za->extractTo($temp_directory.'/');
$za->close();

// Load file csv
$data_arr = array();
$row = 1;
if (($handle = fopen($temp_csv , "r")) !== FALSE) {
while (($data2 = fgetcsv($handle, 0, ",")) !== FALSE) {
$num = count($data2);
$commnet .= " $num fields in line $row \n";
if ($row == 1){ // Head
$data_head = $data2;
} else {
for ($c=0; $c < $num; $c++) {
$data_arr[$row][$data_head[$c]] = $data2[$c];
}
}
$row++;
}
fclose($handle);
}

// Manager All new record by file CSV
foreach ($data_arr as &$new_record) {

$image = Null;
$name_file = $temp_directoryimage."/image".$new_record['id'];
foreach (glob($name_file .".*") as $temp_file) {
$image = file_get_contents($temp_file);
}

// Prepare INSERT new Record
// All fields: name, addDate, precio, image, filename

$data3 = array();
$data3["name"] = $new_record['name'];
$date_aux = DateTime::createFromFormat('d/m/Y', $new_record['addDate']);
$error = DateTime::getLastErrors();
$data3["addDate"] = date_format($date_aux,'Y-m-d');
$data3["precio"] = floatval(str_replace(',', '.', str_replace('.', '', $new_record['precio'])));
$data3["image"] = $image;
$data3["filename"] = $new_record['filename'];

DB::Insert("zip_user", $data3); // Insert new record in data base
if (DB::LastError() <> ''){
$comment .= DB::LastError()."in record with ID = ".$new_record['id']."\n";
}
}

// Delete Temporal files
deleteAllFilesToDirectory($temp_directory); // Delete All file temporal
rmdir($temp_directory);
unlink($temp_zip); // delete file zip

// Update Archive
$data4 = array();
$keyvalues = array();
$data4["comment"] = $comment;
$data4["status"] = "1";
$keyvalues["id"] = $data['id'];
DB::Update("zip_archive", $data4, $keyvalues );`The export and import of information is very varied, so I hope this example will make programming easier for you.
For any questions, contact me through my email fernandohumanes@gmail.com
As always, I leave you the example with all the files so that you can install, test and change it on your computers.