Créer ou écrire / ajouter dans un fichier texte

170

J'ai un site Web qui, chaque fois qu'un utilisateur se connecte ou se déconnecte, je l'enregistre dans un fichier texte.

Mon code ne fonctionne pas pour ajouter des données ou créer un fichier texte s'il n'existe pas. Voici l'exemple de code

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

Il semble qu'il ne s'ajoute pas à la ligne suivante après que je l'ai rouvert.

Je pense également qu'il y aurait également une erreur dans une situation où 2 utilisateurs se connectent en même temps, cela affecterait-il l'ouverture du fichier texte et son enregistrement par la suite?

Jerahmeel Acebuche
la source

Réponses:

337

Essayez quelque chose comme ceci:

 $txt = "user id date";
 $myfile = file_put_contents('logs.txt', $txt.PHP_EOL , FILE_APPEND | LOCK_EX);
SpencerX
la source
5
cela crée-t-il un fichier texte s'il n'existe pas?
Jerahmeel Acebuche
5
Yup, il crée le fichier texte logs.txtet y ajoute le contenu
SpencerX
5
J'ai une question. en utilisant le LOCK_EX. Je sais que cela empêchera quiconque d'écrire dans le fichier en même temps. mais qu'arrivera-t-il à l'autre?
Jerahmeel Acebuche
13
php.net/manual/en/function.file-put-contents.php Cette fonction renvoie le nombre d'octets qui ont été écrits dans le fichier, ou FALSE en cas d'échec. Juste si quelqu'un se demande.
Master James
7
@JerahmeelAcebuche Le deuxième processus pour tenter d'acquérir le verrou "se bloquera jusqu'à ce que le verrou demandé soit acquis" ( source ). En d'autres termes, le deuxième processus attendra que le premier ait fermé le fichier et libéré le verrou.
rinogo
102

Utilisez le amode. Cela signifie append.

$myfile = fopen("logs.txt", "a") or die("Unable to open file!");
$txt = "user id date";
fwrite($myfile, "\n". $txt);
fclose($myfile);
Valentin Mercier
la source
j'ai aussi ce problème du \ n. ça ne marche pas. cela fonctionne-t-il pour vous?
Jerahmeel Acebuche
1
cela fonctionne-t-il si la situation se produit comme je l'ai dit?
Jerahmeel Acebuche
1
le adrapeau créera le fichier s'il n'existe pas et veillera quoi qu'il en soit à ce que vous ayez vraiment du appendnouveau texte. Pour le \ncela fonctionne mais seulement si entre guillemets doubles et "non guillemets simples'
Valentin Mercier
je veux dire la situation de ce que si les deux utilisateurs se connectent dans un navigateur différent. puis le php ouvrira le fichier sur les deux navigateurs en même temps et le mettra également à jour en même temps. y aura-t-il un problème? \
Jerahmeel Acebuche
1
Oh, oui il y aura, dans ce cas, utiliser une base de données SQL, il a un moteur intégré pour éviter les conditions de course. Mais c'est une toute nouvelle question.
Valentin Mercier
10

Vous pouvez le faire de la manière OO, juste une alternative et flexible:

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

}

Ensuite, utilisez-le comme ceci .. disons que vous avez user_namestocké dans une session (semi pseudo code):

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

Vérifiez votre journal avec ceci:

$log->getLog();

Le résultat est comme:

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


github.com/thielicious/Logger

Thielicious
la source
1
Merci beaucoup pour ce cours de Logger! Je ne m'attendais pas à trouver cela lorsque j'ai trouvé cette page ... mais c'est en fait le fondement d'une bien meilleure solution que ce que j'avais initialement prévu de mettre en œuvre.
Myke Carter
4

Cela fonctionne pour moi, écrire (créer aussi) et / ou ajouter du contenu dans le même mode.

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

Essayez ce code:

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

Je l'utilise toujours comme ça, et ça marche ...

Rwakos
la source
1
Il n'y a aucune raison de le faire (!file_exists($logPath)) ? 'w':'a'- l' aoption a déjà le bon comportement lorsque le fichier n'existe pas. Vous pouvez donc simplifier cette réponse en supprimant la ligne $mode = ...;et en remplaçant la ligne suivante par $logfile = fopen($logPath, 'a');.
ToolmakerSteve
2

Il n'y a pas de mode d'ouverture de fichier tel que "wr" dans votre code:

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

Les modes d'ouverture des fichiers en PHP http://php.net/manual/en/function.fopen.php sont les mêmes qu'en C: http://www.cplusplus.com/reference/cstdio/fopen/

Il existe les principaux modes ouverts suivants "r" pour la lecture, "w" pour l'écriture et "a" pour l'ajout, et vous ne pouvez pas les combiner. Vous pouvez ajouter d'autres modificateurs comme "+" pour la mise à jour, "b" pour le binaire. Le nouveau standard C ajoute un nouveau sous-spécificateur standard ("x"), pris en charge par PHP, qui peut être ajouté à n'importe quel spécificateur "w" (pour former "wx", "wbx", "w + x" ou "w + bx "/" wb + x "). Ce sous-spécificateur force la fonction à échouer si le fichier existe, au lieu de l'écraser.

En plus de cela, dans PHP 5.2.6, le mode d'ouverture principal «c» a été ajouté. Vous ne pouvez pas combiner «c» avec «a», «r», «w». Le «c» ouvre le fichier pour l'écriture uniquement. Si le fichier n'existe pas, il est créé. S'il existe, il n'est ni tronqué (contrairement à «w»), ni l'appel à cette fonction échoue (comme c'est le cas avec «x»). 'c +' Ouvre le fichier pour lecture et écriture; sinon, il a le même comportement que «c».

De plus, et dans PHP 7.1.2, l'option «e» a été ajoutée et peut être combinée avec d'autres modes. Il définit l'indicateur de fermeture à l'exécution sur le descripteur de fichier ouvert. Uniquement disponible en PHP compilé sur les systèmes conformes POSIX.1-2008.

Ainsi, pour la tâche telle que vous l'avez décrite, le meilleur mode d'ouverture de fichier serait «a». Il ouvre le fichier pour l'écriture uniquement. Il place le pointeur de fichier à la fin du fichier. Si le fichier n'existe pas, il tente de le créer. Dans ce mode, fseek () n'a aucun effet, les écritures sont toujours ajoutées.

Voici ce dont vous avez besoin, comme cela a déjà été souligné ci-dessus:

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

Bien qu'il existe de nombreuses façons de le faire. Mais si vous souhaitez le faire de manière simple et que vous souhaitez formater le texte avant de l'écrire dans le fichier journal. Vous pouvez créer une fonction d'assistance pour cela.

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);
    }
}
Ver PHP ...
la source