Ciao Raga, scrivo queste righe sperando che possano servire in futuro…

Qui spiegherò come utilizzare la compressione di files e le relative funzioni che
potranno essere utili… Esse riguardano soprattutto il filesistem, in quanto
le funzioni per comprimere possono essere tante. Allora Cominciamo…
PERCHE’ COMPRIMERE??
Perchè così risparmiamo spazio… :stordita:

SI POSSONO CREARE ARCHIVI??
Ho fatto in modo di creare degli pseudo-archivi serializzando i dati. Quindi
essi non saranno visibili nei programmi per la gestione degli archivi.

QUANDO SI COMINCIA??
Ora…
Allora… Inizialmente analizziamo le funzioni principali per comprimere i
singoli files. Avevo creato una piccola classe, ed ora la analizzeremo insieme.

<?php
class gz_single {

/* Inizializza le variabili */
var $source;
var $dest;
var $level;
var $pointer;
var $gzdata;
var $data;
var $status;

function compress($source, $dest, $level)
{
/* Inizializza le variabili */
$this->source = $source;
$this->dest = $dest;
$this->level = $level;

/* Controlla che il file d’origine esista e che sia leggibile */
if(!is_file($this->source) OR !file_exists($this->source) OR !is_readable($this->source)) exit(“Error 1: Source file doesn’t exists or it’s not readable!<br>”);

/* Controlla che il file di destinazione non sia di sola lettura */
if(is_file($this->dest) AND !is_writeable($this->dest)) exit(“Error 2: The destination file it’s not writeable”);

/* Arrotonda il livello di compressione */
$this->level = round($this->level);

/* Controlla il livello e se è troppo grande, lo porta al massimo */
if($this->level == ‘MAX’ OR $this->level > 9) $this->level = 9;

/* Controlla il livello e se è troppo piccolo, lo porta al minimo */
if($this->level == ‘MIN’ OR $this->level < 1) $this->level = 1;

/* Prende i dati dal file d’origine */
$this->data = file_get_contents($this->source);

/* Comprime i dati del file d’origine */
$this->gzdata = gzcompress($this->data, $this->level);

/* Scrive i dati compressi nel file di destinazione */
$this->status = file_put_contents($this->dest, $this->gzdata);

/* Ritorna i valori positivi e negativi in base all’esito dell’operazione */
if($this->status) return TRUE; else return FALSE;
}

function decompress($source, $dest)
{
/* Inizializza le variabili */
$this->source = $source;
$this->dest = $dest;

/* Controlla che il file d’origine esista e che sia leggibile */
if(!is_file($this->source) OR !file_exists($this->source) OR !is_readable($this->source)) exit(“Error 1: Source file doesn’t exists or it’s not readable!<br>”);

/* Controlla che il file di destinazione non sia di sola lettura */
if(is_file($this->dest) AND !is_writeable($this->dest)) exit(“Error 2: The destination file it’s not writeable”);

/* Prende i dati dal file d’origine */
$this->gzdata = file_get_contents($this->source);

/* Comprime i dati del file d’origine */
$this->data = gzuncompress($this->gzdata);

/* Scrive i dati decompressi nel file di destinazione */
$this->status = file_put_contents($this->dest, $this->data);

/* Ritorna i valori positivi e negativi in base all’esito dell’operazione */
if($this->status) return TRUE; else return FALSE;
}
}
?>

Come vedete, ho creato solo due funzioni per questa classe, quelle fondamentali.
Analizziamo intanto la prima funzione, quella che comprime, poi passeremo
all’altra, che servirà a decomprimere il contenuto del file.
/* Controlla che il file d’origine esista e che sia leggibile */
if(!is_readable($this->source)) exit(“Error 1: Source file doesn’t exists or it’s not readable!<br>”);

/* Controlla che il file di destinazione non sia di sola lettura */
if(is_file($this->dest)) AND !is_writeable($this->dest)) exit(“Error 2: The destination file isn’t writeable”);

Sono due controlli, il primo verifica che il file sorgente sia leggibile, con
la funzione is_readable() e la seconda, che sia scrivibile, con la funzione
is_writeable().
In caso di errore, interrompono lo script e stampano un messaggio di errore.
/* Arrotonda il livello di compressione */
$this->level = round($this->level);

/* Controlla il livello e se è troppo grande, lo porta al massimo */
if($this->level == ‘MAX’ OR $this->level > 9) $this->level = 9;

/* Controlla il livello e se è troppo piccolo, lo porta al minimo */
if($this->level == ‘MIN’ OR $this->level < 1) $this->level = 1;

