cari

Rumah  >  Soal Jawab  >  teks badan

Pembacaan PHP terbalik bagi fail CSV

<p>Saya mempunyai skrip PHP yang membaca fail CSV dan saya mahu ia membacanya bermula dari baris terakhir, iaitu, dalam susunan terbalik. </p> <pre class="brush:php;toolbar:false;"><?php $f = fopen("./data/data-esp8266-$idluf-$currentdata.csv", "r"); fgets($f); manakala (($line = fgetcsv($f)) !== palsu) { $row = $line[0]; $cells = meletup(";",$row); echo "<tr>n"; foreach ($sel sebagai $sel) { echo "<td><a style='text-decoration:none;color:#fff;' class='tooltip' data-tool=' $cell'>" . /a></td>n"; } echo "</tr>n"; } fclose($f); ?></pra> <p><br /></p>
P粉512729862P粉512729862476 hari yang lalu655

membalas semua(2)saya akan balas

  • P粉118698740

    P粉1186987402023-08-09 12:56:44

    Jika fail yang anda ingin baca ialah fail "mudah" dengan hanya baris baharu sebagai pembatas, membaca dari belakang ke hadapan akan menjadi agak mudah. Walau bagaimanapun, CSV ialah format yang lebih kompleks, dengan pembatas medan dan baris, tanda petikan (petikan) dan aksara melarikan diri. Anda mungkin menjumpai data seperti

    id,name,value
    1,foo,"hello world"
    2,bar,"hello 
    world"
    3, baz,"""hello 
    world"""
    

    Ini adalah CSV yang sangat sah, tetapi kebanyakan penyelesaian yang dicadangkan pada masa ini di forum akan menghadapi masalah membaca data secara terbalik.

    Kaedah yang paling boleh dipercayai adalah dengan terlebih dahulu membaca data dari permulaan fail dan kemudian menggunakan maklumat ini untuk membaca data secara terbalik. Versi paling mudah adalah dengan hanya meletakkan segala-galanya ke dalam tatasusunan dan kemudian membaca tatasusunan secara terbalik, seperti ini:

    $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);
    

    Tetapi jika anda berurusan dengan fail yang besar, anda mungkin menghadapi had memori kerana semua data perlu disimpan.

    Alternatifnya ialah membaca fail sekali dan kemudian hanya menyimpan fail mengimbangi pada permulaan rekod dan kemudian melelang ke belakang sekali lagi menggunakan pengimbangan tersebut.


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

    Terdapat pertukaran bahawa fail perlu dilalui dua kali, tetapi jika terdapat kekangan memori, maka ini perlu dilakukan.

    Dengan semua pepatah ini, pilihan yang lebih baik ialah meletakkan data dalam pangkalan data, di mana pangkalan data boleh menyusun semula data dengan mudah jika boleh. Kod ini sudah melaksanakan semula fungsi berkaitan pangkalan data sedikit sebanyak, tetapi ia lebih teruk.

    balas
    0
  • P粉513316221

    P粉5133162212023-08-09 10:41:12

    Sebagai alternatif, anda juga boleh menggunakan gelung 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";
    }
    
    ?>

    Kaedah ini sepatutnya lebih pantas daripada kaedah lain berdasarkan array_reverse() fungsi

    balas
    0
  • Batalbalas