L'uso di un ciclo di fgets()chiamate è una soluzione eccellente e la più semplice da scrivere, tuttavia:
anche se internamente il file viene letto utilizzando un buffer di 8192 byte, il codice deve comunque chiamare quella funzione per ogni riga.
è tecnicamente possibile che una singola riga possa essere più grande della memoria disponibile se stai leggendo un file binario.
Questo codice legge un file in blocchi di 8 kB ciascuno e quindi conta il numero di nuove righe all'interno di quel blocco.
function getLines($file)
{
$f = fopen($file, 'rb');
$lines = 0;
while (!feof($f)) {
$lines += substr_count(fread($f, 8192), "\n");
}
fclose($f);
return $lines;
}
Se la lunghezza media di ogni riga è al massimo 4kB, inizierai già a risparmiare sulle chiamate di funzione e queste possono sommarsi quando elabori file di grandi dimensioni.
Prova delle prestazioni
Ho eseguito un test con un file da 1 GB; ecco i risultati:
+-------------+------------------+---------+
| This answer | Dominic's answer | wc -l |
+------------+-------------+------------------+---------+
| Lines | 3550388 | 3550389 | 3550388 |
+------------+-------------+------------------+---------+
| Runtime | 1.055 | 4.297 | 0.587 |
+------------+-------------+------------------+---------+
Il tempo è misurato in secondi in tempo reale, guarda qui cosa significa reale
\n) analizzato su una macchina Windows (PHP_EOL == '\r\n')