• User Newbie

    [Tutorial] Funzioni GZ con PHP

    dopo la penalizzazione avvenuta nei mesi scorsi agli spinoff di couponing dei quotidiani online in inghilterra e in usa, possiamo attenderci che accada qualche cosa anche negli paesi europei? inclusa l'Italia? con i vari:

    https://www.ansa.it/codici-sconto/
    https://www.focus.it/codice-sconto/
    https://www.repubblica.it/codici-sconto/
    https://www.gazzetta.it/codici-sconto/
    https://codicesconto.corriere.it/codice-sconto/
    https://descuentos.elpais.com/
    https://gutscheine.spiegel.de/

    ... giusto per citarne alcuni


  • Super User

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

    
    <?php
    class gz_archive &#123;
    
        /* Inizializza le variabili */
        var $source;
        var $dest;
        var $level;
        var $pointer;
        var $gzdata;
        var $data;
        var $status = TRUE;
        var $key = 0;
        var $files = array&#40;&#41;;
        var $contents;
        var $count;
        var $fcontents;
        var $path;
    
        function gz_archive&#40;$path&#41;
        &#123;
            $this->path = $path;
        &#125;
    
        function compress&#40;$source, $level&#41;
        &#123;
            /* Inizializza le variabili */
            $this->source = $source;
            $this->level = $level;
            
            /* Controlla che $this->source sia un array */
            if&#40;!is_array&#40;$this->source&#41;&#41; exit&#40;"The source input must be an array"&#41;;
            
            /* Controlla che i files indicati nell'array esistano */
            foreach&#40;$this->source AS $key => $value&#41;
            &#123;
                if&#40;!is_file&#40;$this->source&#91;$key&#93;&#41;&#41; exit&#40;print_R&#40;$this->source&#91;$key&#93;&#41; . " isn't a file"&#41;;
            &#125;
    
            /* Arrotonda il livello di compressione */
            $this->level = round&#40;$this->level&#41;;
    
            /* Controlla il livello e se è troppo grande, lo porta al massimo */
            if&#40;$this->level == 'MAX' OR $this->level > 9&#41; $this->level = 9;
    
            /* Controlla il livello e se è troppo piccolo, lo porta al minimo */
            if&#40;$this->level == 'MIN' OR $this->level < 0&#41; $this->level = 0;
            
            /* Crea un array nel quale ci sarà il contenuto dei files */
            $this->count = count&#40;$this->source&#41;;
            
            while&#40;$this->data = file_get_contents&#40;$this->source&#91;$this->key&#93;&#41;&#41;
            &#123;
                print $this->data;
                $this->fcontents&#91;$this->source&#91;$this->key&#93;&#93; = $this->data;
                $this->key++;
                if&#40;$this->key >= $this->count&#41; break;
            &#125;
            
            /* Serializza l'array */
            $this->data = serialize&#40;$this->fcontents&#41;;
    
            /* Comprime i dati del file d'origine */
            $this->gzdata = gzcompress&#40;$this->data, $this->level&#41;;
    
            /* Scrive i dati compressi nel file di destinazione */
            $this->status = file_put_contents&#40;$this->path, $this->gzdata&#41;;
    
            /* Ritorna i valori positivi e negativi in base all'esito dell'operazione */
            if&#40;$this->status&#41; return TRUE; else return FALSE;
        &#125;
        
        function decompress&#40;&#41;
        &#123;
            /* Controlla se il file esiste o meno */
            if&#40;!is_file&#40;$this->path&#41;&#41; exit&#40;"File doesn't exists"&#41;;
            
            /* Riceve l'array */
            $this->data = file_get_contents&#40;$this->path&#41; or exit&#40;"Cannot read the file"&#41;;
    
            /* Lo decomprime */
            $this->data = gzuncompress&#40;$this->data&#41;;
            
            /* E restituisce l'array */
            $this->data = unserialize&#40;$this->data&#41;;
            
            /* Installa i files */
            foreach&#40;$this->data AS $filename => $contents&#41;
            &#123;
                print $contents;
                if&#40;!file_put_contents&#40;$filename, $contents&#41;&#41; $this->status = FALSE;
            &#125;
    
            /* Ritorna i valori positivi e negativi in base all'esito dell'operazione */
            if&#40;$this->status&#41; return TRUE; else return FALSE;
        &#125;
    &#125;
    ?>
    
    

    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&#40;!is_array&#40;$this->source&#41;&#41; exit&#40;"The source input must be an array"&#41;;
    
    /* Controlla che i files indicati nell'array esistano */
    foreach&#40;$this->source AS $key => $value&#41;
    &#123;
        if&#40;!is_readable&#40;$this->source&#91;$key&#93;&#41;&#41; exit&#40;print_R&#40;$this->source&#91;$key&#93;&#41; . " isn't a file or is't readable"&#41;;
    &#125;
    
    

    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&#40;$this->source&#41;;
    
    while&#40;$this->data = file_get_contents&#40;$this->source&#91;$this->key&#93;&#41;&#41;
    &#123;
        $this->fcontents&#91;$this->source&#91;$this->key&#93;&#93; = $this->data;
        $this->key++;
        if&#40;$this->key >= $this->count&#41; break;
    &#125;
    
    /* Serializza l'array */
    $this->data = serialize&#40;$this->fcontents&#41;;
    
    

    la sostanziale differenza stà proprio qua:
    [URL='http://it.php.net/count']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 [URL='http://it.php.net/serialize']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&#40;$this->data&#41;;
    
    /* Installa i files */
    foreach&#40;$this->data AS $filename => $contents&#41;
    &#123;
        print $contents;
        if&#40;!file_put_contents&#40;$filename, $contents&#41;&#41; $this->status = FALSE;
    &#125;
    
    

    In quanto, dopo che l'archivio è stato decompresso, bisogna deserializzarlo,
    con la funzione [URL='http://it.php.net/unserialize']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 [URL='http://it.php.net/gzencode']gzencode()
    che permette di farlo.

    Esistono inoltre altri tipi di comrpessione GZ, Come quello DEFLATE:
    Per creare archivi così, bisogna utilizzare la funzione [URL='http://it.php.net/gzdeflate']gzdeflate()
    che ha come argomenti i dati da comprimere e il livello di compressione.
    Per poi decomprimere questo tipo di archivio, utilizzaremo la funzione [URL='http://it.php.net/gzinflate']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&#40;"./PaTeR_Class.php"&#41;;
    // Esempio per la creazione di un file singolo
    $singlegz = new gz_single&#40;&#41;;
    $status = $singlegz->compress&#40;".\File_di_origine.txt", "Nuovo_archivio_gz.txt.gz", /* Livello di compressione */&#41;;
    if&#40;!$status&#41; print "Errore durante la creazione dell'archivio gz";
    
    // Esempio per la decompressione dell'archivio gz
    $singlegz = new gz_single&#40;&#41;;
    $status = $singlegz->decompress&#40;"File_gz_da_decomprimere.gz", "Nuovo_file_decompresso.txt"&#41;;
    if&#40;!$status&#41; print "Errore durante la decompressione dell'archivio gz";
    
    // Esempio creazione di un'archivio gz
    $archivegz = new gz_archive&#40;".\Mio_archivio_gz.gz"&#41;;
    $files = array&#40;".\file1.txt", ".\file2.exe", ".\file3.doc"&#41;;
    $status = $archivegz->compress&#40;$files, /* Livello di compressione */&#41;;
    if&#40;!$status&#41; print "Errore durante la creazione dell'archivio gz";
    
    // Esempio di estrazione di un'archivio gz
    $archivegz = new gz_archive&#40;".\Mio_archivio_gz.gz"&#41;;
    $status = $archivegz->decompress&#40;&#41;;
    if&#40;!$status&#41; print "Errore durante la decompressione dell'archivio gz";
    
    

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

    :ciauz: