PHP: bagaimana cara menghapus jeda baris terakhir dari file teks?

Dalam tugas sekolah, saya membangun situs untuk museum luar angkasa fiksi di kota saya menggunakan PHP. Ini memiliki sistem Inklusi Data dan Konsultasi Data, tetapi saya memiliki masalah dengan konsultasi yang ingin saya ketahui cara mengatasinya: bagaimana cara menghapus baris terakhir dari file?

Inklusi Data

Di area terlarang situs, saya memiliki formulir HTML5 dengan 5 bidang (nama, alamat, nomor telepon, jenis kelamin dan pameran yang dikunjungi) yang mengirimkan data dengan metode POST ke fungsi di PHP yang menuliskannya pada file txt tertentu dengan menggunakan perintah fwrite:

fwrite ($pointer, "$name | $addres | $telephone | $sex | $exhibitions " .PHP_EOL);

Seperti yang Anda lihat, ia menulis dalam file txt data yang dimasukkan pada formulir, ditambah jeda baris. Pointer adalah variabel yang digunakan oleh fopen untuk membuka file yang saya perlukan agar berfungsi. Contoh keluaran:

Márcio Aguiar | Jalan Belmiro Braga | 1234-5678 | M | Planet Tata Surya
Joana Tobias | Jalan Santos Dummont | 8765-4321 | F | Lubang Hitam, Satelit

Konsultasi Data

Lalu ada sistem konsultasi. Ini memiliki loop yang berjalan hingga file berakhir. Di dalam loop ini ada variabel bernama $buffer yang mendapatkan satu baris file txt setiap kali. Kemudian exploded membuat array bernama $lines[$counter]. Untuk mencetaknya dengan baik, saya menggunakan array_combine di mana saya menggabungkan nama bidang pada array lain ($keys) dengan nilai yang ditulis dalam $lines[$counter], dan mengatribusikannya ke $combined[$counter]. Kemudian loop berakhir dan saya menggunakan print_r di dalam <pre></pre> untuk melihat data yang ditulis dalam $combined, sambil mempertahankan spasi dan jeda yang akan diabaikan oleh HTML. Ini kodenya:

$keys = array ("Name", "Address", "Telephone", "Sex", "Visited exhibition");
for ($counter=0;!feof($reader);$counter++){
    $buffer = fgets($reader);
    $lines[$counter] = explode(" | ", $buffer);
    $combined[$counter] = array_combine($keys, $lines[$counter]);
}
echo "<pre>";
print_r($combined);
echo "</pre>";

Contoh keluaran:

    Array
    (
    [0] => Array
        (
            [Name] => Márcio Aguiar
            [Address] => Belmiro Braga Street
            [Telephone] => 1234-5678
            [Sex] => M
            [Visited exhibitions] => Planets of Solar System 

        )

    [1] => Array
        (
            [Name] => Joana Tobias
            [Address] => Santos Dummont Avenue
            [Telephone] => 8765-4321
            [Sex] => F
            [Visited exhibitions] => Black Holes, Satellites 

        )

    [2] => 
    )

Di sini Anda dapat melihat bahwa 2 Array dibuat kosong. Hal ini disebabkan karena baris terakhir hanya berisi satu baris saja yang disisipkan oleh form di atas. Saya perlu menghapus jeda baris terakhir ini, dan hanya yang itu, tetapi tidak tahu caranya. Saya ingin tahu! Ketidaktahuan menyebabkan munculnya kesalahan ketika eksekusi tiba di array_combine, karena kedua array harus memiliki jumlah elemen yang sama, dan 2 kosong. Ini kesalahannya:

Peringatan: array_combine(): Kedua parameter harus memiliki jumlah elemen yang sama di E:\Aluno\Documents\Wamp\www\trab_1\area_restrita\consulta.php on line 60


person Anders    schedule 04.05.2015    source sumber


Jawaban (3)


Jawaban asli:

Untuk menghapus jeda baris di akhir teks, Anda dapat menggunakan trim(), namun dalam kasus Anda, Anda hanya perlu menggunakan fopen dalam mode penambahan :

$handle = fopen("/path/to/file", "a");

Kemudian singkirkan PHP_EOL:

fwrite ($pointer, "$name | $addres | $telephone | $sex | $exhibitions");

Sunting: Anda benar bahwa menambahkan tidak berarti menambahkan pada baris baru. saya salah. Jadi Anda bisa menggunakan trim() seperti yang saya sebutkan sebelumnya. Saya membuat contoh cepat menggunakan file_get_contents() dan file_put_contents() dan tampaknya melakukan apa yang Anda inginkan:

<?php

$file = 'test.txt';

// Set existing contents (for testing sake)
$orig_contents = "bob | 123 fake street | 1234567890 | yes, please | no\n";
$orig_contents .= "bob | 123 fake street | 1234567890 | yes, please | no\n";
$orig_contents .= "bob | 123 fake street | 1234567890 | yes, please | no\n";
$orig_contents .= "bob | 123 fake street | 1234567890 | yes, please | no\n";
file_put_contents($file, $orig_contents);

// Here is how you could add a single new line with append mode
// Notice the trailing \n
file_put_contents($file, "billy | 456 fake street | 2345678901 | no | yes\n", FILE_APPEND);

// Get contents from the file and remove any trailing line breaks
$contents = trim(file_get_contents($file));

$keys = array ("Name", "Address", "Telephone", "Sex", "Visited exhibition");

// Explode based on the new line character
$lines = explode("\n", $contents);

foreach ($lines as $line) {
    $values = explode(" | ", $line);
    $combined[] = array_combine($keys, $values);
}

print_r($combined);

Ini mencetak:

Array
(
    [0] => Array
        (
            [Name] => bob
            [Address] => 123 fake street
            [Telephone] => 1234567890
            [Sex] => yes, please
            [Visited exhibition] => no
        )

    [1] => Array
        (
            [Name] => bob
            [Address] => 123 fake street
            [Telephone] => 1234567890
            [Sex] => yes, please
            [Visited exhibition] => no
        )

    [2] => Array
        (
            [Name] => bob
            [Address] => 123 fake street
            [Telephone] => 1234567890
            [Sex] => yes, please
            [Visited exhibition] => no
        )

    [3] => Array
        (
            [Name] => bob
            [Address] => 123 fake street
            [Telephone] => 1234567890
            [Sex] => yes, please
            [Visited exhibition] => no
        )

    [4] => Array
        (
            [Name] => billy
            [Address] => 456 fake street
            [Telephone] => 2345678901
            [Sex] => no
            [Visited exhibition] => yes
        )

)
person Mike    schedule 04.05.2015
comment
Saya tidak tahu di mana harus menggunakan trim, bisakah Anda menjelaskannya? - person Anders; 05.05.2015
comment
Anda tidak meletakkan trim di mana pun. Buka saja file dengan mode penambahan seperti yang dijelaskan oleh jawaban lainnya. - person Mike; 05.05.2015
comment
Saya sudah menggunakan a di fopen. Menghapus PHP_EOL membuat data orang yang berbeda disisipkan semuanya dalam satu baris, tetapi saya memerlukan informasi yang didistribusikan ke banyak baris, satu untuk setiap orang. - person Anders; 05.05.2015
comment
Saya melihat, tetapi tidak dapat memahami sepenuhnya... Saat Anda menggunakan baris $contents = trim(file_get_contents($file)); Anda mendapatkan konten lengkap file dengan menggunakan file_get_contents(), menghapus semua \n dengan menggunakan trim() dan mengaitkan hasilnya ke $contents, bukan? Jadi mengapa Anda kemudian menggunakan $lines = explode("\n", $contents);? Saya memahami bahwa baris ini membagi $contents dalam substring dibagi dengan \ns, dan mengatribusikan matriks string ini ke $lines dengan menggunakan explode()... Tetapi mengapa menggunakan parameter \n pada explode() jika Anda sudah menghapus semua \ns menggunakan trim()? - person Anders; 10.05.2015
comment
@Anders Alasannya adalah karena trim() hanya menghapus karakter spasi pertama dan terakhir. Jadi jika Anda memiliki {tab}line one{line break}line two{space}{line break} maka akan diubah menjadi line one{line break}line two. Itu tidak menghilangkan setiap baris baru, hanya jika ada satu baris di awal atau di akhir. Dan saya melakukan explode() untuk membagi string menjadi sebuah array dengan setiap baris menjadi nilai dalam array sehingga saya bisa mengulanginya. - person Mike; 11.05.2015
comment
Saya baru saja menemukan fungsi menarik lainnya yang dapat berfungsi sebagai pengganti explode dan loop: strtok. Anda mungkin ingin melihatnya juga. - person Mike; 11.05.2015

