Crea o scrivi / aggiungi in un file di testo


170

Ho un sito Web che ogni volta che un utente accede o si disconnette, lo salvo in un file di testo.

Il mio codice non funziona per aggiungere dati o creare un file di testo se non esiste. Ecco il codice di esempio

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

Sembra che non si aggiunge alla riga successiva dopo averlo aperto di nuovo.

Inoltre penso che avrebbe anche un errore in una situazione in cui 2 utenti accedono contemporaneamente, influenzerebbe l'apertura del file di testo e il salvataggio in seguito?

Risposte:


337

Prova qualcosa del genere:

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

5
questo crea un file di testo se non esiste?
Jerahmeel Acebuche,

5
Sì, crea il file di testo logs.txte aggiungi il contenuto in esso
SpencerX,

5
Ho una domanda. utilizzando LOCK_EX. so che questo impedirà a chiunque altro di scrivere sul file contemporaneamente. ma cosa succederà all'altro?
Jerahmeel Acebuche,

13
php.net/manual/en/function.file-put-contents.php Questa funzione restituisce il numero di byte scritti nel file o FALSE in caso di errore. Solo se qualcuno si sta chiedendo.
Master James,

7
@JerahmeelAcebuche Il secondo processo per tentare di acquisire il blocco "bloccherà fino all'acquisizione del blocco richiesto" ( sorgente ). In altre parole, il secondo processo attenderà fino a quando il primo avrà chiuso il file e rilasciato il blocco.
Rinogo,

102

Usa la amodalità. Sta per append.

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

ho anche questo problema di \ n. non funziona. funziona per te?
Jerahmeel Acebuche,

1
funziona se la situazione si presenta come ho detto?
Jerahmeel Acebuche,

1
il aflag creerà il file se non esiste e non importa cosa si assicuri che tu sia davvero appendnuovo testo. Perché \nfunziona, ma solo se all'interno di virgolette "non virgolette singole'
Valentin Mercier,

intendo la situazione di cosa succede se i due utenti accedono in un browser diverso. quindi php aprirà il file sui due browser contemporaneamente e lo aggiornerà allo stesso tempo. ci sarà un problema? \
Jerahmeel Acebuche,

1
Oh, sì, in questo caso ci sarà un database SQL, che ha un motore integrato per evitare le condizioni di gara. Ma questa è una domanda completamente nuova.
Valentin Mercier,

10

Puoi farlo nel modo OO, solo un'alternativa e flessibile:

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

}

Quindi usalo in questo modo ... diciamo che hai user_namearchiviato in una sessione (semi pseudo codice):

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

Controlla il tuo registro con questo:

$log->getLog();

Il risultato è come:

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


github.com/thielicious/Logger


1
Mille grazie per questa lezione Logger! Non mi aspettavo di scoprirlo quando ho trovato questa pagina ... ma in realtà è la base di una soluzione molto migliore di quella che inizialmente avevo intenzione di implementare.
Myke Carter,

4

Questo funziona per me, scrivere (anche creare) e / o aggiungere contenuti nella stessa modalità.

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

3

Prova questo codice:

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

Lo uso sempre così e funziona ...


1
Non c'è motivo di farlo (!file_exists($logPath)) ? 'w':'a': l' aopzione ha già il comportamento corretto quando il file non esiste. Quindi puoi semplificare questa risposta rimuovendo la riga $mode = ...;e cambiando la riga successiva in $logfile = fopen($logPath, 'a');.
ToolmakerSteve

2

Non esiste una modalità di apertura file come "wr" nel codice:

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

Le modalità di apertura dei file in PHP http://php.net/manual/en/function.fopen.php sono le stesse di C: http://www.cplusplus.com/reference/cstdio/fopen/

Esistono le seguenti modalità aperte "r" per lettura, "w" per scrittura e "a" per append e non è possibile combinarle. Puoi aggiungere altri modificatori come "+" per l'aggiornamento, "b" per binario. Il nuovo standard C aggiunge un nuovo sottospecificatore standard ("x"), supportato da PHP, che può essere aggiunto a qualsiasi identificatore "w" (per formare "wx", "wbx", "w + x" o "w + bx "/" wb + x "). Questo sottospecificatore impone che la funzione fallisca se il file esiste, invece di sovrascriverlo.

Oltre a ciò, in PHP 5.2.6 è stata aggiunta la modalità di apertura principale 'c'. Non puoi combinare 'c' con 'a', 'r', 'w'. La 'c' apre il file solo per la scrittura. Se il file non esiste, viene creato. Se esiste, non viene né troncato (al contrario di 'w'), né la chiamata a questa funzione fallisce (come nel caso di 'x'). 'c +' Apre il file per la lettura e la scrittura; altrimenti ha lo stesso comportamento di "c".

Inoltre, e in PHP 7.1.2 è stata aggiunta l'opzione 'e' che può essere combinata con altre modalità. Imposta il flag close-on-exec sul descrittore di file aperto. Disponibile solo in PHP compilato su sistemi conformi POSIX.1-2008.

Quindi, per l'attività come l'hai descritta, la migliore modalità di apertura del file sarebbe 'a'. Apre il file solo per la scrittura. Posiziona il puntatore del file alla fine del file. Se il file non esiste, tenta di crearlo. In questa modalità, fseek () non ha alcun effetto, le scritture vengono sempre aggiunte.

Ecco cosa ti serve, come è già stato sottolineato sopra:

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

0

Sebbene ci siano molti modi per farlo. Ma se vuoi farlo in modo semplice e vuoi formattare il testo prima di scriverlo nel file di registro. È possibile creare una funzione di supporto per questo.

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);
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.