Crear o escribir / agregar en un archivo de texto

170

Tengo un sitio web que cada vez que un usuario inicia o cierra sesión lo guardo en un archivo de texto.

Mi código no funciona al agregar datos o crear un archivo de texto si no existe. Aquí está el código de muestra

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

Parece que no se agrega a la siguiente línea después de abrirlo nuevamente.

También creo que también tendría un error en una situación en la que 2 usuarios inician sesión al mismo tiempo, ¿afectaría abrir el archivo de texto y guardarlo después?

Jerahmeel Acebuche
fuente

Respuestas:

337

Intenta algo como esto:

 $txt = "user id date";
 $myfile = file_put_contents('logs.txt', $txt.PHP_EOL , FILE_APPEND | LOCK_EX);
SpencerX
fuente
55
¿esto crea un archivo de texto si no existe?
Jerahmeel Acebuche
55
Sí, crea el archivo de texto logs.txty agrega el contenido en él
SpencerX
55
tengo una pregunta. usando el LOCK_EX. Sé que esto evitará que alguien más escriba en el archivo al mismo tiempo. ¿Pero qué pasará con el otro?
Jerahmeel Acebuche
13
php.net/manual/en/function.file-put-contents.php Esta función devuelve el número de bytes que se escribieron en el archivo, o FALSE en caso de error. Solo si alguien se pregunta.
Maestro James
77
@JerahmeelAcebuche El segundo proceso para intentar adquirir el bloqueo "se bloqueará hasta que se obtenga el bloqueo solicitado" ( fuente ). En otras palabras, el segundo proceso esperará hasta que el primero haya cerrado el archivo y haya liberado el bloqueo.
rinogo
102

Usa el amodo. Es sinónimo de append.

$myfile = fopen("logs.txt", "a") or die("Unable to open file!");
$txt = "user id date";
fwrite($myfile, "\n". $txt);
fclose($myfile);
Valentin Mercier
fuente
También tengo este problema de la \ n. No funciona. te funciona?
Jerahmeel Acebuche
1
¿funciona esto si la situación sucede como he dicho?
Jerahmeel Acebuche
1
la abandera creará el archivo si no existe y no importa lo que se asegure de que realmente hay appendtexto nuevo. Para el \nfunciona pero solo si entre comillas dobles "no comillas simples'
Valentin Mercier
Me refiero a la situación de qué si los dos usuarios inician sesión en un navegador diferente. entonces el php abrirá el archivo en los dos navegadores al mismo tiempo y también lo actualizará al mismo tiempo. ¿habrá algún problema? \
Jerahmeel Acebuche
1
Ah, sí, habrá, en este caso, una base de datos SQL, tiene un motor incorporado para evitar condiciones de carrera. Pero esa es una pregunta completamente nueva.
Valentin Mercier
10

Puedes hacerlo de la manera OO, solo una alternativa y 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;
    }

}

Luego úselo de esta manera ... supongamos que lo ha user_namealmacenado en una sesión (semi pseudocódigo):

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

Verifique su registro con esto:

$log->getLog();

El resultado es como:

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


github.com/thielicious/Logger

Thielicious
fuente
1
¡Muchas gracias por esta clase de Logger! No esperaba encontrar eso cuando encontré esta página ... pero en realidad es la base de una solución mucho mejor que la que originalmente estaba planeando implementar.
Myke Carter
4

Esto funciona para mí, escribir (crear también) y / o agregar contenido en el mismo modo.

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

Prueba este código:

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

Siempre lo uso así, y funciona ...

Rwakos
fuente
1
No hay razón para hacerlo (!file_exists($logPath)) ? 'w':'a': la aopción ya tiene el comportamiento correcto cuando el archivo no existe. Por lo tanto, puede simplificar esta respuesta eliminando la línea $mode = ...;y cambiando la siguiente línea a $logfile = fopen($logPath, 'a');.
ToolmakerSteve
2

No hay modo de archivo abierto como "wr" en su código:

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

Los modos de apertura de archivos en PHP http://php.net/manual/en/function.fopen.php son los mismos que en C: http://www.cplusplus.com/reference/cstdio/fopen/

Existen los siguientes modos abiertos principales "r" para leer, "w" para escribir y "a" para agregar, y no puede combinarlos. Puede agregar otros modificadores como "+" para actualizar, "b" para binario. El nuevo estándar C agrega un nuevo subespecificador estándar ("x"), compatible con PHP, que se puede agregar a cualquier especificador "w" (para formar "wx", "wbx", "w + x" o "w + bx "/" wb + x "). Este subespecificador obliga a la función a fallar si el archivo existe, en lugar de sobrescribirlo.

Además de eso, en PHP 5.2.6, se agregó el modo abierto principal 'c'. No puede combinar 'c' con 'a', 'r', 'w'. La 'c' abre el archivo solo para escribir. Si el archivo no existe, se crea. Si existe, no está truncado (en oposición a 'w'), ni falla la llamada a esta función (como es el caso con 'x'). 'c +' Abre el archivo para leer y escribir; de lo contrario, tiene el mismo comportamiento que 'c'.

Además, y en PHP 7.1.2 se agregó la opción 'e' que se puede combinar con otros modos. Establece el indicador close-on-exec en el descriptor de archivo abierto. Solo disponible en PHP compilado en sistemas conformes POSIX.1-2008.

Entonces, para la tarea como la ha descrito, el mejor modo de abrir archivo sería 'a'. Abre el archivo solo para escribir. Coloca el puntero del archivo al final del archivo. Si el archivo no existe, intenta crearlo. En este modo, fseek () no tiene efecto, las escrituras siempre se agregan.

Esto es lo que necesita, como ya se señaló anteriormente:

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

Aunque hay muchas formas de hacer esto. Pero si desea hacerlo de una manera fácil y desea formatear el texto antes de escribirlo en el archivo de registro. Puede crear una función auxiliar para esto.

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);
    }
}
Gusano PHP ...
fuente