Suche…


Syntax

  • int readfile (Zeichenfolge $ filename [, bool $ use_include_path = false [, Ressource $ context]])

Parameter

Parameter Beschreibung
Dateiname Der zu lesende Dateiname
use_include_path Sie können den optionalen zweiten Parameter verwenden und auf TRUE setzen, wenn Sie auch im include_path nach der Datei suchen möchten.
Kontext Eine Kontextstream-Ressource

Bemerkungen

Dateiname-Syntax

Die meisten Dateinamen, die an Funktionen in diesem Thema übergeben werden, sind:

  1. Zeichenketten in der Natur.
    • Dateinamen können direkt übergeben werden. Wenn Werte anderer Typen übergeben werden, werden sie in String umgewandelt. Dies ist besonders nützlich bei SplFileInfo , dem Wert in der Iteration von DirectoryIterator .
  2. Relativ oder absolut
    • Sie können absolut sein. Auf Unix-ähnlichen Systemen beginnen absolute Pfade mit / , z. B. /home/user/file.txt , während unter Windows absolute Pfade mit dem Laufwerk beginnen, z. B. C:/Users/user/file.txt
    • Sie können auch relativ sein, was vom Wert von getcwd abhängig ist und von chdir geändert werden kann.
  3. Protokolle akzeptieren.
    • Sie können mit scheme:// , um den Protokoll-Wrapper anzugeben, mit dem verwaltet werden soll. Beispielsweise file_get_contents("http://example.com") Inhalte von http://example.com ab .
  4. Slash-kompatibel.
    • Während der DIRECTORY_SEPARATOR unter Windows ein umgekehrter Schrägstrich ist und das System standardmäßig umgekehrte Schrägstriche für Pfade zurückgibt, kann der Entwickler / als Verzeichnistrennzeichen verwenden. Aus Kompatibilitätsgründen können Entwickler / als Verzeichnistrennzeichen auf allen Systemen verwenden. realpath jedoch, dass die von den Funktionen (z. B. realpath ) zurückgegebenen Werte möglicherweise Backslashes enthalten.

Dateien und Verzeichnisse löschen

Dateien löschen

Die unlink Funktion löscht eine einzelne Datei und gibt zurück, ob die Operation erfolgreich war.

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

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

Löschen von Verzeichnissen mit rekursiver Löschung

Zum anderen sollten Verzeichnisse mit rmdir gelöscht werden. Diese Funktion löscht jedoch nur leere Verzeichnisse. Um ein Verzeichnis mit Dateien zu löschen, löschen Sie zuerst die Dateien in den Verzeichnissen. Wenn das Verzeichnis Unterverzeichnisse enthält, ist möglicherweise eine Rekursion erforderlich.

Das folgende Beispiel durchsucht Dateien in einem Verzeichnis, löscht Mitgliedsdateien / Verzeichnisse rekursiv und gibt die Anzahl der gelöschten Dateien (nicht Verzeichnisse) zurück.

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

Komfortfunktionen

Rohes direktes IO

file_get_contents und file_put_contents bieten die Möglichkeit, in einem einzigen Aufruf von / in eine Datei in / aus einem PHP-String zu schreiben.

file_put_contents kann auch mit dem Bitmaske-Flag file_put_contents verwendet werden, um an die FILE_APPEND anzuhängen, anstatt sie FILE_APPEND und zu überschreiben. Sie kann zusammen mit der LOCK_EX Bitmaske verwendet werden, um beim Schreiben eine exklusive Sperre für die Datei zu erhalten. Bitmaskenflags können mit der | bitweises ODER-Operator.

$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 ist praktisch zum Anhängen an Protokolldateien, während LOCK_EX beiträgt, die Race-Bedingung beim Schreiben von Dateien aus mehreren Prozessen zu verhindern. So schreiben Sie beispielsweise eine Protokolldatei über die aktuelle Sitzung:

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

CSV IO

fgetcsv($file, $length, $separator)

Die Datei fgetcsv analysiert die Zeile der geöffneten Datei und prüft, fgetcsv Felder vorhanden sind. Bei Erfolg wird ein CSV-Feld in einem Array oder bei einem Fehler FALSE .

Standardmäßig liest es nur eine Zeile der CSV-Datei.

$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

Ausgabe:

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

Eine Datei direkt in stdout einlesen

readfile kopiert eine Datei in den Ausgabepuffer. Bei readfile () treten selbst beim Senden großer Dateien keine Speicherprobleme auf.

$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;
}

Oder von einem Dateizeiger

fpassthru einen Punkt in der Datei zu suchen, um mit dem Kopieren nach stdout zu beginnen, verwenden fpassthru stattdessen fpassthru . Im folgenden Beispiel werden die letzten 1024 Bytes nach stdout kopiert:

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

Eine Datei in ein Array einlesen

file gibt die Zeilen in der übergebenen Datei in einem Array zurück. Jedes Element des Arrays entspricht einer Zeile in der Datei, wobei der Zeilenumbruch noch angefügt ist.

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

