Menu

file_get_contents() w PHP: odczyt pliku do stringa

file_get_contents('notes.txt') odczytuje cały plik i zwraca go jako jeden string albo false, jeśli się nie da. Jej odpowiednik file_put_contents() zapisuje string do pliku, a file() zwraca linie jako tablicę.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

file_get_contents('notes.txt') odczytuje cały plik i zwraca go jako jeden string. Jeśli pliku nie da się odczytać, zwraca false. Do zapisu użyj file_put_contents('notes.txt', $text), które tworzy plik albo zastępuje jego zawartość.

Wynik:

Buy milk
Call Ada
Write docs
29 bytes
3 lines

Blok najpierw zapisuje notes.txt, a potem go odczytuje, więc ma z czym pracować. Ścieżka taka jak 'notes.txt' jest względna do bieżącego katalogu roboczego; w aplikacji WWW buduj ścieżkę od własnego folderu skryptu przez __DIR__ . '/notes.txt'.

Zapis i dopisywanie przez file_put_contents()

file_put_contents() zwraca liczbę zapisanych bajtów albo false przy błędzie. Domyślnie nadpisuje plik. Flaga FILE_APPEND dopisuje zamiast tego na końcu, tak działają proste logi, a LOCK_EX nie pozwala dwóm żądaniom zapisywać w tej samej chwili:

Wynik:

Wrote 8 bytes
started
step 1 done
step 2 done

replaced

abc
5 bytes

Aby zapisać tablicę i odczytać ją z powrotem jako tablicę, zapisz ją jako JSON przez json_encode() i odczytaj przez json_decode().

Odczyt pliku linia po linii przez file()

file() wczytuje plik do tablicy z jedną linią na element. Każda linia zachowuje na końcu znak nowej linii, chyba że przekażesz FILE_IGNORE_NEW_LINES, a FILE_SKIP_EMPTY_LINES odrzuca puste linie (działa tylko razem z FILE_IGNORE_NEW_LINES):

Wynik:

string(9) "Buy milk
"
1. Buy milk
2. Call Ada
3. Write docs
3 tasks

file() i file_get_contents() wczytują cały plik do pamięci. To w porządku dla plików konfiguracyjnych i logów o rozmiarze kilku megabajtów. Plik o rozmiarze setek megabajtów czytaj zamiast tego po jednej linii przez fopen() i fgets().

Sprawdzanie, czy plik istnieje, przed odczytem

Gdy pliku brakuje, file_get_contents() zwraca false, a PHP wypisuje ostrzeżenie:

Warning: file_get_contents(missing.txt): Failed to open stream: No such file or directory in /home/index.php on line 2

Najpierw sprawdź przez is_file() (plik, który istnieje i nie jest katalogiem) albo file_exists() (plik lub katalog) i zawsze porównuj wynik z === false, bo pusty plik zwraca "", które też jest traktowane jak fałsz:

Wynik:

empty.txt   exists file 
missing.txt missing 
.           exists directory 
Cannot read missing.txt, using defaults
bool(false)
bool(true)
0 bytes

Nie ukrywaj ostrzeżenia przez @file_get_contents(). Sprawdzenie z góry albo obsługa false sprawiają, że błąd pozostaje widoczny, gdy pójdzie nie tak coś innego.

Odczyt części pliku

Czwarty i piąty argument to przesunięcie w bajtach, od którego zacząć, i liczba bajtów do odczytu. Ujemne przesunięcie liczy od końca pliku. Argumenty nazwane pozwalają pominąć dwa argumenty pośrodku:

Wynik:

HEADER
line 2
last line

Przesunięcia liczą bajty, a nie znaki. W UTF-8 znak japoński zajmuje 3 bajty, a polska litera 2, więc przesunięcie w środku takiego znaku przecina go na pół. Aby pracować na znakach, odczytaj cały string i użyj mb_substr().

Plik tekstowy na stronie WWW

Zawartość pliku to tekst, a tekst wypisywany do HTML trzeba escapować, inaczej < w pliku staje się znacznikiem. htmlspecialchars() go escapuje, a nl2br() zamienia znaki nowej linii w znaczniki <br>. Uruchom i spójrz na zakładkę Page:

Usuń htmlspecialchars() i uruchom ponownie: strona kończy się teraz na „v1.2: Fixed”, bo przeglądarka czyta <title> jako prawdziwy znacznik i połyka wszystko po nim jako tytuł strony. Strona htmlspecialchars() wyjaśnia, dlaczego ma to znaczenie dla wszystkiego, co może napisać użytkownik.

Odczyt URL przez file_get_contents()

Z włączonym allow_url_fopen (domyślnie w php.ini) file_get_contents() czyta też adresy URL i zwraca treść odpowiedzi. Kontekst strumienia dodaje metodę, nagłówki, treść i limit czasu:

<?php
$html = file_get_contents('https://example.com/');

$context = stream_context_create([
    'http' => [
        'method'  => 'POST',
        'header'  => "Content-Type: application/json\r\n",
        'content' => json_encode(['name' => 'Ada']),
        'timeout' => 5,
        'ignore_errors' => true,   // return the body of 4xx/5xx responses too
    ],
]);

$response = file_get_contents('https://api.example.com/users', false, $context);
if ($response === false) {
    // DNS failure, timeout, or a refused connection
}

Do ponawiania, przekierowań z limitami i czytelnych kodów błędów lepszym narzędziem jest cURL albo biblioteka klienta HTTP, taka jak Guzzle.

file_get_contents vs file() vs fopen()

ChceszUżyjPamięć
Cały plik jako jeden stringfile_get_contents()Cały plik
Linie jako tablicęfile($path, FILE_IGNORE_NEW_LINES)Cały plik
Zapisać lub zastąpić plik jednym wywołaniemfile_put_contents()Zapisywane dane
Dodać linię do logufile_put_contents($path, $line, FILE_APPEND | LOCK_EX)Jedna linia
Czytać duży plik linia po linii albo wiersze CSVfopen() z fgets() lub fgetcsv()Jedna linia
Czytać i zapisywać ten sam otwarty plikfopen() z r+, a+ lub c+To, co odczytasz

Funkcje działające jednym wywołaniem same otwierają, czytają lub zapisują i zamykają plik, więc to właściwy wybór domyślny. Po fopen() sięgnij, gdy plik jest za duży, by trzymać go w pamięci, albo musisz trzymać go otwartym między operacjami.

Najczęściej zadawane pytania

Jak odczytać plik do stringa w PHP?

Wywołaj file_get_contents('path/to/file.txt'). Zwraca cały plik jako string albo false, jeśli pliku nie da się odczytać, więc przed użyciem porównaj wynik z === false.

Jak dopisać do pliku w PHP?

Przekaż flagę FILE_APPEND: file_put_contents('log.txt', "new line\n", FILE_APPEND);. Bez niej file_put_contents() zastępuje cały plik. Dodaj LOCK_EX (FILE_APPEND | LOCK_EX), gdy kilka żądań może zapisywać jednocześnie.

Jak odczytać plik linia po linii w PHP?

Dla małych plików file('data.txt', FILE_IGNORE_NEW_LINES) zwraca tablicę z jedną linią na element. Dla dużych otwórz plik przez fopen() i czytaj po jednej linii przez fgets() w pętli while, co trzyma w pamięci tylko jedną linię.

Dlaczego file_get_contents zwraca false?

Plik nie istnieje, ścieżka jest względna do innego katalogu, niż myślisz, albo PHP nie ma uprawnień do odczytu. PHP wypisuje też ostrzeżenie, takie jak Failed to open stream: No such file or directory. Sprawdzaj przez is_file() i is_readable() i buduj ścieżki od __DIR__.

Czy file_get_contents potrafi odczytać URL?

Tak, gdy w php.ini włączone jest allow_url_fopen: file_get_contents('https://example.com/') zwraca treść odpowiedzi. Dla nagłówków, danych POST albo limitu czasu przekaż kontekst z stream_context_create(); przy czymś bardziej złożonym cURL daje lepszą obsługę błędów.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