Metin dosyasına oluşturma veya yazma / ekleme


171

Her kullanıcı oturum açtığında veya oturumu kapattığında bir metin dosyasına kaydettiğim bir web sitem var.

Kodum, veri ekleme veya yoksa bir metin dosyası oluşturmada çalışmıyor. İşte örnek kod

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

Tekrar açtıktan sonra bir sonraki satıra eklenmiyor gibi görünüyor.

Ayrıca, aynı anda 2 kullanıcı giriş yaptığında da bir hata olacağını düşünüyorum, metin dosyasını açmayı ve daha sonra kaydetmeyi etkiler mi?

Yanıtlar:


337

Bunun gibi bir şey deneyin:

 $txt = "user id date";
 $myfile = file_put_contents('logs.txt', $txt.PHP_EOL , FILE_APPEND | LOCK_EX);

5
yoksa bu bir metin dosyası oluşturur mu?
Jerahmeel Acebuche

5
Evet, metin dosyasını oluşturun logs.txtve içeriği ekleyin
SpencerX

5
bir sorum var. LOCK_EX kullanarak. Bu herkesin aynı anda dosyaya yazma engelleyeceğini biliyorum. ama diğerine ne olacak?
Jerahmeel Acebuche

13
php.net/manual/tr/function.file-put-contents.php Bu işlev, dosyaya yazılan bayt sayısını veya hata durumunda FALSE değerini döndürür. Sadece biri merak ederse.
Usta James

7
@JerahmeelAcebuche Kilidi edinmeye çalışan ikinci işlem "istenen kilit elde edilene kadar engellenir" ( kaynak ). Başka bir deyişle, ikinci işlem birincisi dosyayı kapatıp kilidi serbest bırakana kadar bekleyecektir.
rinogo

102

aModu kullanın . Anlamına gelir append.

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

Ayrıca \ n bu sorunu var. İşe yaramıyor. işinize yarıyor mu?
Jerahmeel Acebuche

1
söylediğim gibi durum olursa bu işe yarar mı?
Jerahmeel Acebuche

1
ao da mevcut değil ve hiçbir gerçekten emin ne olursa eğer bayrak dosyası oluşturur appendYeni bir metin. İçin \nçalıştığını ama sadece iç çift tırnak "değil tek tırnak'
Valentin Mercier

iki kullanıcı farklı tarayıcıda giriş yaparsanız ne demek istediğimi. php dosyayı aynı anda iki tarayıcıda açar ve aynı zamanda günceller. bir sorun olacak mı? \
Jerahmeel Acebuche

1
Oh, evet olacak, bu durumda bir SQL veritabanı kullanın, yarış koşullarından kaçınmak için yerleşik bir motoru vardır. Ama bu tamamen yeni bir soru.
Valentin Mercier

10

OO yolunu yapabilirsiniz, sadece alternatif ve esnek:

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

}

Sonra böyle kullanın .. diyelim ki user_namebir oturumda sakladınız (yarı sahte kod):

$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"]);
}

Günlüğünüzü şu şekilde kontrol edin:

$log->getLog();

Sonuç şöyle:

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


github.com/thielicious/Logger


1
Bu Logger sınıfı için çok teşekkürler! Bu sayfayı bulduğumda bunu beklemiyordum ... ama aslında aslında uygulamayı planladığımdan çok daha iyi bir çözümün temeli.
Myke Carter

4

Bu benim için çalışıyor, Yazıyor (oluşturuyor) ve / veya aynı modda içerik ekliyor.

$fp = fopen("MyFile.txt", "a+") 

3

Bu kodu deneyin:

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

Her zaman böyle kullanıyorum ve işe yarıyor ...


1
Bunu yapmak için hiçbir neden yoktur (!file_exists($logPath)) ? 'w':'a'- adosya olmadığında seçenek zaten doğru davranışa sahiptir. Böylece satırı kaldırarak $mode = ...;ve bir sonraki satırı değiştirerek bu cevabı basitleştirebiliriz $logfile = fopen($logPath, 'a');.
ToolmakerSteve

2

Kodunuzda "wr" gibi bir dosya açma modu yok:

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

PHP http://php.net/manual/en/function.fopen.php dosya açık modları C: http://www.cplusplus.com/reference/cstdio/fopen/ ile aynıdır

Aşağıdaki ana açık modları okumak için "r", yazmak için "w" ve ekleme için "a" vardır ve bunları birleştiremezsiniz. Güncelleme için "+", ikili dosya için "b" gibi başka değiştiriciler ekleyebilirsiniz. Yeni C standardı, PHP tarafından desteklenen ve herhangi bir "w" belirticisine eklenebilecek ("wx", "wbx", "w + x" veya "w + bx oluşturmak için) yeni bir standart alt belirtici (" x ") ekler "/" wB + x "). Bu alt belirtici, dosyanın üzerine yazmak yerine, işlev varsa başarısız olmaya zorlar.

Bunun yanı sıra, PHP 5.2.6'da 'c' ana açık modu eklendi. 'C' ile 'a', 'r', 'w' birleştiremezsiniz. 'C' dosyayı yalnızca yazmak için açar. Dosya yoksa, oluşturulur. Varsa, ne kesilir ('w' yerine) veya bu işleve çağrı başarısız olur ('x' ile olduğu gibi). 'c +' Dosyayı okumak ve yazmak için açın; aksi takdirde 'c' ile aynı davranışa sahiptir.

Ayrıca, PHP 7.1.2'de diğer modlarla birleştirilebilen 'e' seçeneği eklendi. Açılan dosya tanımlayıcısında yürütme yakın bayrağını ayarlar. Yalnızca POSIX.1-2008 uyumlu sistemlerde derlenen PHP'de kullanılabilir.

Bu nedenle, tanımladığınız görev için en iyi dosya açma modu 'a' olacaktır. Dosyayı yalnızca yazmak için açar. Dosya işaretçisini dosyanın sonuna yerleştirir. Dosya yoksa, dosyayı oluşturmaya çalışır. Bu modda, fseek () herhangi bir etkiye sahip değildir, yazma işlemleri her zaman eklenir.

Yukarıda belirtildiği gibi ihtiyacınız olan şey:

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

0

Bunu yapmanın birçok yolu olmasına rağmen. Ancak bunu kolay bir şekilde yapmak ve metni günlük dosyasına yazmadan önce biçimlendirmek istiyorsanız. Bunun için bir yardımcı işlev oluşturabilirsiniz.

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);
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.