test.txt

Welcome to File handling
This is to test file handling

Ausgabe:

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

Dateiinformationen abrufen

Prüfen Sie, ob ein Pfad ein Verzeichnis oder eine Datei ist

Die Funktion is_dir zurück, ob das Argument ein Verzeichnis ist, während is_file zurückgibt, ob das Argument eine Datei ist. Verwenden Sie file_exists , um zu überprüfen, ob dies der file_exists ist.

$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;

Das gibt:

/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

Dateityp überprüfen

Verwenden Sie den filetype , um den filetype zu überprüfen. filetype sein:

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

Den Dateinamen direkt an den filetype :

echo filetype("~"); // dir

Beachten Sie, dass der filetype false zurückgibt und ein E_WARNING auslöst, wenn die Datei nicht vorhanden ist.

Lesbarkeit und Beschreibbarkeit prüfen

Wenn Sie den Dateinamen an die Funktionen is_writable und is_readable , überprüfen Sie, ob die Datei schreibbar oder lesbar ist.

Die Funktionen geben ordnungsgemäß false wenn die Datei nicht vorhanden ist.

Dateizugriffs- / Änderungszeit prüfen

Die Verwendung von filemtime und fileatime gibt den Zeitstempel der letzten Änderung oder des Zugriffs auf die Datei zurück. Der Rückgabewert ist ein Unix-Zeitstempel - Einzelheiten finden Sie unter Arbeiten mit Datum und Uhrzeit .

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"));

Erhalte Pfadteile mit fileinfo

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

$filePathParts = pathinfo($fileToAnalyze);

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

Dieses Beispiel gibt Folgendes aus:

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

Welches kann verwendet werden als:

$filePathParts['dirname']
$filePathParts['basename']
$filePathParts['extension']
$filePathParts['filename']
Parameter Einzelheiten
$ path Der vollständige Pfad der zu analysierenden Datei
Option $ Eine von vier verfügbaren Optionen [PATHINFO_DIRNAME, PATHINFO_BASENAME, PATHINFO_EXTENSION oder PATHINFO_FILENAME]
  • Wenn eine Option (der zweite Parameter) nicht übergeben wird, wird ein assoziatives Array zurückgegeben, andernfalls wird ein String zurückgegeben.
  • Überprüft nicht, dass die Datei vorhanden ist.
  • Parst die Saite einfach in Teile. Die Datei wird nicht validiert (keine Überprüfung des Mime-Typs usw.).
  • Die Erweiterung ist einfach die letzte Erweiterung von $path Der Pfad für die Datei image.jpg.png wäre .png auch wenn es sich technisch um eine .jpg Datei handelt. Eine Datei ohne Erweiterung gibt kein Erweiterungselement im Array zurück.

Minimieren Sie den Speicherverbrauch beim Umgang mit großen Dateien

Wenn eine große Datei analysiert werden muss, z. B. eine CSV mit mehr als 10 MByte, die Millionen von Zeilen enthält, verwenden einige die Funktionen file oder file_get_contents und enden mit der Einstellung memory_limit mit

Zulässige Speichergröße von XXXXX Byte erschöpft

Error. Betrachten Sie die folgende Quelle (top-1m.csv hat genau 1 Million Zeilen und ist ungefähr 22 MB groß)

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

Dies gibt aus:

int(262144)
int(210501632) 

Da der Interpreter alle Zeilen im Array $arr , verbrauchte er ~ 200 MB RAM. Beachten Sie, dass wir mit dem Inhalt des Arrays noch nichts unternommen haben.

Betrachten Sie nun den folgenden Code:

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));

welche Ausgänge

int(262144)
int(262144)

Wir verwenden also kein einzelnes zusätzliches Byte Speicher, sondern analysieren die gesamte CSV-Datei und speichern sie in einer anderen Datei, wobei der Wert der 2. Spalte umgekehrt wird. Das liegt daran, dass fgetcsv nur eine Zeile liest und $row in jeder Schleife überschrieben wird.

Stream-basierte Datei-IO

Einen Stream öffnen

fopen öffnet ein Dateistream-Handle, das mit verschiedenen Funktionen zum Lesen, Schreiben, Suchen und anderen Funktionen darüber verwendet werden kann. Dieser Wert ist vom resource und kann nicht an andere Threads übergeben werden, die ihre Funktionalität beibehalten.

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

Der zweite Parameter ist der Modus des Dateistreams:

Modus Beschreibung
r Öffnet den schreibgeschützten Modus und beginnt am Anfang der Datei
r+ Zum Lesen und Schreiben öffnen, beginnend am Anfang der Datei
w Nur zum Schreiben geöffnet, beginnend am Anfang der Datei. Wenn die Datei vorhanden ist, wird die Datei geleert. Wenn es nicht existiert, wird es versuchen, es zu erstellen.
w+ Zum Lesen und Schreiben geöffnet, beginnend am Anfang der Datei. Wenn die Datei vorhanden ist, wird die Datei geleert. Wenn es nicht existiert, wird es versuchen, es zu erstellen.
a Öffnen Sie eine Datei nur zum Schreiben, beginnend am Ende der Datei. Wenn die Datei nicht vorhanden ist, wird versucht, sie zu erstellen
a+ Öffnen Sie eine Datei zum Lesen und Schreiben, und zwar am Ende der Datei. Wenn die Datei nicht vorhanden ist, wird versucht, sie zu erstellen
x Erstellen und öffnen Sie eine Datei nur zum Schreiben. Wenn die Datei vorhanden ist, fopen der fopen Aufruf fehl
x+ Erstellen und öffnen Sie eine Datei zum Lesen und Schreiben. Wenn die Datei vorhanden ist, fopen der fopen Aufruf fehl
c Öffnen Sie die Datei nur zum Schreiben. Wenn die Datei nicht vorhanden ist, wird versucht, sie zu erstellen. Das Schreiben beginnt am Anfang der Datei, leert die Datei jedoch nicht vor dem Schreiben
c+ Öffnen Sie die Datei zum Lesen und Schreiben. Wenn die Datei nicht vorhanden ist, wird versucht, sie zu erstellen. Das Schreiben beginnt am Anfang der Datei, leert die Datei jedoch nicht vor dem Schreiben

Wenn Sie in Windows ein t hinter dem Modus hinzufügen (z. B. a+b , wt usw.), werden "\n" Zeilenenden in "\r\n" wenn Sie mit der Datei arbeiten. Fügen Sie b hinter dem Modus ein, wenn dies nicht beabsichtigt ist, insbesondere wenn es sich um eine Binärdatei handelt.

Die PHP-Anwendung sollte Streams mit fclose wenn sie nicht mehr verwendet werden, um den Fehler Too many open files zu verhindern. Dies ist besonders wichtig in CLI - Programmen, da die Ströme nur dann geschlossen , wenn die Laufzeit ausschaltet - dies bedeutet , dass in Web - Servern, ist es nicht notwendig sein kann (aber immer noch sollte, als eine Praxis Ressource - Leck zu verhindern) , die Ströme zu schließen Wenn Sie nicht davon ausgehen, dass der Prozess längere Zeit ausgeführt wird, und viele Streams nicht geöffnet werden.

lesen

Mit fread wird die angegebene Anzahl von Bytes aus dem Dateizeiger gelesen oder bis ein EOF erreicht wird.

Zeilen lesen

Mit fgets wird die Datei gelesen, bis eine EOL erreicht wird oder die angegebene Länge gelesen wird.

fread und fgets bewegen den Dateizeiger während des Lesens.

Lesen Sie alles, was noch übrig ist

Bei Verwendung von stream_get_contents werden alle verbleibenden Bytes im Stream in einen String umgewandelt und zurückgegeben.

Dateizeigerposition anpassen

Nach dem Öffnen des Streams befindet sich der Dateizeiger am Anfang der Datei (oder am Ende, wenn der Modus a verwendet wird). Mit der Funktion fseek wird der Dateizeiger relativ zu einem der drei Werte an eine neue Position fseek :

  • SEEK_SET : Dies ist der Standardwert. Der Versatz der Dateiposition ist relativ zum Dateianfang.
  • SEEK_CUR : Der Versatz der SEEK_CUR ist relativ zur aktuellen Position.
  • SEEK_END : Der Versatz der SEEK_END ist relativ zum Ende der Datei. Das Übergeben eines negativen Offsets wird für diesen Wert am häufigsten verwendet. Die Dateiposition wird vor dem Ende der Datei auf die angegebene Anzahl von Bytes verschoben.

rewind ist eine praktische Abkürzung von fseek($fh, 0, SEEK_SET) .

Bei Verwendung von ftell wird die absolute Position des Dateizeigers ftell .

Das folgende Skript liest beispielsweise die ersten 10 Bytes, liest die nächsten 10 Bytes, überspringt 10 Bytes, liest die nächsten 10 Bytes und dann die letzten 10 Bytes 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);

Schreiben

Bei Verwendung von fwrite der bereitgestellte String ab dem aktuellen Dateizeiger in die Datei geschrieben.

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

Dateien und Verzeichnisse verschieben und kopieren

Dateien kopieren

copy kopiert die Quelldatei im ersten Argument an das Ziel im zweiten Argument. Das aufgelöste Ziel muss sich in einem Verzeichnis befinden, das bereits erstellt wurde.

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

Verzeichnisse kopieren mit Rekursion

Das Kopieren von Verzeichnissen ist dem Löschen von Verzeichnissen sehr ähnlich, mit der Ausnahme, dass für Dateien copy anstelle von unlink verwendet wird, während für Verzeichnisse mkdir anstelle von rmdir verwendet wird, anstatt am Ende der Funktion.

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

Umbenennen / Verschieben

Das Umbenennen / Verschieben von Dateien und Verzeichnissen ist wesentlich einfacher. Ganze Verzeichnisse können in einem einzigen Aufruf verschoben oder umbenannt werden, die mit 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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow