Buat atau tulis / tambahkan dalam file teks

170

Saya memiliki situs web yang setiap kali pengguna log in atau log out saya menyimpannya ke file teks.

Kode saya tidak berfungsi dalam menambahkan data atau membuat file teks jika tidak ada .. Berikut adalah contoh kode

$myfile = fopen("logs.txt", "wr") or die("Unable to open file!");
$txt = "user id date";
fwrite($myfile, $txt);
fclose($myfile);

Sepertinya tidak ditambahkan ke baris berikutnya setelah saya buka lagi.

Juga saya pikir itu juga akan memiliki kesalahan dalam situasi ketika 2 pengguna masuk pada saat yang sama, apakah akan mempengaruhi membuka file teks dan menyimpannya setelah itu?

Jerahmeel Acebuche
sumber

Jawaban:

337

Coba sesuatu seperti ini:

 $txt = "user id date";
 $myfile = file_put_contents('logs.txt', $txt.PHP_EOL , FILE_APPEND | LOCK_EX);
SpencerX
sumber
5
apakah ini membuat file teks jika tidak ada?
Jerahmeel Acebuche
5
Yup itu membuat file teks logs.txtdan menambahkan konten di dalamnya
SpencerX
5
Saya punya pertanyaan. menggunakan LOCK_EX. saya tahu bahwa ini akan mencegah orang lain menulis ke file pada saat yang sama. tetapi apa yang akan terjadi pada yang lain?
Jerahmeel Acebuche
13
php.net/manual/en/function.file-put-contents.php Fungsi ini mengembalikan jumlah byte yang ditulis ke file, atau FALSE pada kegagalan. Hanya jika ada yang bertanya-tanya.
Master James
7
@JerahmeelAcebuche Proses kedua untuk mencoba mendapatkan kunci "akan memblokir sampai kunci yang diminta diperoleh" ( sumber ). Dengan kata lain, proses kedua akan menunggu sampai yang pertama telah menutup file dan melepaskan kunci.
rinogo
102

Gunakan amode. Itu singkatan append.

$myfile = fopen("logs.txt", "a") or die("Unable to open file!");
$txt = "user id date";
fwrite($myfile, "\n". $txt);
fclose($myfile);
Valentin Mercier
sumber
saya juga punya masalah dengan \ n. tidak bekerja. apakah itu bekerja untukmu?
Jerahmeel Acebuche
1
apakah ini berfungsi jika situasinya terjadi seperti yang saya katakan?
Jerahmeel Acebuche
1
yang abendera akan membuat file jika tidak ada dan tidak ada yang akan peduli apa pastikan bahwa Anda benar-benar appendteks baru. Untuk \nitu berfungsi tetapi hanya jika di dalam tanda kutip ganda "bukan tanda kutip tunggal'
Valentin Mercier
maksud saya situasi bagaimana jika dua pengguna login di browser yang berbeda. maka php akan membuka file pada dua browser pada waktu yang sama dan memperbaruinya pada waktu yang sama juga. apakah akan ada masalah? \
Jerahmeel Acebuche
1
Oh, ya akan ada, dalam hal ini menggunakan database SQL, ia memiliki mesin bawaan untuk menghindari kondisi balapan. Tapi itu pertanyaan yang sama sekali baru.
Valentin Mercier
10

Anda dapat melakukannya dengan cara OO, hanya sebuah alternatif dan fleksibel:

class Logger {

    private
        $file,
        $timestamp;

    public function __construct($filename) {
        $this->file = $filename;
    }

    public function setTimestamp($format) {
        $this->timestamp = date($format)." » ";
    }

    public function putLog($insert) {
        if (isset($this->timestamp)) {
            file_put_contents($this->file, $this->timestamp.$insert."<br>", FILE_APPEND);
        } else {
            trigger_error("Timestamp not set", E_USER_ERROR);
        }
    }

    public function getLog() {
        $content = @file_get_contents($this->file);
        return $content;
    }

}

Kemudian gunakan seperti ini .. katakanlah Anda telah user_namemenyimpan dalam satu sesi (kode semi pseudo):

$log = new Logger("log.txt");
$log->setTimestamp("D M d 'y h.i A");

if (user logs in) {
    $log->putLog("Successful Login: ".$_SESSION["user_name"]);
}
if (user logs out) {
    $log->putLog("Logout: ".$_SESSION["user_name"]);
}

Periksa log Anda dengan ini:

$log->getLog();

Hasilnya seperti:

Sun Jul 02 '17 05.45 PM » Successful Login: JohnDoe
Sun Jul 02 '17 05.46 PM » Logout: JohnDoe


github.com/thielicious/Logger

Sangat berbahaya
sumber
1
Terima kasih banyak untuk kelas Logger ini! Saya tidak berharap untuk menemukan bahwa ketika saya menemukan halaman ini ... tapi sebenarnya itu adalah dasar dari solusi yang jauh lebih baik daripada apa yang awalnya saya rencanakan untuk implementasikan.
Myke Carter
4

Ini berfungsi untuk saya, Menulis (membuat juga) dan / atau menambahkan konten dalam mode yang sama.

$fp = fopen("MyFile.txt", "a+") 
Mihir Bhatt
sumber
3

Coba kode ini:

function logErr($data){
  $logPath = __DIR__. "/../logs/logs.txt";
  $mode = (!file_exists($logPath)) ? 'w':'a';
  $logfile = fopen($logPath, $mode);
  fwrite($logfile, "\r\n". $data);
  fclose($logfile);
}

Saya selalu menggunakannya seperti ini, dan berfungsi ...

Rwakos
sumber
1
Tidak ada alasan untuk melakukan (!file_exists($logPath)) ? 'w':'a'- aopsi sudah memiliki perilaku yang benar ketika file tidak ada. Jadi dapat menyederhanakan jawaban ini dengan menghapus baris $mode = ...;, dan mengubah baris berikutnya menjadi $logfile = fopen($logPath, 'a');.
ToolmakerSteve
2

Tidak ada mode buka file seperti "wr" dalam kode Anda:

fopen("logs.txt", "wr") 

Mode buka file di PHP http://php.net/manual/en/function.fopen.php sama dengan di C: http://www.cplusplus.com/reference/cstdio/fopen/

Ada mode terbuka utama berikut "r" untuk dibaca, "w" untuk menulis dan "a" untuk ditambahkan, dan Anda tidak dapat menggabungkannya. Anda dapat menambahkan pengubah lain seperti "+" untuk pembaruan, "b" untuk biner. Standar C baru menambahkan subspecifier standar baru ("x"), didukung oleh PHP, yang dapat ditambahkan ke specifier "w" (untuk membentuk "wx", "wbx", "w + x" atau "w + bx "/" wb + x "). Subspecifier ini memaksa fungsi gagal jika file ada, alih-alih menimpanya.

Selain itu, di PHP 5.2.6, mode buka utama 'c' ditambahkan. Anda tidak dapat menggabungkan 'c' dengan 'a', 'r', 'w'. 'C' membuka file hanya untuk menulis. Jika file tidak ada, itu dibuat. Jika ada, maka tidak terpotong (tidak seperti 'w'), atau panggilan ke fungsi ini gagal (seperti halnya dengan 'x'). 'c +' Buka file untuk membaca dan menulis; selain itu ia memiliki perilaku yang sama dengan 'c'.

Selain itu, dan dalam PHP 7.1.2 opsi 'e' ditambahkan yang dapat dikombinasikan dengan mode lainnya. Ini mengatur flag close-on-exec pada deskriptor file yang dibuka. Hanya tersedia di PHP yang dikompilasi pada sistem yang sesuai POSIX.1-2008.

Jadi, untuk tugas seperti yang Anda gambarkan, mode buka file terbaik adalah 'a'. Ini membuka file hanya untuk menulis. Ini menempatkan penunjuk file di akhir file. Jika file tidak ada, ia mencoba membuatnya. Dalam mode ini, fseek () tidak berpengaruh, menulis selalu ditambahkan.

Inilah yang Anda butuhkan, sebagaimana telah disebutkan di atas:

fopen("logs.txt", "a") 
Maxim Masiutin
sumber
0

Meskipun ada banyak cara untuk melakukan ini. Tetapi jika Anda ingin melakukannya dengan cara yang mudah dan ingin memformat teks sebelum menulisnya ke file log. Anda dapat membuat fungsi pembantu untuk ini.

if (!function_exists('logIt')) {
    function logIt($logMe)
    {
        $logFilePath = storage_path('logs/cron.log.'.date('Y-m-d').'.log');
        $cronLogFile = fopen($logFilePath, "a");
        fwrite($cronLogFile, date('Y-m-d H:i:s'). ' : ' .$logMe. PHP_EOL);
        fclose($cronLogFile);
    }
}
PHP Worm ...
sumber