Una panoramica approfondita delle operazioni sui file in PHP

In questo tutorial Tuts + Premium impareremo come lavorare con le operazioni sui file usando PHP. Questo è uno degli argomenti più fondamentali della programmazione lato server in generale. I file vengono utilizzati nelle applicazioni Web di tutte le dimensioni. Quindi impariamo come leggere, scrivere, creare, spostare, copiare, cancellare file e altro.


Anteprima Screencast



Copia, spostamento ed eliminazione di file

Iniziamo con queste operazioni a imparare, perché sono molto semplici su un solo liner e non implicano la gestione dei puntatori di file.

Copia di un file

 $ file = "test.txt"; $ new_file = "test_copy.txt"; copia ($ file, $ newfile);

Spostare un file

 $ file = "test.txt"; $ new_file = "test_copy.txt"; rinomina ($ file, $ newfile);

Si noti che la funzione è chiamata "rinomina" e non "sposta". Internamente, rinominare un file equivale a spostarlo in una nuova posizione.

Lo stesso codice funziona quando si modifica la directory del file:

 $ file = "test.txt"; $ new_file = "different / folder / test_copy.txt"; rinomina ($ file, $ newfile);

Eliminazione di un file

Non esiste una funzione come "cancella". Qui chiamiamo la funzione "unlink".

 $ file = "test.txt"; scollegare ($ file, $ newfile);

Apertura e lettura di un file

Ora è il momento di iniziare a trattare con alcuni puntatori di file. C'è più di un modo di leggere il contenuto di un file in PHP, ma per prima cosa inizieremo con il metodo più basilare. Più avanti nell'articolo impareremo i metodi alternativi.

Ci sono tre funzioni di file che useremo qui: fopen, fread e fclose.

 $ file = "test.txt"; // apri il file $ fp = fopen ($ file, "r"); // legge i dati 5k dal file $ contents = fread ($ fp, 5000); // chiudi il file fclose ($ fp);

Quando apriamo il file, includiamo un secondo parametro, che determina il tipo di accesso. In questo caso "r" sta per "sola lettura". Ci sono altri tipi che dobbiamo usare per la scrittura e l'aggiunta che copriremo più avanti nell'articolo.

La seconda cosa importante a cui prestare attenzione è il secondo parametro nella funzione di fread. Questo determina la lunghezza dei dati (in byte) da leggere dal file. Per leggere l'intero contenuto del file, dobbiamo passare la dimensione totale del file. La funzione filesize fa il trucco:

 $ file = "test.txt"; // apri il file $ fp = fopen ($ file, "r"); // legge i dati 5k dal file $ contents = fread ($ fp, filesize ($ file)); // chiudi il file fclose ($ fp);

Screencast completo



Capire i puntatori di file

Da quando abbiamo iniziato a lavorare con i puntatori di file, prendiamo un momento e proviamo a capirli meglio.

Un puntatore di file, noto anche come file "handle", è una variabile che fa riferimento a un file. Il valore esatto di questa variabile non è importante; tutto quello che dobbiamo sapere è che punta a un file specifico. Il puntatore viene solitamente ottenuto aprendo un file. In PHP usiamo la funzione fopen.

Anche se PHP ha un eccellente garbage collector che chiude tutti i puntatori di file aperti al termine dell'esecuzione di uno script, è buona pratica chiuderli manualmente usando la funzione fclose.

 $ fp = fopen ($ file, 'r'); // ... // chiude sempre i file fclose ($ fp);

Posizione in un file

Il puntatore del file non fa altro che puntare a un file. Indica anche una posizione specifica all'interno di quel file. Nella maggior parte dei casi, quando apri un file, il puntatore del file punta all'inizio (o alla posizione 0) in quel file. Tratteremo questo concetto in modo più dettagliato quando parliamo di "cercare" più avanti nell'articolo.


Scrivere su un file

Proprio come leggere i file, c'è più di un modo di scrivere su un file. Per prima cosa vedremo il modo di base, e più avanti nell'articolo vedremo le alternative.

Il seguente codice scrive il contenuto della variabile $ data nel file test.txt.

 $ file = "test.txt"; $ data = "0123456789abc"; // apri il file per scrivere $ fp = fopen ($ file, "w"); // scrive i dati sul file fwrite ($ fp, $ data); // chiudi il file fclose ($ fp);

Questa volta abbiamo usato un flag diverso per aprire il file. Il flag "w" apre il file per la scrittura e sovrascrive tutti i dati esistenti nel file. Se c'era qualcosa nel file test.txt, sarà sostituito con la stringa in $ data.

La funzione fwrite era molto semplice, abbiamo appena passato il puntatore del file e i dati da scrivere sul file. Esiste un terzo parametro opzionale che determina la lunghezza dei dati da scrivere:

 $ file = "test.txt"; $ data = "0123456789abc"; // apri il file per scrivere $ fp = fopen ($ file, "w"); // scrive i dati nel file (solo 5 byte) fwrite ($ fp, $ data, 5); // chiudi il file fclose ($ fp);

Se esegui il codice sopra, il contenuto di test.txt sarà solo "01234".

Creare un nuovo file

Gli esempi sopra funzionano anche per la creazione di nuovi file. Se il file test.txt non esiste, verrà creato automaticamente, solo tramite la chiamata alla funzione fopen.

Se tutto quello che vuoi fare è creare un nuovo file vuoto, senza scrivere alcun dato in esso, questo codice funzionerà:

 $ file = "does_not_exist.txt"; // crea e apre il file $ fp = fopen ($ file, "w"); // chiudi il file fclose ($ fp);

Cerco

L'atto di spostare la posizione dei puntatori di file è chiamato "ricerca". Per cercare possiamo usare la funzione fseek, e per ottenere la posizione di un dato puntatore, possiamo usare la funzione ftell.

Prima di utilizzare la ricerca, creiamo un file con 10 byte di dati al suo interno.

 $ file = "test.txt"; $ data = "0123456789"; $ fp = fopen ($ file, "w"); fwrite ($ fp, $ data); fclose ($ fp);

Ora vediamo come si comportano queste funzioni. Ecco alcuni esempi diversi:

 $ file = "test.txt"; // aprendo per la lettura, il puntatore dovrebbe essere a 0 $ fp = fopen ($ file, "r"); echo "open:"; // output 0 echo ftell ($ fp). "\ n"; // ----- // cerca il byte 4 fseek ($ fp, 4); echo "seek 4:"; // output 4 echo ftell ($ fp). "\ n"; // ----- // puoi uscire dai limiti fseek ($ fp, 9000); echo "fuori limite:"; // output 9000 echo ftell ($ fp). "\ n"; // ---- // questo è come si arriva alla fine fseek ($ fp, 0, SEEK_END); echo "end:"; // output 10 echo ftell ($ fp). "\ n"; // ---- // sposta relativo alla posizione corrente // i numeri negativi funzionano fseek ($ fp, -3, SEEK_CUR); echo "torna indietro di 3:"; // output 7 echo ftell ($ fp). "\ n"; // ---- // o cerca relativo alla fine // di nuovo, negativo funziona fseek ($ fp, -3, SEEK_END); echo "torna indietro di 3 dalla fine:"; // output 7 echo ftell ($ fp). "\ n"; // ---- // fa la stessa cosa che cerca di 0 rewind ($ fp); echo "rewind:"; // output 0 echo ftell ($ fp). "\ n"; fclose ($ fp);

Altre operazioni Spostamento della posizione del puntatore di file

La posizione del puntatore del file può spostarsi con operazioni diverse da fseek.

Ad esempio, la lettura sposta la posizione:

 $ file = "test.txt"; $ fp = fopen ($ file, "r"); // lettura di 6 byte $ data = fread ($ fp, 6); // output 6 echo ftell ($ fp); fclose ($ fp);

Anche la scrittura lo muove:

 $ file = "test.txt"; $ data = "0123456789"; $ fp = fopen ($ file, "w"); // scrivendo 10 byte fwrite ($ fp, $ data); // output 10 echo ftell ($ fp); fclose ($ fp);

Modalità di accesso ai file

Ora che conosciamo i concetti di lettura, scrittura e ricerca, è ora di capire meglio le diverse modalità di accesso ai file. Quando si apre un file con la funzione fopen, deve essere fornito il secondo parametro, che è la modalità di accesso al file. C'è una tabella nel manuale PHP che li descrive:


Osservandoli, puoi vedere che abbiamo più opzioni di quante ne abbiamo discusse finora. Ecco alcuni fattori importanti da considerare sulla scelta dell'opzione giusta:

  • L'apertura con 'r +' fallirà, se il file non è scrivibile, anche se si vuole solo leggere e non scrivere ad esso.
  • Sia 'w' che 'w +' cancelleranno completamente il contenuto di un file esistente non appena lo apri. Se intendi aggiungere dati, devi usare 'a' o 'a +'.
  • Se vuoi creare nuovi file e anche evitare la sovrascrittura accidentale e il file esistente, usa "x" o "x +".
  • Quando si lavora con file binari, come immagini, aggiungere la lettera "b" dopo la modalità. Ad esempio: 'rb' o 'r + b'

Ottenere informazioni sui file

Ci sono molte informazioni che possiamo ottenere su un file oltre al suo contenuto (dimensioni, ultimo tempo di accesso, modifica del tempo ecc ...) La funzione principale utilizzata per questo è stat.

Restituisce le informazioni in un array:

 $ data = stat ("test.txt"); print_r ($ data); / * stampa: Array ([0] => 2 [1] => 0 [2] => 33206 [3] => 1 [4] => 0 [5] => 0 [6] => 2 [7 ] => 10 [8] => 1264374556 [9] => 1264374556 [10] => 1264373231 [11] => -1 [12] => -1 [dev] => 2 [ino] => 0 [modo ] => 33206 [nlink] => 1 [uid] => 0 [gid] => 0 [rdev] => 2 [dimensione] => 10 [atime] => 1264374556 [mtime] => 1264374556 [ctime] = > 1264373231 [blksize] => -1 [blocks] => -1) * /

I dati sono in 12 parti e vengono ripetuti, prima con i tasti numerici e poi di nuovo con i tasti di stringa.

Il manuale PHP ha una tabella che spiega ciascuno di essi:



Funzioni alternative

Come ho detto prima, ci sono altre funzioni alternative che possono essere utilizzate per leggere e scrivere file. Andiamo su alcuni di loro.

file_get_contents

Questa funzione restituisce l'intero contenuto di un determinato file. Inoltre non è necessario trattare con i puntatori di file.

 $ file = "test.txt"; $ contents = file_get_contents ($ file);

La funzione accetta altri quattro parametri aggiuntivi come descritto nel manuale PHP. Ad esempio, per leggere solo una parte del file, puoi impostare il quarto e il quinto parametro:

 $ file = "test.txt"; // legge 5 byte di dati, a partire dal byte 3 $ contents = file_get_contents ($ file, NULL, NULL, 3, 5);

file

Sì, questa funzione è semplicemente denominata file e restituisce di nuovo l'intero contenuto di un file. Ma questa volta, i contenuti sono divisi in una matrice, dal carattere di nuova riga.

Creiamo un file con i seguenti contenuti:

 abc 123 riga vuota dopo quest'ultima riga

Ora usa la funzione:

 $ file = "test.txt"; $ contenuto = file ($ file); print_r ($ contenuto); / * stampa Array ([0] => abc [1] => 123 [2] => riga vuota dopo questo [3] => [4] => ultima riga) * /

Potrebbe non essere ovvio, ma c'è un carattere di fine riga a ogni elemento dell'array. Se non li vuoi, puoi eliminarli manualmente o utilizzare il flag FILE_IGNORE_NEW_LINES:

 $ file = "test.txt"; $ contents = file ($ file, FILE_IGNORE_NEW_LINES); print_r ($ contenuto); / * stampa Array ([0] => abc [1] => 123 [2] => riga vuota dopo questo [3] => [4] => ultima riga) * /

