62

What's the quickest, easiest way to read the first line only from a file? I know you can use file, but in my case there's no point in wasting the time loading the whole file.

Preferably a one-liner.

Jonah
  • 9,991
  • 5
  • 45
  • 79
  • wonder if that's possible (read only the first line of a file without loading any "extras") – yoda Dec 23 '10 at 19:46
  • Maybe something like `$buffer = '';while(strpos($buffer, "\n")===false){$buffer .= fread($handle, 16);} $string = substr($buffer, 0, strpos($buffer, "\n"));` – Jonah Dec 23 '10 at 19:52
  • 10
    `$line = (new SplFileObject($file))->fgets();` — Fancy construct-and-call-method syntax available as of PHP 5.4.0. – salathe Mar 26 '13 at 22:36

11 Answers11

149

Well, you could do:

$f = fopen($file, 'r');
$line = fgets($f);
fclose($f);

It's not one line, but if you made it one line you'd either be screwed for error checking, or be leaving resources open longer than you need them, so I'd say keep the multiple lines

Edit

If you ABSOLUTELY know the file exists, you can use a one-liner:

$line = fgets(fopen($file, 'r'));

The reason is that PHP implements RAII for resources.

That means that when the file handle goes out of scope (which happens immediately after the call to fgets in this case), it will be closed.

ircmaxell
  • 163,128
  • 34
  • 264
  • 314
26
$firstline=`head -n1 filename.txt`;
profitphp
  • 8,104
  • 2
  • 28
  • 21
  • 4
    linux ftw. I guess being the only 1 liner wasn't enough to get the answer vote... damn you microsoft!! – profitphp Dec 23 '10 at 20:01
  • 3
    A one liner might be enough, but an answer that is totally newbie-unfriendly is not. The code might be fine, but if somebody needs this answer, he/she probably doesn't know PHP like his/her boots - I use PHP for 10 years and have no clue how/why your line works, and as such would never use it in my code. An explanation would be nice. – Kalko Mar 18 '20 at 17:15
  • @Kalko, the backtick executes the string as a shell command in php https://www.php.net/manual/en/function.shell-exec.php – ssi-anik Aug 07 '20 at 23:24
  • 2
    @ssi-anik damn, I didn't know that. Thanks for the explanation. I suggest you add this explanation to the answer itself so more people will understand. – Kalko Aug 10 '20 at 16:35
  • there are two problems with this approach: 1/ the question was about the quickest way, but the backtick operator means a serious overhead. 2/ if you use the "head" unix system command, your code will not be portable any more. – ThatsMe Dec 02 '21 at 07:35
12

I'm impressed no one mentioned the file() function:

$line = file($filename)[0];

or if version_compare(PHP_VERSION, "5.4.0") < 0:

$line = array_shift(file($filename));
Tarjei Huse
  • 1,231
  • 11
  • 14
  • 20
    _"I know you can use `file`, but in my case there's no point in wasting the time loading the whole file."_ :-) – Jonah Mar 25 '14 at 22:11
8
$line = '';
$file = 'data.txt';
if($f = fopen($file, 'r')){
  $line = fgets($f); // read until first newline
  fclose($f);
}
echo $line;
Sarah
  • 513
  • 4
  • 11
4

In modern PHP using SplFileObject;

$fileObject = new \SplFileObject('myfile');
$line = $fileObject->current();

complementary information

With SplFileObject, it's also easy to seek lines, for example to skip 2 lines;

$fileObject = new \SplFileObject('myfile');

$fileObject->seek(2);
$line = $fileObject->current();

or to read the first 10 lines;

$fileObject = new \SplFileObject('myfile');

$lines = '';
for ($i = 0; $i < 10 && $fileObject->valid(); ++$i) {
    $lines .= $fileObject->getCurrentLine();
}

note: getCurrentLine() will read the current line and move the internal cursor to the next one (essentially current() + next())

Fabien Sa
  • 9,135
  • 4
  • 37
  • 44
  • Is there any difference between `current()` and `getCurrentLine()`? – matronator Aug 18 '22 at 21:33
  • 1
    @matronator `getCurrentLine()` is an alias for `fgets()`; it's similar but it will move the cursor internally to the next line, essentially it is a current() + next(). I added a note. – Fabien Sa Aug 19 '22 at 03:44
3
if(file_exists($file)) {
    $line = fgets(fopen($file, 'r'));
}
1

fgets() returns " " which is a new line at the end,but using this code you will get first line without the lineBreak at the end :

$handle = @fopen($filePath, "r");
$text=fread($handle,filesize($filePath));
$lines=explode(PHP_EOL,$text);
$line = reset($lines);
George SEDRA
  • 796
  • 8
  • 11
0

In one of my projects (qSandbox) I uses this approach to get the first line of a text file that I read anyways. I have my email templates are in a text files and the subject is in the first line.

$subj_regex = '#^\s*(.+)[\r\n]\s*#i';

// subject is the first line of the text file. Smart, eh?
if (preg_match($subj_regex, $buff, $matches)) {
    $subject = $matches[1];
    $buff = preg_replace($subj_regex, '', $buff); // rm subject from buff now.
}
Svetoslav Marinov
  • 1,498
  • 14
  • 11
0

You could try to us fread and declare the file size to read.

ngen
  • 8,816
  • 2
  • 18
  • 15
-1

If you don't mind reading in the entire file, then a one-liner would be:

$first_line = array_shift(array_values(preg_split('/\r\n|\r|\n/', file_get_contents($file_path), 2)));

:)

rcourtna
  • 4,589
  • 5
  • 26
  • 27
-8

Try this:

$file = 'data.txt';
$data = file_get_contents($file);
$lines = explode