텍스트 파일에서 작성 또는 쓰기 / 추가


170

사용자가 로그인하거나 로그 아웃 할 때마다 텍스트 파일로 저장하는 웹 사이트가 있습니다.

데이터를 추가하거나 텍스트 파일이없는 경우 내 코드가 작동하지 않습니다. 샘플 코드는 다음과 같습니다.

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

다시 열면 다음 줄에 추가되지 않는 것 같습니다.

또한 2 명의 사용자가 동시에 로그인 할 때 오류가 발생한다고 생각합니다. 텍스트 파일을 열고 나중에 저장하는 데 영향을 미칩니 까?

답변:


337

다음과 같이 해보십시오 :

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

5
텍스트 파일이 없으면 작성합니까?
Jerahmeel Acebuche

5
텍스트 파일을 만들고 그 logs.txt안에 내용을 추가하십시오
SpencerX

5
질문이 있습니다. LOCK_EX를 사용합니다. 다른 사람이 파일에 동시에 쓰는 것을 막을 수 있음을 알고 있습니다. 그러나 다른 하나는 어떻게됩니까?
Jerahmeel Acebuche

13
php.net/manual/en/function.file-put-contents.php 이 함수는 파일에 기록 된 바이트 수 또는 실패시 FALSE를 반환합니다. 누군가 궁금한 경우.
마스터 제임스

7
@JerahmeelAcebuche 잠금을 획득하려는 두 번째 프로세스는 "요청 된 잠금을 획득 할 때까지 차단됩니다"( source ). 즉, 두 번째 프로세스는 첫 번째 프로세스가 파일을 닫고 잠금을 해제 할 때까지 기다립니다.
rinogo

102

a모드를 사용하십시오 . 의 약자입니다 append.

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

또한이 문제는 \ n입니다. 작동하지 않습니다. 그것은 당신에게 작동합니까?
Jerahmeel Acebuche

1
내가 말한 것처럼 상황이 발생하면이 작동합니까?
Jerahmeel Acebuche

1
a가 존재하지 않습니다 않고 당신이 정말로 있는지 확인 어떤 문제가됩니다 경우 플래그는 파일을 만듭니다 append새 텍스트. 의 경우 \n는 작동하지만 경우에만 내부 따옴표 "없는 따옴표'
발렌틴 메르

두 사용자가 다른 브라우저에 로그인하면 어떻게 될까요? 그런 다음 PHP는 두 브라우저에서 동시에 파일을 열고 동시에 업데이트합니다. 문제가 있습니까? \
Jerahmeel Acebuche

1
아, 그렇습니다.이 경우 SQL 데이터베이스를 사용하십시오. 경쟁 조건을 피하기 위해 내장 엔진이 있습니다. 그러나 그것은 완전히 새로운 질문입니다.
Valentin Mercier

10

대안적이고 유연한 OO 방식으로 할 수 있습니다.

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

}

그런 다음 다음과 같이 사용하십시오. user_name세션에 저장 했다고 가정 해 봅시다 (세미 의사 코드).

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

이것으로 로그를 확인하십시오 :

$log->getLog();

결과는 다음과 같습니다

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


github.com/thielicious/Logger


1
이 로거 수업에 감사드립니다! 나는이 페이지를 발견했을 때 그것을 알기를 기대하지 않았지만 실제로는 원래 구현하려고했던 것보다 훨씬 더 나은 솔루션의 기초입니다.
Myke Carter

4

이것은 저에게 효과적이며, 동일한 모드에서 컨텐츠를 작성하거나 작성하고 있습니다.

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

3

이 코드를 사용해보십시오 :

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

나는 항상 이렇게 사용하고 작동합니다 ...


1
할 이유가 없습니다 (!file_exists($logPath)) ? 'w':'a'- a파일이 존재하지 않을 때 옵션이 이미 올바르게 작동합니다. 따라서 행을 제거 $mode = ...;하고 다음 행을로 변경 하여이 답변을 단순화 할 수 있습니다 $logfile = fopen($logPath, 'a');.
ToolmakerSteve

2

코드에는 "wr"과 같은 파일 열기 모드가 없습니다.

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

PHP http://php.net/manual/en/function.fopen.php 의 파일 열기 모드 는 C와 동일합니다 : http://www.cplusplus.com/reference/cstdio/fopen/

읽기를위한 "r", 쓰기를위한 "w"및 추가를위한 "a"의 다음과 같은 주요 열기 모드가 있으며이를 결합 할 수 없습니다. 업데이트에는 "+", 바이너리에는 "b"와 같은 다른 수정자를 추가 할 수 있습니다. 새로운 C 표준은 PHP에서 지원하는 새로운 표준 하위 지정자 ( "x")를 추가하여 "w"지정자에 추가 할 수 있습니다 ( "wx", "wbx", "w + x"또는 "w + bx를 형성하기 위해) "/"wb + x "). 이 하위 지정자는 파일을 덮어 쓰는 대신 파일이 존재하면 함수가 실패하도록합니다.

PHP 5.2.6에서는 'c'메인 오픈 모드가 추가되었습니다. 'c'를 'a', 'r', 'w'와 결합 할 수 없습니다. 'c'는 쓰기 전용 파일을 엽니 다. 파일이 없으면 작성됩니다. 존재하는 경우 잘리지 않거나 ( 'w'가 아닌)이 함수에 대한 호출이 실패하지 않습니다 ( 'x'의 경우와 동일). 'c +'읽고 쓸 파일을 엽니 다. 그렇지 않으면 'c'와 동일한 동작을 갖습니다.

또한 PHP 7.1.2에서는 다른 모드와 결합 할 수있는 'e'옵션이 추가되었습니다. 열린 파일 디스크립터에서 close-on-exec 플래그를 설정합니다. POSIX.1-2008 호환 시스템에서 컴파일 된 PHP에서만 사용할 수 있습니다.

따라서 설명한 작업의 경우 가장 좋은 파일 열기 모드는 'a'입니다. 쓰기 전용으로 파일을 엽니 다. 파일 끝에 파일 포인터를 놓습니다. 파일이 존재하지 않으면 파일을 작성하려고합니다. 이 모드에서는 fseek ()가 적용되지 않으며 쓰기가 항상 추가됩니다.

이미 위에서 지적했듯이 여기에 필요한 것이 있습니다.

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

0

이를 수행하는 방법은 여러 가지가 있지만 그러나 쉬운 방법으로 수행하고 텍스트를 로그 파일에 쓰기 전에 텍스트를 형식화하려는 경우. 이를 위해 도우미 기능을 만들 수 있습니다.

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);
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.