Servono ad arrotondare il livello di compressione, ed a portarlo ad una cifra
accettabile.
round() serve ad arrotondare il numero.
I due controlli, servono invece per ridurre o aumentare il numero se è troppo
grande o troppo piccolo. Si possono utilizzare anche ‘MIN’ o ‘MAX’ per portarli
al minimo od al massimo.
/* Prende i dati dal file d’origine */
$this->data = file_get_contents($this->source);
[/code]
File_Get_Contents()serve a leggere un file ed a memorizzare
il suo contenuto in una variabile, in questo caso $this->data.
/* Comprime i dati del file d’origine */
$this->gzdata = gzcompress($this->data, $this->level);

Questa è la vera funzione che esercita la compressione: gzcompress()
che comprime il file secondo il metodo COMPRESS. Gli argomenti sono: Il testo da
comprimere ed il livello di compressione.
/* Scrive i dati compressi nel file di destinazione */
$this->status = file_put_contents($this->dest, $this->gzdata);

/* Ritorna i valori positivi e negativi in base all’esito dell’operazione */
if($this->status) return TRUE; else return FALSE;

File_Put_Contentssvolge invece il compito di scrivere nel file:
Gli argomenti sono: Il percorso del file ed il contenuto da scrivere, in questo
caso il contenuto compresso. Se il file non esiste, lo crea. Inoltre la funzione
ritorna TRUE o FALSE in base all’esito della scrittura nel file di destinazione.

Così abbiamo spiegato come si comprimo i files, opportunamente verificando la
sintassi usata per gli argomenti. Ora spiegherò come decomprimare i file
compressi con il metodo COMPRESS:

/* Controlla che il file d’origine esista e che sia leggibile */
if(!is_readable($this->source)) exit(“Error 1: Source file doesn’t exists or it’s not readable!<br>”);

/* Controlla che il file di destinazione non sia di sola lettura */
if(is_file($this->dest)) AND !is_writeable($this->dest)) exit(“Error 2: The destination file it’s not writeable”);

Soliti controlli… Verifica che il file sorgente sia leggibile e che quello di
destinazione non sia di sola lettura (se esiste).
/* Prende i dati dal file d’origine */
$this->gzdata = file_get_contents($this->source);

Memorizza il contenuto del file in $this->gzdata
/* Comprime i dati del file d’origine */
$this->data = gzuncompress($this->gzdata);

Decomprime il file con la funzione gzuncompress(), che ha come unico argomento
il testo da decomprimere.

 

/* Scrive i dati decompressi nel file di destinazione */
$this->status = file_put_contents($this->dest, $this->data);

/* Ritorna i valori positivi e negativi in base all’esito dell’operazione */
if($this->status) return TRUE; else return FALSE;

Scrive i dati ‘puliti’ nel file di destinazione, e memorizza in $this->status
l’esito della scrittura.

Questa ulteriore classe, descrive come gestire più files in un’unico archivio
mediante serializzazione:

<?php
class gz_archive {

/* Inizializza le variabili */
var $source;
var $dest;
var $level;
var $pointer;
var $gzdata;
var $data;
var $status = TRUE;
var $key = 0;
var $files = array();
var $contents;
var $count;
var $fcontents;
var $path;

function gz_archive($path)
{
$this->path = $path;
}

function compress($source, $level)
{
/* Inizializza le variabili */
$this->source = $source;
$this->level = $level;

/* Controlla che $this->source sia un array */
if(!is_array($this->source)) exit(“The source input must be an array”);

/* Controlla che i files indicati nell’array esistano */
foreach($this->source AS $key => $value)
{
if(!is_file($this->source[$key])) exit(print_R($this->source[$key]) . ” isn’t a file”);
}

/* Arrotonda il livello di compressione */
$this->level = round($this->level);

/* Controlla il livello e se è troppo grande, lo porta al massimo */
if($this->level == ‘MAX’ OR $this->level > 9) $this->level = 9;

/* Controlla il livello e se è troppo piccolo, lo porta al minimo */
if($this->level == ‘MIN’ OR $this->level < 0) $this->level = 0;

/* Crea un array nel quale ci sarà il contenuto dei files */
$this->count = count($this->source);

while($this->data = file_get_contents($this->source[$this->key]))
{
print $this->data;
$this->fcontents[$this->source[$this->key]] = $this->data;
$this->key++;
if($this->key >= $this->count) break;
}

/* Serializza l’array */
$this->data = serialize($this->fcontents);

/* Comprime i dati del file d’origine */
$this->gzdata = gzcompress($this->data, $this->level);

/* Scrive i dati compressi nel file di destinazione */
$this->status = file_put_contents($this->path, $this->gzdata);

/* Ritorna i valori positivi e negativi in base all’esito dell’operazione */
if($this->status) return TRUE; else return FALSE;
}

function decompress()
{
/* Controlla se il file esiste o meno */
if(!is_file($this->path)) exit(“File doesn’t exists”);

/* Riceve l’array */
$this->data = file_get_contents($this->path) or exit(“Cannot read the file”);

/* Lo decomprime */
$this->data = gzuncompress($this->data);

/* E restituisce l’array */
$this->data = unserialize($this->data);

/* Installa i files */
foreach($this->data AS $filename => $contents)
{
print $contents;
if(!file_put_contents($filename, $contents)) $this->status = FALSE;
}

/* Ritorna i valori positivi e negativi in base all’esito dell’operazione */
if($this->status) return TRUE; else return FALSE;
}
}
?>