Se non vuoi neanche le linee vuote, puoi usare il flag FILE_SKIP_EMPTY_LINES:

 $ file = "test.txt"; $ contents = file ($ file, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES); print_r ($ contenuto); / * stampa Array ([0] => abc [1] => 123 [2] => riga vuota dopo questo [3] => ultima riga) * /

file_put_contents

Ancora una volta, non è necessario utilizzare i puntatori di file. Questa funzione scrive semplicemente i dati dati nel file specificato:

 $ file = "test.txt"; $ data = "0123456789"; file_put_contents ($ file, $ dati);

filesize, fileatime, filemtime

Queste sono alternative alla funzione stat per ottenere informazioni sui file.

 $ file = "test.txt"; // ottiene la dimensione del file echo filesize ($ file); // ottiene l'ultima volta che il file è stato modificato echo filemtime ($ file); // ottiene l'ultima volta che si accede al file echo fileatime ($ file);

Autorizzazioni per i file

I sistemi di tipo Unix hanno uno standard di autorizzazioni di file abbastanza dettagliato. I sistemi Windows hanno un po 'più semplice. L'intero argomento delle autorizzazioni per i file può essere lungo e un intero articolo separato può essere scritto su di esso. Quindi, guarderemo solo due semplici concetti di permessi sui file: essere "leggibili" ed essere "scrivibili".

Verifica delle autorizzazioni

Lo script può o non può avere accesso in lettura e / o scrittura a un file a causa di vari motivi. Prima di tentare di aprire un file per leggere o scrivere, è opportuno verificare se si dispone dell'autorizzazione per farlo:

 $ file = "test.txt"; if (is_readable ($ file)) // file è leggibile if (is_writable ($ file)) // file è scrivibile

Impostazione delle autorizzazioni

Per impostare i permessi di un file, usiamo la funzione chmod:

 $ file = "test.txt"; // rende il file chmod di sola lettura ($ file, 0444); // rende il file leggibile e scrivibile chmod ($ file, 0666);

Il codice sopra dovrebbe funzionare su entrambi i sistemi Unix e Windows. Tuttavia, potresti non essere in grado di impostare le autorizzazioni, se non sei il proprietario del file o se disponi di autorizzazioni in primo luogo.

Per comprendere meglio le autorizzazioni chmod e file in generale, puoi controllare questi collegamenti:

  • Informazioni sui permessi dei file su Unix: un breve tutorial
  • Autorizzazioni file e cartelle in Windows
  • chmod voce di Wikipedia
  • Pagina manuale per chmod

Utilizzo di cicli per file grandi

L'ultima cosa di cui parleremo è un consiglio rapido per la gestione di file di grandi dimensioni. Questo ha alcune implicazioni sulle prestazioni.

Il modo più semplice per leggere ed emettere un file è questo:

 $ file = "test.txt"; echo file_get_contents ($ file);

Ma questo fa sì che l'intero contenuto del file venga caricato nella memoria. Rimarrà finché viene scaricato dal navigatore web. Se più persone stanno scaricando i file contemporaneamente, ciò può consumare la memoria dei server Web molto rapidamente.

Un'idea migliore per gestirlo sarebbe utilizzare un ciclo per leggere solo piccoli blocchi del file alla volta. Per la condizione del ciclo utilizzeremo la funzione feof:

 $ file = "test.txt"; $ fp = fopen ($ file, 'r'); while (! feof ($ fp)) echo fread ($ fp, 4092);  fclose ($ fp);

Il codice sopra caricherà solo 4kb di dati in una sola volta nella memoria e questo ridurrà notevolmente l'utilizzo della memoria per le uscite di file di grandi dimensioni. La funzione feof restituisce true quando raggiungiamo la fine del file e questo si interrompe.