Maison > Questions et réponses > le corps du texte
P粉1186987402023-08-09 12:56:44
Si le fichier que vous souhaitez lire est un fichier "simple" avec juste des nouvelles lignes comme délimiteurs, la lecture de l'arrière vers l'avant sera assez simple. Cependant, CSV est un format plus complexe, avec des délimiteurs de champs et de lignes, des guillemets (guillemets) et des caractères d'échappement. Vous pouvez rencontrer des données telles que
id,name,value 1,foo,"hello world" 2,bar,"hello world" 3, baz,"""hello world"""
Il s'agit d'un CSV parfaitement valide, mais la plupart des solutions actuellement proposées sur les forums auront du mal à lire les données à l'envers.
La méthode la plus fiable consiste à lire d'abord les données depuis le début du fichier, puis à utiliser ces informations pour lire les données à l'envers. La version la plus simple consiste simplement à tout mettre dans un tableau, puis à lire le tableau à l'envers, comme ceci :
$f = fopen("./data/data-esp8266-$idluf-$currentdata.csv", "r"); fgets($f); $lines = []; while (($lines[] = fgetcsv($f)) !== false) {} for( $i=count($lines)-1; $i>=0; --$i ) { $line = lines[$i]; $row = $line[0]; // Dobbiamo ottenere la riga effettiva (è il primo elemento in un array di 1 elemento) $cells = explode(";",$row); echo "<tr>\n"; foreach ($cells as $cell) { echo "<td><a style='text-decoration:none;color:#fff;' class='tooltip' data-tool=' $cell'>" . htmlspecialchars($cell) . "</a></td>\n"; } echo "</tr>\n"; } fclose($f);
Mais si vous avez affaire à un fichier volumineux, vous risquez de rencontrer des limitations de mémoire car toutes les données doivent être stockées.
Une alternative serait de lire le fichier une fois, puis de simplement stocker les décalages du fichier au début de l'enregistrement, puis d'utiliser ces décalages pour itérer à nouveau en arrière.
function csv_reverse($handle, ...$csv_options) { $offsets = []; do { $offsets[] = ftell($handle); } while($row = fgetcsv($handle, ...$csv_options)); array_pop($offsets); // last offset is EOF for( $i=count($offsets)-1; $i>=0; --$i ) { fseek($handle, $offsets[$i]); yield fgetcsv($handle, ...$csv_options); } } $f = fopen("./data/data-esp8266-$idluf-$currentdata.csv", "r"); fgets($f); // assuming that this discards the header row $lines = []; while (($lines[] = fgetcsv($f)) !== false) {} foreach( csv_reverse($f) as $line ) { // same as above } fclose($f);
Il existe un compromis : le fichier doit être parcouru deux fois, mais s'il y a des contraintes de mémoire, cela doit être fait.
Tous ces dictons, une meilleure option est de mettre les données dans une base de données où les données peuvent être facilement réorganisées si possible. Ce code est déjà en quelque sorte une réimplémentation des fonctionnalités liées aux bases de données, mais c'est encore pire.
P粉5133162212023-08-09 10:41:12
Alternativement, vous pouvez également utiliser une boucle for
<?php $lines = file("./data/data-esp8266-$idluf-$currentdata.csv", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); // 将循环倒序遍历lines数组 for ($i = count($lines)-1; $i >= 0; $i--) { $row = $lines[$i]; $cells = explode(";", $row); echo "<tr>\n"; foreach ($cells as $cell) { echo "<td><a style='text-decoration:none;color:#fff;' class='tooltip' data-tool=' $cell'>" . htmlspecialchars($cell) . "</a></td>\n"; } echo "</tr>\n"; } ?>
Cette méthode devrait être plus rapide que les autres méthodes basées sur la fonction array_reverse()