Il funzionamento è più o meno simile rispetto a quello della classe precedente, qui spiegherò
le differenze… Trattiamo prima la compressione:
/* Controlla che $this->source sia un array */
if(!is_array($this->source)) exit(“The source input must be an array”);

/* Controlla che i files indicati nell’array esistano */
foreach($this->source AS $key => $value)
{
if(!is_readable($this->source[$key])) exit(print_R($this->source[$key]) . ” isn’t a file or is’t readable”);
}

due controlli: Il primo controlla che $this->source sia un’array,
il secondo, che i percorsi indicati in esso siano leggibili.
/* Crea un array nel quale ci sarà il contenuto dei files */
$this->count = count($this->source);

while($this->data = file_get_contents($this->source[$this->key]))
{
$this->fcontents[$this->source[$this->key]] = $this->data;
$this->key++;
if($this->key >= $this->count) break;
}

/* Serializza l’array */
$this->data = serialize($this->fcontents);

la sostanziale differenza stà proprio qua:
Count() Conta gli elementi di un’array, in questo caso quello
contenente i percorsi dei files da comprimere.

Il while esegue l’operazione di recupero dei files dal percorso specificato, e
li memorizza in $this->fcontents, forse vi sarà di più difficile comprensione,
questo: $this->fcontents[$this->source[$this->key]] = $this->data; che memorizza
in $this->fcontents[‘percorso_del_file’] il suo contenuto.

Infine con serialize() Serializziamo l’array contenente
i files ed il loro percorso.
Poi crea l’archivio e vi mette dentro il contenuto compresso della serializzazione.

Per quanto riguarda la decompressione dell’archivio, il codice è mutato qui:

/* E restituisce l’array */
$this->data = unserialize($this->data);

/* Installa i files */
foreach($this->data AS $filename => $contents)
{
print $contents;
if(!file_put_contents($filename, $contents)) $this->status = FALSE;
}

In quanto, dopo che l’archivio è stato decompresso, bisogna deserializzarlo,
con la funzione unserialize() , che in questo caso restituirà l’array
precedentemente creato.
Il foreach, in questo caso, serve a ‘installare’ i files, nel percorso salvato
durante la creazione dell’archivio, e in caso di un qualsiasi errore, non blocca
lo script ma restuirà FALSE.

Questo metodo di compressione, come ho detto in precedenza, non è visualizzabile
con i programmi di gestione archivi, ma esiste la funzione gzencode()
che permette di farlo.

Esistono inoltre altri tipi di comrpessione GZ, Come quello DEFLATE:
Per creare archivi così, bisogna utilizzare la funzione gzdeflate()
che ha come argomenti i dati da comprimere e il livello di compressione.
Per poi decomprimere questo tipo di archivio, utilizzaremo la funzione gzinflate()
che ha come argomenti, i dati e (opzionale) la lunghezza del file.

Ora scriverò un paio di esempio per quanto riguarda l’utilizzo delle classi, sia
per i singoli che per gli archivi:

include(“./PaTeR_Class.php”);
// Esempio per la creazione di un file singolo
$singlegz = new gz_single();
$status = $singlegz->compress(“.\File_di_origine.txt”, “Nuovo_archivio_gz.txt.gz”, /* Livello di compressione */);
if(!$status) print “Errore durante la creazione dell’archivio gz”;

// Esempio per la decompressione dell’archivio gz
$singlegz = new gz_single();
$status = $singlegz->decompress(“File_gz_da_decomprimere.gz”, “Nuovo_file_decompresso.txt”);
if(!$status) print “Errore durante la decompressione dell’archivio gz”;

// Esempio creazione di un’archivio gz
$archivegz = new gz_archive(“.\Mio_archivio_gz.gz”);
$files = array(“.\file1.txt”, “.\file2.exe”, “.\file3.doc”);
$status = $archivegz->compress($files, /* Livello di compressione */);
if(!$status) print “Errore durante la creazione dell’archivio gz”;

// Esempio di estrazione di un’archivio gz
$archivegz = new gz_archive(“.\Mio_archivio_gz.gz”);
$status = $archivegz->decompress();
if(!$status) print “Errore durante la decompressione dell’archivio gz”;

Con tutto ciò, ho pensato di poter essere stato utile a qualcuno…
Perchè a volte può essere utile comprimere files o stringhe, specialmente quando
si lavora con file anche abbastanza grossi.

 

Questo tutorial è stato scritto da PATER