4

Thank you for taking the time to read this and I will appreciate every single response no mater the quality of content. :)

Using PHP, I'm trying to get the last 15 lines of a text document (.txt) and store that data into a php variable. I understand that this is possible, however when I do get the last 15 lines, is it possible to retain the order? For example:

text document:

A
B
C

When I grab the text document from the last 15 characters, I don't want the echo to end up like:

C
B
A

All assistance is appreciated and I look forward to your replies; thank you. :) If I didn't explain anything clearly and/or you'd like me to explain in more detail, please reply. :)

Thank you.

aullah
  • 1,204
  • 2
  • 20
  • 28
  • I am out of closevotes and too tired to stay up for 35 minutes, but anyway: possible duplicate of [php how to read only 5 last line of the txt file](http://stackoverflow.com/questions/2961618/php-how-to-read-only-5-last-line-of-the-txt-file) – Gordon Aug 25 '10 at 23:24
  • Another one http://stackoverflow.com/questions/514673/how-do-i-open-a-file-from-line-x-to-line-y-in-php – Gordon Aug 25 '10 at 23:32

6 Answers6

10

Try using array_slice, which will return a part of an array. In this case you want it to return the last 15 lines of the array, so:

$filearray = file("filename");
$lastfifteenlines = array_slice($filearray,-15);
Bob Baddeley
  • 2,234
  • 1
  • 14
  • 22
  • Hi Bob Baddeley, thank you for your response as well as your efforts. I extremely appreciate it. ;) When I try to echo $lastfifteenlines, it only seems to display the text "Array" of course, I'm pretty sure that it's an error on my end and my lack of php knowledge. Again, thank you for your response and effort. ;) – aullah Aug 26 '10 at 12:56
  • `echo` instead `implode("\n", $lastfifteenlines)`. – Hammerite Aug 26 '10 at 13:01
  • Hi Hammerite, thanks for the response. I'm really grateful, using this code even allows me to assign variables in the correct order. Thanks for the responses as well as effort. ;) – aullah Aug 26 '10 at 13:39
5

If you don't mind loading the entire file into memory:

$lines = array_slice(file('test.txt'), -15);
print_r($lines );

If the file is too large to fit into memory you can use a circular method:

// Read the last $num lines from stream $fp
function read_last_lines($fp, $num)
{
    $idx   = 0;

    $lines = array();
    while(($line = fgets($fp)))
    {
        $lines[$idx] = $line;
        $idx = ($idx + 1) % $num;
    }

    $p1 = array_slice($lines,    $idx);
    $p2 = array_slice($lines, 0, $idx);
    $ordered_lines = array_merge($p1, $p2);

    return $ordered_lines;
}

// Open the file and read the last 15 lines
$fp    = fopen('test.txt', 'r');
$lines = read_last_lines($fp, 15);
fclose($fp);

// Output array
print_r($lines);

This method will also work if the file has less than 15 lines- returning an array with however many lines are in the file.

  • Hey David Churchill, thank you for your response and efforts. I extremely appreciate it and can't thank you enough. ;) – aullah Aug 26 '10 at 17:07
2

You can use fseek with a negative position to seek backwards through the file, counting newlines as you go.

I'm too tired to write up copy/past-able code, but there are some examples in the comments to the manual page for fseek that are very close to what you want.

timdev
  • 57,660
  • 6
  • 74
  • 90
1

If the file isn't bigger than available memory you can do this:

$fArray = file("filename");
$len = sizeof($fArray);
for($i=$len -15;$i<$len ;$i++)
{
   echo $fArray[$i];
}

If you have a file that is hundreds of megabytes :

$rc = fopen("file","r");
for ($i=0; $line = fgets($file) ;$i++)
{
   if ($i%15 == 0)
   {
      $last15 = array();
   }
   $last15[] = $line;
}

echo join("\n",$last15);

Byron Whitlock
  • 49,611
  • 27
  • 114
  • 164
  • 1
    Surely that second one only works if the number of lines in the file is a multiple of 15. If there are 20 lines (numbered 0 through 19) then you only get back the last 5 lines. – Hammerite Aug 25 '10 at 23:25
  • Hi Byron Whitlock, thank you for your response, I extremely appreciate it. :) One little thing though, after reading the last 15 lines of the txt document, I want to be able to give each text it's own php variable. However, when I go to do this, it grabs the data from the last line so I can't add any variables for the above lines. Is there a way to do this? Apologies for the question, especially as it seems a little off-topic. Again, I appreciate your response. ;) – aullah Aug 26 '10 at 12:34
1

the longer array solution: array_slice(explode("\n",file_get_contents($file)),-15);

the shorter array solution: array_slice(file($file),-15);

bcosca
  • 16,475
  • 5
  • 36
  • 50
  • Hi stillstanding, I extremely appreciate your response! I'm not really too much of an expert with php, although I know it's ins and outs, I'm not too comfortable with arrays. I won't mind using arrays as long as I'll be able to assign a php variable to the array content? if possible. Anyhow, I extremely appreciate your response as well as your time and effort. ;) Thank you. – aullah Aug 26 '10 at 12:54
1

This code will open the file, show the total lines, show the header of file and show the last lines of file defined in $limit.

<?php
// open the file in read mode
$file = new SplFileObject('file.csv', 'r');

// get the total lines
$file->seek(PHP_INT_MAX);
$last_line = $file->key();
echo $last_line;
echo "<br>";

// Rewind to first line to get header
$file->rewind();

// Output first line if you need use the header to make something
echo $file->current();
echo "<br>";

// selecting the limit
$limit = 6;

// selecting the last lines using the $limit
$lines = new LimitIterator($file, $last_line - $limit, $last_line);

//print all the last 6 lines array
//print_r(iterator_to_array($lines));
//echo "<br>";

// Loop over whole file to use a single line
foreach ($lines as $line) {

    print_r($line);
    echo "<br>";

}