Sök…


Syntax

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

parametrar

Parameter Beskrivning
filnamn Filnamnet som läses.
use_include_path Du kan använda den andra tillvalsparametern och ställa in den till SANT om du också vill söka efter filen i inkludera sökvägen.
sammanhang En resurs för kontextström.

Anmärkningar

Filnamnssyntax

De flesta filnamn som skickas till funktioner i detta ämne är:

  1. Strängar i naturen.
    • Filnamn kan skickas direkt. Om värden av andra typer skickas, kastas de till sträng. Detta är särskilt användbart med SplFileInfo , som är värdet i iterationen av DirectoryIterator .
  2. Relativ eller absolut.
    • De kan vara absoluta. På Unix-liknande system börjar absoluta sökvägar med / , t.ex. /home/user/file.txt , medan på Windows startar absoluta vägar med enheten, t.ex. C:/Users/user/file.txt
    • De kan också vara relativa, vilket är beroende av värdet på getcwd och kan ändras av chdir .
  3. Acceptera protokoll.
    • De kan börja med scheme:// att ange protokollomslaget att hantera med. Till exempel file_get_contents("http://example.com") innehåll från http://example.com .
  4. Slash-kompatibla.
    • Medan DIRECTORY_SEPARATOR Windows är ett backslash, och systemet returnerar backslags för sökvägar som standard, kan utvecklaren fortfarande använda / som katalogseparator. Därför, för kompatibilitet, kan utvecklare använda / som katalogseparatorer på alla system, men vara medvetna om att de värden som returneras av funktionerna (t.ex. realpath ) kan innehålla backstänger.

Radera filer och kataloger

Radera filer

unlink funktionen raderar en enda fil och returnerar om operationen var framgångsrik.

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

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

Radera kataloger, med rekursiv radering

Å andra sidan bör kataloger tas bort med rmdir . Men den här funktionen raderar bara tomma kataloger. Om du vill ta bort en katalog med filer tar du först bort filerna i katalogerna. Om katalogen innehåller underkataloger kan rekursion behövas.

Följande exempel skannar filer i en katalog, raderar medlemsfiler / kataloger rekursivt och returnerar antalet filer (inte kataloger) som har raderats.

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

Bekvämlighetsfunktioner

Rå direkt IO

file_get_contents och file_put_contents ger möjlighet att läsa / skriva från / till en fil till / från en PHP-sträng i ett enda samtal.

file_put_contents kan också användas med FILE_APPEND bitmaskflaggan för att lägga till, istället för att trunkera och skriva över, filen. Det kan användas tillsammans med LOCK_EX bitmask för att skaffa ett exklusivt lås för filen medan du fortsätter att skriva. Bitmaskerflaggor kan förenas med | bitvis-ELLER operatör.

$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 är praktiskt för att lägga till loggfiler medan LOCK_EX hjälper till att förhindra LOCK_EX från flera processer. För att till exempel skriva till en loggfil om den aktuella sessionen:

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

CSV IO

fgetcsv($file, $length, $separator)

fgetcsv från öppen fil som kontrollerar efter csv-fält. Det returnerar CSV-fält i en matris om framgång eller FALSE on fail.

Som standard läser den bara en rad i CSV-filen.

$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

Produktion:

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

Läser en fil till stdout direkt

readfile kopierar en fil till utgångsbufferten. readfile () kommer inte att presentera några minnesproblem, ens när du skickar stora filer, på egen hand.

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

Eller från en filpekare

Alternativt, för att söka efter en punkt i filen för att börja kopiera till stdout, använd istället fpassthru . I följande exempel kopieras de sista 1024 byte till stdout:

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

Läser en fil i en matris

file returnerar raderna i den skickade filen i en matris. Varje element i matrisen motsvarar en rad i filen, med den nya linjen fortfarande bifogad.

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

test.txt

Welcome to File handling
This is to test file handling

Produktion:

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

Få filinformation

Kontrollera om en sökväg är en katalog eller en fil

Funktionen is_dir returnerar om argumentet är en katalog, medan is_file returnerar om argumentet är en fil. Använd file_exists att kontrollera om det är antingen.

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

Detta ger:

/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

Kontrollerar filtyp

Använd filetype att kontrollera typen av fil, som kan vara:

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

Skickar filnamnet direkt till filetype :

echo filetype("~"); // dir

Observera att filetype returnerar falskt och utlöser en E_WARNING om filen inte finns.

Kontrollera läsbarhet och skrivbarhet

Att is_writable filnamnet till is_writable och is_readable funktionerna kontrollerar om filen är skrivbar respektive läsbar.

Funktionerna returnerar false graciöst om filen inte finns.

Kontrollerar filåtkomst / ändra tid

Att använda filemtime och fileatime returnerar tidsstämpeln för den senaste ändringen eller åtkomsten till filen. Returvärdet är en Unix-tidsstämpel - se Arbeta med datum och tid för mer information.

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

Hämta sökvägsdelar med filinfo

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

$filePathParts = pathinfo($fileToAnalyze);

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

Detta exempel kommer att matas ut:

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

Som kan användas som:

$filePathParts['dirname']
$filePathParts['basename']
$filePathParts['extension']
$filePathParts['filename']
Parameter detaljer
$ PATH Filens hela sökväg som ska analyseras
$ alternativ Ett av fyra tillgängliga alternativ [PATHINFO_DIRNAME, PATHINFO_BASENAME, PATHINFO_EXTENSION eller PATHINFO_FILENAME]
  • Om ett alternativ (den andra parametern) inte passeras, returneras en associerande matris, annars returneras en sträng.
  • Validerar inte att filen finns.
  • Torkar bara strängen i delar. Ingen validering görs på filen (ingen mime-typkontroll, etc.)
  • Tillägget är helt enkelt den sista utvidgningen av $path Sökvägen för filen image.jpg.png skulle vara .png även om den tekniskt sett är en .jpg fil. En fil utan tillägg kommer inte att returnera ett tilläggselement i matrisen.

Minimera minnesanvändningen när du hanterar stora filer

Om vi behöver analysera en stor fil, t.ex. en CSV som är mer än 10 Mbyte som innehåller miljoner rader, använder vissa file eller file_get_contents funktioner och slutar med att slå memory_limit inställningen med

Tillåten minnestorlek på XXXXX byte uttömd

fel. Tänk på följande källa (top-1m.csv har exakt 1 miljon rader och är ungefär 22 Mbyte i storlek)

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

Denna utgångar:

int(262144)
int(210501632) 

eftersom tolkarna behövde hålla alla raderna i $arr array, så den konsumerade ~ 200 Mbyte RAM. Observera att vi inte ens har gjort något med innehållet i matrisen.

Tänk nu på följande kod:

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

vilka utgångar

int(262144)
int(262144)

så vi använder inte en enda extrabyte med minne, utan analyserar hela CSV-filen och sparar den i en annan fil som vänder värdet på den andra kolumnen. Det beror på att fgetcsv bara läser en rad och $row skrivs över i varje slinga.

Strömbaserad fil IO

Öppnar en ström

fopen öppnar ett fopen som kan användas med olika funktioner för att läsa, skriva, söka och andra funktioner ovanpå det. Detta värde är av resource och kan inte vidarebefordras till andra trådar som fortsätter att fungera.

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

Den andra parametern är läget för filströmmen:

Läge Beskrivning
r Öppna i skrivskyddsläge, från början av filen
r+ Öppet för läsning och skrivning, från början av filen
w öppet för skrivning endast från början av filen. Om filen finns kommer den att tömma filen. Om det inte existerar kommer det att försöka skapa det.
w+ öppet för läsning och skrivning, från början av filen. Om filen finns kommer den att tömma filen. Om det inte existerar kommer det att försöka skapa det.
a öppna en fil för skrivning endast från slutet av filen. Om filen inte finns, kommer den att försöka skapa den
a+ öppna en fil för att läsa och skriva, från slutet av filen. Om filen inte finns, kommer den att försöka skapa den
x skapa och öppna en fil för skrivning. Om filen finns kommer fopen samtalet att misslyckas
x+ skapa och öppna en fil för läsning och skrivning. Om filen finns kommer fopen samtalet att misslyckas
c öppna filen endast för skrivning. Om filen inte finns kommer den att försöka skapa den. Det börjar skriva i början av filen, men kommer inte att tömma filen innan den skrivs
c+ öppna filen för att läsa och skriva. Om filen inte finns kommer den att försöka skapa den. Det börjar skriva i början av filen, men kommer inte att tömma filen innan den skrivs

Att lägga till en t bakom läget (t.ex. a+b , wt , etc.) i Windows kommer att översätta "\n" radavslut till "\r\n" när du arbetar med filen. Lägg till b bakom läget om detta inte är avsett, särskilt om det är en binär fil.

PHP-applikationen bör stänga strömmar med fclose när de inte längre används för att förhindra felet Too many open files . Detta är särskilt viktigt i CLI-program, eftersom strömmarna endast stängs när körtiden stängs av - det innebär att det på webbservrar kanske inte är nödvändigt (men ändå borde det som en praxis för att förhindra resursläckage) att stänga strömmarna om du inte förväntar dig att processen ska köras under lång tid och inte kommer att öppna många strömmar.

Läsning

Användning av fread läser det givna antalet byte från filpekaren eller tills en EOF uppfylls.

Läser linjer

Med fgets läses filen tills en EOL har nåtts, eller den angivna längden läses.

Både fread och fgets flyttar filpekaren under läsning.

Läser allt som återstår

Med hjälp av stream_get_contents kommer alla återstående byte i strömmen till en sträng och returneras.

Justera filmarkörens position

Ursprungligen efter att strömmen har öppnats är filpekaren i början av filen (eller i slutet, om läget a används). Med hjälp av fseek funktionen flyttas filpekaren till en ny position, relativt ett av tre värden:

  • SEEK_SET : Detta är standardvärdet; filpositionförskjutningen kommer att vara relativt filens början.
  • SEEK_CUR : SEEK_CUR kommer att vara relativt den aktuella positionen.
  • SEEK_END : SEEK_END kommer att vara relativt filens slut. Att passera en negativ offset är den vanligaste användningen för detta värde; den kommer att flytta filpositionen till det angivna antalet byte före filens slut.

rewind är en bekväm genväg för fseek($fh, 0, SEEK_SET) .

Att använda ftell visar ftell absoluta position.

Exempelvis läser följande skript över de första 10 byte, läser de nästa 10 byte, hoppar över 10 byte, läser de nästa 10 byte och sedan de 10 senaste byte i 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);

Skrivning

Med hjälp av fwrite skriver du den fwrite strängen till filen från och med den aktuella filpekaren.

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

Flytta och kopiera filer och kataloger

Kopierar filer

copy kopierar källfilen i det första argumentet till destinationen i det andra argumentet. Den lösta destinationen måste finnas i en katalog som redan är skapad.

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

Kopiering av kataloger, med rekursion

Kopiering av kataloger liknar ganska mycket som att ta bort kataloger, förutom att för filer copy istället för unlink används, medan för kataloger används mkdir istället för rmdir , i början istället för att vara i slutet av funktionen.

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

Döpa / Moving

Byt namn på / flytta filer och kataloger är mycket enklare. Hela kataloger kan flyttas eller byta namn på i ett enda samtal med hjälp av 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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow