file
Reads an entire file into an array, with one element per line.
file(string $filename, int $flags = 0, ?resource $context = null): array|false- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$filename | string | Path to the file. |
$flagsoptional | int= 0 | A bitmask of FILE_USE_INCLUDE_PATH, FILE_IGNORE_NEW_LINES, FILE_SKIP_EMPTY_LINES and FILE_NO_DEFAULT_CONTEXT. |
$contextoptional | ?resource= null | A stream context created with stream_context_create(). |
Return value
array|falseAn array with one element per line of the file, or false on failure.
Errors
Emits E_WARNING and returns false when the file cannot be opened. As of PHP 8.3 a ValueError is thrown for invalid flags.
Changelog
- PHP 8.3.0A ValueError is thrown for any invalid value of flags, instead of the value being silently ignored.
file() is the one-liner for "give me the lines of this file". It opens, reads, splits and closes in a single call, and the result is a plain indexed array you can foreach, array_filter or count.
The flags
- FILE_IGNORE_NEW_LINES — drop the line ending from each element. Almost always what you want.
- FILE_SKIP_EMPTY_LINES — omit blank lines.
- FILE_USE_INCLUDE_PATH — also look for the file on the include path.
Combine them with |.
When not to reach for it
The whole file lands in memory, and an array of short strings costs considerably more than the file's byte size — every element carries its own zval and string header. On a 500 MB log that is a fatal memory error. Switch to fopen() plus a fgets() loop the moment the file could be large or is attacker-controlled in size.
Also note the newlines: without FILE_IGNORE_NEW_LINES every element except possibly the last ends in \n, and on a Windows file in \r\n. Comparisons against the raw elements will fail.
Since PHP 8.3 an invalid flag value throws a ValueError rather than being silently ignored — passing a constant that does not belong here, such as FILE_APPEND, now fails loudly instead of doing nothing.
Example
When to use it
- Load a small allow-list or blocklist of domains into an array in one call
- Number and display the lines of a short config or template file
- Parse a key=value settings file with explode() after splitting on lines
- Count matching lines in a modest log file with array_filter()
Frequently asked questions
What is the difference between file and file_get_contents?
file() returns an array with one element per line; file_get_contents() returns the whole file as a single string. Both load everything into memory, so neither is suitable for very large files.
How do I remove the newline characters from file()?
Pass FILE_IGNORE_NEW_LINES as the second argument. Combine it with FILE_SKIP_EMPTY_LINES using | when you also want blank lines dropped.
Is file safe to use on large files?
No. The entire file becomes an array in memory, and per-element overhead makes the array larger than the file itself, so a big log will exhaust memory_limit. Use fopen() with an fgets() loop instead.
More examples
Numbering and filtering log lines
Array keys are zero-based line offsets, so display numbers need the + 1. array_filter() preserves keys, which is why array_values() is wrapped around it — otherwise the single match would come back with key 2 and json_encode() would render it as an object rather than a list.
<?php
file_put_contents("app.log", "boot\nwarn: slow\nerror: 500\ndone\n");
$lines = file("app.log", FILE_IGNORE_NEW_LINES);
foreach ($lines as $i => $line) {
printf("%3d %s\n", $i + 1, $line);
}
$errors = array_values(array_filter($lines, fn($l) => str_starts_with($l, "error")));
print_r($errors);
unlink("app.log");Parsing a key=value config
The two flags together give clean, blank-free lines so the loop only has to skip comments. The third argument to explode() caps the split at two parts, so a value that itself contains an equals sign survives intact — dropping it is a common source of truncated passwords and DSNs.
<?php
file_put_contents("app.ini", "host=localhost\nport=5432\n\n# a comment\nuser=admin\n");
$config = [];
foreach (file("app.ini", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
if ($line === "" || $line[0] === "#") {
continue;
}
[$key, $value] = explode("=", $line, 2);
$config[$key] = $value;
}
print_r($config);
unlink("app.ini");Why FILE_SKIP_EMPTY_LINES needs its partner
The first two counts are both 3. On its own FILE_SKIP_EMPTY_LINES sees the blank line as the one-character string "\n", which is not empty, so nothing is skipped. Only with FILE_IGNORE_NEW_LINES also set does the line become genuinely empty and the count drop to 2.
<?php
file_put_contents("gaps.txt", "a\n\nb\n");
var_dump(count(file("gaps.txt")));
var_dump(count(file("gaps.txt", FILE_SKIP_EMPTY_LINES)));
var_dump(count(file("gaps.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)));
unlink("gaps.txt");
Discussion