PHP way to get count of lines in file and to move file pointer to specified line? [closed]
-
16-06-2021 - |
Domanda
Is there a way to:
- count number of lines (1 line = data row) in my small_db.php
- tell PHP to move file pointer exactly to start of line 322. (so I could fgets() data from this line)
- tell PHP to return line number or entire content of line in which text "Quick brown fox" occures?
I know there is another way by getting all contents of file in one single string, but as you know that method is time and memory inefficient if the size of file is big.
Soluzione
To start out with, here is some basic variables:
$filename = 'small_db.php';
$linenum = 322;
$needle = 'Quick brown fox';
How can I count number of lines in a file?
To do this quickly and easily, use
count()
after you open the file withfile()
:$count = count( file( $filename));
However, this will use a lot of memory if your file is large, as it has to load the entire file into memory in order to count the return value from
file()
. Alternatively, you can use the standard file functions,fopen()
,feof()
,fgets()
, andfclose()
, to open the file and read it line by line, keeping a count as you go, like so:$count = 0; $fp = fopen( $filename, 'r'); while( !feof( $fp)) { fgets( $fp); $count++; } fclose( $fp);
How can I move a file pointer to the start of a specific line number?
This is best achieved using the
SplFileObject
class. You create a new object of this class with the filename of the file you're opening, then useseek()
to seek to the line number of your choosing. You can then usekey()
to show the line number andcurrent()
(orgetCurrentLine()
orfgets()
) to get the contents of that line, like so:// Create a new object for the file $file = new SplFileObject( $filename); // Seek to to the specific line number $file->seek( $linenum); // Print that line: echo 'Line #' . $file->key() . ' contains: ' . $file->current();
How can I return the line number or the entire content of line in which a specific needle occurs?
There is no inbuilt PHP functions / methods that can do this as far as I know. You will need to parse it yourself with something similar to this function, which checks each line in a file, given by its file pointer
$fp
, against a specific case-sensitive$needle
usingstrpos()
(you can usestripos()
for case-insensitive searching):function find_in_file( $fp, $needle) { rewind( $fp); // Or: fseek($fp, 0); $line_number = 0; while( !feof( $fp)) { $line = fgets( $fp); if( !( strpos( $line, $needle) === false)) { break; } $line_number++; } return feof( $fp) ? null : array( 'line_number' => $line_number, 'line' => fgets( $fp) ); }
You'd need to call this function like so:
$fp = fopen( $filename, 'r'); $return = find_in_file( $fp, $needle); if( !is_null( $return)) { echo 'Found ' . $needle . ' in line #' . $return['line_number'] . "\n"; echo 'That line contains: ' . $return['line']; } fclose( $fp);