Ricerca…


Sintassi

  • int readfile (string $ filename [, bool $ use_include_path = false [, resource $ context]])

Parametri

Parametro Descrizione
nome del file Il nome del file viene letto.
use_include_path È possibile utilizzare il secondo parametro opzionale e impostarlo su TRUE, se si desidera cercare il file anche in include_path.
contesto Una risorsa di flusso di contesto.

Osservazioni

Sintassi del nome file

La maggior parte dei nomi di file passati a funzioni in questo argomento sono:

  1. Archi in natura.
    • I nomi dei file possono essere passati direttamente. Se vengono passati i valori di altri tipi, vengono convertiti in stringa. Questo è particolarmente utile con SplFileInfo , che è il valore SplFileInfo di DirectoryIterator .
  2. Relativo o assoluto.
    • Possono essere assoluti. Sui sistemi Unix, i percorsi assoluti iniziano con / , ad esempio /home/user/file.txt , mentre su Windows i percorsi assoluti iniziano con l'unità, ad es. C:/Users/user/file.txt
    • Possono anche essere relativi, che dipende dal valore di getcwd e soggetti a modifiche da parte di chdir .
  3. Accetta i protocolli.
    • Possono iniziare con scheme:// per specificare il wrapper del protocollo con cui gestire. Ad esempio, file_get_contents("http://example.com") recupera il contenuto da http://example.com .
  4. Slash-compatibili.
    • Mentre il DIRECTORY_SEPARATOR su Windows è una barra rovesciata e il sistema restituisce i backslash per i percorsi per impostazione predefinita, lo sviluppatore può ancora usare / come separatore di directory. Pertanto, per ragioni di compatibilità, gli sviluppatori possono utilizzare / come separatori di directory su tutti i sistemi, ma tenere presente che i valori restituiti dalle funzioni (ad es. realpath ) possono contenere barre retroverse.

Eliminazione di file e directory

Eliminazione di file

La funzione di unlink cancella un singolo file e restituisce se l'operazione ha avuto successo.

$filename = '/path/to/file.txt';

if (file_exists($filename)) {
    $success = unlink($filename);
    
    if (!$success) {
         throw new Exception("Cannot delete $filename");
    }
}

Eliminazione di directory, con eliminazione ricorsiva

D'altra parte, le directory dovrebbero essere cancellate con rmdir . Tuttavia, questa funzione elimina solo le directory vuote. Per eliminare una directory con file, eliminare prima i file nelle directory. Se la directory contiene sottodirectory, potrebbe essere necessaria la ricorsione .

L'esempio seguente esegue la scansione dei file in una directory, cancella i file / directory dei membri in modo ricorsivo e restituisce il numero di file (non di directory) cancellati.

function recurse_delete_dir(string $dir) : int {
    $count = 0;

    // ensure that $dir ends with a slash so that we can concatenate it with the filenames directly
    $dir = rtrim($dir, "/\\") . "/";

    // use dir() to list files
    $list = dir($dir);

    // store the next file name to $file. if $file is false, that's all -- end the loop.
    while(($file = $list->read()) !== false) {
        if($file === "." || $file === "..") continue;
        if(is_file($dir . $file)) {
            unlink($dir . $file);
            $count++;
        } elseif(is_dir($dir . $file)) {
            $count += recurse_delete_dir($dir . $file);
        }
    }

    // finally, safe to delete directory!
    rmdir($dir);

    return $count;
}

Funzioni di convenienza

IO diretto raw

file_get_contents e file_put_contents forniscono la possibilità di leggere / scrivere da / su un file da / a una stringa PHP in una singola chiamata.

file_put_contents può anche essere utilizzato con il flag di FILE_APPEND da aggiungere a, anziché troncare e sovrascrivere il file. Può essere usato insieme alla LOCK_EX bit LOCK_EX per acquisire un blocco esclusivo per il file mentre si procede alla scrittura. I flag di bitmask possono essere uniti con | Operatore OR bit a bit.

$path = "file.txt";
// reads contents in file.txt to $contents
$contents = file_get_contents($path);
// let's change something... for example, convert the CRLF to LF!
$contents = str_replace("\r\n", "\n", $contents);
// now write it back to file.txt, replacing the original contents
file_put_contents($path, $contents);

FILE_APPEND è utile per aggiungere file di registro mentre LOCK_EX aiuta a prevenire le condizioni di competizione della scrittura di file da più processi. Ad esempio, per scrivere in un file di registro relativo alla sessione corrente:

file_put_contents("logins.log", "{$_SESSION["username"]} logged in", FILE_APPEND | LOCK_EX);

CSV IO

fgetcsv($file, $length, $separator)

fgetcsv analizza la riga dal controllo di file aperti per i campi csv. Restituisce i campi CSV in una matrice in caso di successo o FALSE in caso di errore.

Per impostazione predefinita, leggerà solo una riga del file CSV.

$file = fopen("contacts.csv","r");
print_r(fgetcsv($file));    
print_r(fgetcsv($file,5," "));
fclose($file); 

contacts.csv

Kai Jim, Refsnes, Stavanger, Norway
Hege, Refsnes, Stavanger, Norway

Produzione:

Array
(
    [0] => Kai Jim
    [1] => Refsnes
    [2] => Stavanger
    [3] => Norway
)
Array
(
    [0] => Hege,
)

Lettura diretta di un file su stdout

readfile copia un file nel buffer di output. readfile () non presenterà alcun problema di memoria, nemmeno durante l'invio di file di grandi dimensioni, da solo.

$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($file).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}

O da un puntatore di file

In alternativa, per cercare un punto nel file per iniziare a copiare su stdout, usa invece fpassthru . Nell'esempio seguente, gli ultimi 1024 byte vengono copiati su stdout:

$fh = fopen("file.txt", "rb");
fseek($fh, -1024, SEEK_END); 
fpassthru($fh);

Lettura di un file in un array

file restituisce le righe nel file passato in un array. Ogni elemento dell'array corrisponde a una linea nel file, con il newline ancora collegato.

print_r(file("test.txt"));

test.txt

Welcome to File handling
This is to test file handling

Produzione:

Array 
( 
    [0] => Welcome to File handling 
    [1] => This is to test file handling 
)

Ottenere informazioni sui file

Controlla se un percorso è una directory o un file

La funzione is_dir restituisce se l'argomento è una directory, mentre is_file restituisce se l'argomento è un file. Usa file_exists per verificare se lo è.

$dir  = "/this/is/a/directory";
$file = "/this/is/a/file.txt";

echo is_dir($dir) ? "$dir is a directory" : "$dir is not a directory", PHP_EOL,
    is_file($dir) ? "$dir is a file" : "$dir is not a file", PHP_EOL,
    file_exists($dir) ? "$dir exists" : "$dir doesn't exist", PHP_EOL,
    is_dir($file) ? "$file is a directory" : "$file is not a directory", PHP_EOL,
    is_file($file) ? "$file is a file" : "$file is not a file", PHP_EOL,
    file_exists($file) ? "$file exists" : "$file doesn't exist", PHP_EOL;

Questo da:

/this/is/a/directory is a directory
/this/is/a/directory is not a file
/this/is/a/directory exists
/this/is/a/file.txt is not a directory
/this/is/a/file.txt is a file
/this/is/a/file.txt exists

Controllo del tipo di file

Usa filetype per verificare il tipo di file, che può essere:

  • fifo
  • char
  • dir
  • block
  • link
  • file
  • socket
  • unknown

Passando direttamente il nome del file al tipo di filetype :

echo filetype("~"); // dir

Si noti che filetype restituisce false e attiva E_WARNING se il file non esiste.

Controllo della leggibilità e della scrittura

Passando il nome file alle funzioni is_writable e is_readable , verificare se il file è scrivibile o leggibile rispettivamente.

Le funzioni restituiscono false garbo se il file non esiste.

Controllo dell'accesso ai file / modifica del tempo

L'utilizzo di filemtime e fileatime restituisce il timestamp dell'ultima modifica o accesso del file. Il valore di ritorno è un timestamp Unix - vedi Lavorare con date e orari per i dettagli.

echo "File was last modified on " . date("Y-m-d", filemtime("file.txt"));
echo "File was last accessed on " . date("Y-m-d", fileatime("file.txt"));

Ottieni parti del percorso con fileinfo

$fileToAnalyze = ('/var/www/image.png');

$filePathParts = pathinfo($fileToAnalyze);

echo '<pre>';
   print_r($filePathParts);
echo '</pre>';

Questo esempio produrrà:

Array
(
    [dirname] => /var/www
    [basename] => image.png
    [extension] => png
    [filename] => image
)

Che può essere usato come:

$filePathParts['dirname']
$filePathParts['basename']
$filePathParts['extension']
$filePathParts['filename']
Parametro Dettagli
$ path Il percorso completo del file da analizzare
$ opzione Una delle quattro opzioni disponibili [PATHINFO_DIRNAME, PATHINFO_BASENAME, PATHINFO_EXTENSION o PATHINFO_FILENAME]
  • Se non viene passata un'opzione (il secondo parametro), viene restituito un array associativo, altrimenti viene restituita una stringa.
  • Non convalida che il file esiste.
  • Semplicemente analizza la stringa in parti. Nessuna convalida sul file (nessun controllo di tipo mime, ecc.)
  • L'estensione è semplicemente l'ultima estensione di $path Il percorso per il file image.jpg.png sarebbe .png anche se tecnicamente un file .jpg . Un file senza un'estensione non restituirà un elemento di estensione nell'array.

Riduci al minimo l'utilizzo della memoria quando lavori con file di grandi dimensioni

Se abbiamo bisogno di analizzare un file di grandi dimensioni, ad esempio un CSV più di 10 Mbyte contenente milioni di righe, alcuni usano file funzioni file o file_get_contents e finiscono col colpire memory_limit impostazione memory_limit con

Dimensione di memoria consentita di byte XXXXX esauriti

errore. Considera la seguente fonte (top-1m.csv ha esattamente 1 milione di righe e ha una dimensione di circa 22 Mbyte)

var_dump(memory_get_usage(true));
$arr = file('top-1m.csv');
var_dump(memory_get_usage(true));

Questo produce:

int(262144)
int(210501632) 

perché l'interprete doveva contenere tutte le righe nell'array $arr , quindi consumava ~ 200 Mbyte di RAM. Nota che non abbiamo ancora fatto nulla con il contenuto dell'array.

Ora considera il seguente codice:

var_dump(memory_get_usage(true));
$index = 1;
if (($handle = fopen("top-1m.csv", "r")) !== FALSE) {
    while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
        file_put_contents('top-1m-reversed.csv',$index . ',' . strrev($row[1]) . PHP_EOL, FILE_APPEND);
        $index++;
    }
    fclose($handle);
}
var_dump(memory_get_usage(true));

quali uscite

int(262144)
int(262144)

quindi non usiamo un singolo byte di memoria in più, ma analizziamo l'intero CSV e lo salviamo su un altro file invertendo il valore della seconda colonna. Questo perché fgetcsv legge solo una riga e $row viene sovrascritta in ogni ciclo.

File IO basato su streaming

Aprire un flusso

fopen apre un handle di file stream, che può essere utilizzato con varie funzioni per la lettura, scrittura, ricerca e altre funzioni su di esso. Questo valore è di tipo di resource e non può essere passato ad altri thread mantenendo la sua funzionalità.

$f = fopen("errors.log", "a"); // Will try to open errors.log for writing

Il secondo parametro è la modalità del flusso di file:

Modalità Descrizione
r Apri in modalità di sola lettura, iniziando dall'inizio del file
r+ Aperto per leggere e scrivere, a partire dall'inizio del file
w aperto solo per scrittura, a partire dall'inizio del file. Se il file esiste, svuoterà il file. Se non esiste cercherà di crearlo.
w+ aperto per leggere e scrivere, a partire dall'inizio del file. Se il file esiste, svuoterà il file. Se non esiste cercherà di crearlo.
a apri un file solo per scrittura, a partire dalla fine del file. Se il file non esiste, proverà a crearlo
a+ apri un file per leggere e scrivere, iniziando alla fine del file. Se il file non esiste, proverà a crearlo
x crea e apri un file solo per scrittura. Se il file esiste, la chiamata fopen fallirà
x+ crea e apri un file per leggere e scrivere. Se il file esiste, la chiamata fopen fallirà
c apri il file solo per scrittura. Se il file non esiste, proverà a crearlo. Comincerà a scrivere all'inizio del file, ma non svuoterà il file prima della scrittura
c+ apri il file per leggere e scrivere. Se il file non esiste, proverà a crearlo. Comincerà a scrivere all'inizio del file, ma non svuoterà il file prima della scrittura

L'aggiunta di una t alla modalità (es. A a+b , wt , ecc.) In Windows tradurrà "\n" terminazioni di riga in "\r\n" quando si lavora con il file. Aggiungi b dietro la modalità se questo non è previsto, specialmente se si tratta di un file binario.