Masalahnya ada pada cara Anda membaca file. Anda sedang menguji EOF sebelum membaca dari file. Namun feof() tidak akan benar sampai Anda mencoba membaca saat Anda berada di akhir file.

Sebaliknya, Anda harus menguji apakah fgets() mengembalikan sebuah baris.

for ($counter = 0; $buffer = fgets($reader); $counter++) {
    $lines[$counter] = explode(" | ", $buffer);
    $combined[$counter] = array_combine($keys, $lines[$counter]);
}

DEMO

Untuk menjelaskan lebih lanjut, misalkan Anda memiliki file dengan satu baris di dalamnya. Ketika $counter adalah 0, Anda memanggil feof(), dan ia mengembalikan false. Jadi Anda membaca baris pertama, dan menambahkannya ke $lines dan $combined. Kemudian Anda menambah $counter dan kembali ke awal perulangan.

Ketika $counter adalah 1, Anda menelepon feof(). Itu masih belum benar, karena Anda belum mencoba membaca di bagian akhir file. Kemudian Anda mencoba membaca baris berikutnya, tetapi tidak ada baris di sana, fgets mengembalikan false dan Anda menetapkan ini ke $buffer. Ini diperlakukan sebagai string kosong oleh explode(), jadi Anda menambahkan array kosong ke $lines dan $combined. Kemudian Anda menambah $counter dan kembali ke awal perulangan.

Kemudian Anda memanggil feof(), dan kali ini mengembalikan true karena Anda mencoba membaca di akhir file pada iterasi sebelumnya. Jadi perulangannya berakhir.

Seperti yang Anda lihat di atas, meskipun file hanya memiliki 1 baris, Anda berakhir dengan 2 entri dalam array Anda, karena Anda tidak menguji EOF sampai Anda membaca terlalu jauh.

person Barmar    schedule 05.05.2015
comment
Saya mengerti sekarang. Namun mengubah loop seperti yang Anda sarankan membuatnya bekerja dengan sangat aneh... Dengan 3 item ini: ›a | b | c | M | def ›1 | 2 | 3 | M | 456 ›56 | 78 | 91 | M | 23 › Saya mendapatkan output ini: Array ( [0] =› Array ( [Nama] =› 1 [Alamat] =› 2 [Telepon] =› 3 [Jenis Kelamin] =› M [Pameran yang dikunjungi] =› 456 ) [1] =› ) - person Anders; 05.05.2015
comment
Salah ketik: $lines[counter] seharusnya $lines[$counter] - person Barmar; 05.05.2015
comment
Anda juga kehilangan tanda kurung tutup untuk array_combine. Bagaimana kodenya berjalan? - person Barmar; 05.05.2015
comment
Kesalahan ketik dan tanda kurung yang hilang tidak ada dalam kode. Mereka diperkenalkan ketika saya menerjemahkan kode untuk diposting di sini. - person Anders; 05.05.2015
comment
Tidak ada format dalam komentar, jadi saya tidak tahu apa masukan dan keluaran Anda. Harap perbarui pertanyaan dengan kode Anda yang sebenarnya, masukan pengujian, dan keluaran. - person Barmar; 05.05.2015
comment
Saya tidak mengerti apa yang Anda ingin saya tambahkan... Sudah ada masukan tes dan keluaran pada pertanyaan. - person Anders; 05.05.2015
comment
Tunjukkan masukan dan keluaran yang Anda dapatkan saat mencoba mengimplementasikan jawaban saya. - person Barmar; 05.05.2015

Jika Anda ingin menghilangkan jeda baris terakhir pada data yang Anda ambil dari db ($res) Anda dapat menggunakan cuplikan berikut

for ($i=0; $i <count($res); $i++) {

    // If this is not last item then add items separated by line break
    if($i+1 < count($res)) {
        file_put_contents("file.txt", $res[$i].PHP_EOL, FILE_APPEND);
    }
    // If this is the last item, then don't append the final line break
    else {
        file_put_contents("file.txt", $res[$i], FILE_APPEND);
    }
}
person Robert Sinclair    schedule 29.06.2018