recherche

Maison  >  Questions et réponses  >  le corps du texte

Lecture PHP inversée du fichier CSV

<p>J'ai un script PHP qui lit un fichier CSV et je souhaite qu'il le lise à partir de la dernière ligne, c'est-à-dire dans l'ordre inverse. </p> <pre class="brush:php;toolbar:false;"><?php $f = fopen("./data/data-esp8266-$idluf-$currentdata.csv", "r"); fgets($f); while (($line = fgetcsv($f)) !== false) { $ligne = $ligne[0]; $cells = exploser(";",$row); echo "<tr>n" ; foreach ($cellules comme $cell) { echo "<td><a style='text-decoration:none;color:#fff;' class='tooltip' data-tool=' $cell'>" . /a></td>n"; } echo "</tr>n" ; } ffermer($f); ?>≪/pré> <p><br /></p>
P粉512729862P粉512729862552 Il y a quelques jours758

répondre à tous(2)je répondrai

  • P粉118698740

    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.

    répondre
    0
  • P粉513316221

    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()

    répondre
    0
  • Annulerrépondre