Comment implémenter PHP pour lire certaines lignes d'un gros fichier : 1. Utilisez directement la fonction file pour opérer ; 2. Appelez la commande Linux tail pour afficher les dernières lignes ; . Via PHP La fonction stream_get_line implémente la lecture.
L'environnement d'exploitation de cet article : système windows7, version PHP7.1, ordinateur DELL G3
php Comment lire certaines lignes d'un gros fichier ?
Introduction à diverses méthodes de lecture de gros fichiers avec PHP
La lecture de gros fichiers a toujours été un casse-tête Nous pouvons utiliser diverses fonctions pour utiliser directement PHP pour lire de petits fichiers, mais lorsqu'il s'agit d'articles volumineux, ce sera le cas. a constaté que les méthodes couramment utilisées ne peuvent pas être utilisées normalement ou prennent trop de temps et sont bloquées. Examinons les solutions au problème de lecture de fichiers volumineux en PHP. J'espère que les exemples pourront vous aider.
En PHP, lors de la lecture de fichiers, le moyen le plus rapide est d'utiliser certaines fonctions telles que file et file_get_contents. Quelques lignes de code simples peuvent compléter à merveille les fonctions dont nous avons besoin. Mais lorsque le fichier exploité est un fichier relativement volumineux, ces fonctions peuvent s'avérer insuffisantes. Ce qui suit commencera par expliquer les méthodes d'exploitation couramment utilisées lors de la lecture de fichiers volumineux.
Exigences :
Il existe un fichier journal de 800 M avec environ 5 millions de lignes. Utilisez PHP pour renvoyer le contenu des dernières lignes.
Méthode d'implémentation :
1. Utilisez directement la fonction de fichier pour fonctionner
Étant donné que la fonction de fichier lit tout le contenu dans la mémoire en même temps, PHP empêche certains programmes mal écrits d'occuper trop de mémoire et de provoquer une mémoire système insuffisante, provoquant le crash du serveur, donc par défaut l'utilisation maximale de la mémoire est limitée à 16 Mo. Ceci est défini via memory_limit = 16M dans php.ini. Si cette valeur est définie sur -1, l'utilisation de la mémoire n'est pas limitée.
Ce qui suit est un morceau de code qui utilise file pour extraire la dernière ligne de ce fichier :
<?php ini_set('memory_limit', '-1'); $file = 'access.log'; $data = file($file); $line = $data[count($data) - 1]; echo $line; ?>
L'exécution de l'intégralité du code prend 116,9613 (s).
Ma machine dispose de 2 Go de mémoire. Lorsque j'appuie sur F5 pour exécuter, le système devient gris et ne récupère qu'après près de 20 minutes. On voit que les conséquences de la lecture d'un fichier aussi volumineux directement dans la mémoire sont graves, alors je. Je n'en parlerai pas ici. En dernier recours, memory_limit ne peut pas être réglé trop haut, sinon vous devrez appeler la salle informatique pour réinitialiser la machine.
2. Appelez directement la commande Linux tail pour afficher les dernières lignes
Sous la ligne de commande Linux, vous pouvez directement utiliser tail -n 10 access.log pour afficher facilement les dernières lignes du fichier journal. utilisez PHP pour appeler la commande tail, exécutez le code PHP comme suit :
<?php $file = 'access.log'; $file = escapeshellarg($file); // 对命令行参数进行安全转义 $line = `tail -n 1 $file`; echo $line; ?>
L'exécution complète du code prend 0,0034 (s)
3 Utilisez directement le fseek de PHP pour effectuer des opérations sur les fichiers
Cette méthode est la méthode la plus courante, elle le fait. ne nécessite pas que tout le contenu du fichier soit lu, mais exploité directement via des pointeurs, l'efficacité est donc assez efficace. Lorsque vous utilisez fseek pour exploiter des fichiers, il existe de nombreuses méthodes différentes, et l'efficacité peut être légèrement différente. Voici deux méthodes couramment utilisées :
Méthode 1
Tout d'abord, recherchez le dernier EOF du fichier via fseek. position de départ de la dernière ligne, prenez les données de cette ligne, puis trouvez la position de départ de la ligne suivante, puis prenez la position de cette ligne, et ainsi de suite, jusqu'à ce que la ligne $num soit trouvée.
Le code d'implémentation est le suivant
<?php $fp = fopen($file, "r"); $line = 10; $pos = -2; $t = " "; $data = ""; while ($line > 0) { while ($t != "\n") { fseek($fp, $pos, SEEK_END); $t = fgetc($fp); $pos--; } $t = " "; $data .= fgets($fp); $line--; } fclose($fp); echo $data ?>
L'exécution de l'intégralité du code prend 0,0095 (s)
Méthode 2
Toujours en utilisant fseek pour lire à partir de la fin du fichier, mais cette fois il ne lit pas un par un , mais une lecture une par une, chaque fois qu'une donnée est lue, les données lues sont placées dans un buf, puis le nombre de caractères de nouvelle ligne (\n) est utilisé pour déterminer si les dernières lignes de données $num ont été lire.
Le code d'implémentation est le suivant
<?php $fp = fopen($file, "r"); $num = 10; $chunk = 4096; $fs = sprintf("%u", filesize($file)); $max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file); for ($len = 0; $len < $max; $len += $chunk) { $seekSize = ($max - $len > $chunk) ? $chunk : $max - $len; fseek($fp, ($len + $seekSize) * -1, SEEK_END); $readData = fread($fp, $seekSize) . $readData; if (substr_count($readData, "\n") >= $num + 1) { preg_match("!(.*?\n){" . ($num) . "}$!", $readData, $match); $data = $match[0]; break; } } fclose($fp); echo $data; ?>
L'exécution entière du code prend 0,0009(s).
Troisième méthode
<?php function tail($fp, $n, $base = 5) { assert($n > 0); $pos = $n + 1; $lines = array(); while (count($lines) <= $n) { try { fseek($fp, -$pos, SEEK_END); } catch (Exception $e) { fseek(0); break; } $pos *= $base; while (!feof($fp)) { array_unshift($lines, fgets($fp)); } } return array_slice($lines, 0, $n); } var_dump(tail(fopen("access.log", "r+"), 10)); ?>
L'exécution entière du code prend 0,0003(s)
La quatrième méthode, la fonction stream_get_line de PHP, lit rapidement, et il faut environ 20 secondes pour lire un gros fichier contenant 500 000 données ! L'exemple de code est le suivant
$fp = fopen('./iis.log', 'r'); //文件 while (!feof($fp)) { //for($j=1;$j<=1000;$j++) { //读取下面的1000行并存储到数组中 $logarray[] = stream_get_line($fp, 65535, "\n"); // break; // } }
Apprentissage recommandé : "Tutoriel vidéo PHP"
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!