L'applicazione PHP deve chiudere gli stream utilizzando fclose quando non vengono più utilizzati per impedire l'errore Too many open files . Ciò è particolarmente importante nei programmi CLI, dal momento che gli stream vengono chiusi solo quando il runtime si arresta, questo significa che nei web server potrebbe non essere necessario (ma dovrebbe comunque, come pratica per prevenire perdite di risorse) chiudere i flussi se non si prevede che il processo venga eseguito per un lungo periodo e non si apriranno più flussi.

Lettura

L'uso di fread leggerà il numero dato di byte dal puntatore del file o fino a quando non viene raggiunto un EOF.

Linee di lettura

L'uso di fgets leggerà il file fino a quando non viene raggiunto un EOL o viene letta la lunghezza specificata.

Sia fread che fgets spostano il puntatore del file durante la lettura.

Leggendo tutto ciò che rimane

Usando stream_get_contents tutti i byte restanti nello stream vengono stream_get_contents in una stringa e restituiti.

Regolazione della posizione del puntatore del file

Inizialmente dopo aver aperto lo stream, il puntatore del file si trova all'inizio del file (o alla fine, se si utilizza la modalità a ). L'uso della funzione fseek sposta il puntatore del file in una nuova posizione, relativa a uno dei tre valori:

  • SEEK_SET : questo è il valore predefinito; l'offset della posizione del file sarà relativo all'inizio del file.
  • SEEK_CUR : lo spostamento della posizione del file sarà relativo alla posizione corrente.
  • SEEK_END : l'offset della posizione del file sarà relativo alla fine del file. Passare un offset negativo è l'uso più comune di questo valore; sposterà la posizione del file sul numero specificato di byte prima della fine del file.

rewind è una comoda scorciatoia di fseek($fh, 0, SEEK_SET) .

Utilizzando ftell mostrerà la posizione assoluta del puntatore del file.

Ad esempio, il seguente script legge salta i primi 10 byte, legge i 10 byte successivi, salta 10 byte, legge i 10 byte successivi e quindi gli ultimi 10 byte in file.txt:

$fh = fopen("file.txt", "rb");
fseek($fh, 10); // start at offset 10
echo fread($fh, 10); // reads 10 bytes
fseek($fh, 10, SEEK_CUR); // skip 10 bytes
echo fread($fh, 10); // read 10 bytes
fseek($fh, -10, SEEK_END); // skip to 10 bytes before EOF
echo fread($fh, 10); // read 10 bytes
fclose($fh);

scrittura

L'utilizzo di fwrite scrive la stringa fornita nel file partendo dal puntatore del file corrente.

fwrite($fh, "Some text here\n");

Spostamento e copia di file e directory

Copia di file

copy copia il file sorgente nel primo argomento nella destinazione nel secondo argomento. La destinazione risolta deve trovarsi in una directory già creata.

if (copy('test.txt', 'dest.txt')) {
    echo 'File has been copied successfully';
} else {
    echo 'Failed to copy file to destination given.'
}

Copia di directory, con ricorsione

Copiare le directory è molto simile all'eliminazione delle directory, ad eccezione del fatto che per la copy file invece di usare lo unlink , mentre per le directory si utilizza mkdir invece di rmdir , all'inizio invece di trovarsi alla fine della funzione.

function recurse_delete_dir(string $src, string $dest) : int {
    $count = 0;

    // ensure that $src and $dest end with a slash so that we can concatenate it with the filenames directly
    $src = rtrim($dest, "/\\") . "/";
    $dest = rtrim($dest, "/\\") . "/";

    // use dir() to list files
    $list = dir($src);

    // create $dest if it does not already exist
    @mkdir($dest);

    // store the next file name to $file. if $file is false, that's all -- end the loop.
    while(($file = $list->read()) !== false) {
        if($file === "." || $file === "..") continue;
        if(is_file($src . $file)) {
            copy($src . $file, $dest . $file);
            $count++;
        } elseif(is_dir($src . $file)) {
            $count += recurse_copy_dir($src . $file, $dest . $file);
        }
    }

    return $count;
}

Rinominare / Moving

Rinominare / spostare file e directory è molto più semplice. Intere directory possono essere spostate o rinominate in una singola chiamata, usando la funzione di rename .

  • rename("~/file.txt", "~/file.html");

  • rename("~/dir", "~/old_dir");

  • rename("~/dir/file.txt", "~/dir2/file.txt");



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow