2012-04-12 59 views
0

該腳本應該使用文件鎖等編寫日誌文件,以確保同時運行的腳本不會有任何讀/寫複雜性。我在php.net上找到了它。當我試圖同時運行兩次時,我發現它完全忽略了鎖定文件。但是,當我連續運行它們時,鎖定文件工作得很好。腳本的第二個實例運行與第一個腳本完全相同的代碼

這不作任何任何意義。該腳本只是檢查一個文件是否存在,並基於此進行操作。不管另一個腳本是否正在運行,都不應該影響它。我再次檢查以確保在兩種情況下都創建了鎖文件;它是。

於是我開始做一些測試。

Started at: 2012-04-12 11:21:00 
Checking if weblog/20120412test.txt.1.wlock exists 
Got lock: weblog/20120412test.txt.1.wlock 
log file not exists, make new 
log file was either appended to or create anew 
Wrote: 2012-04-12 11:21:00 xx.xx.xx.xxx "testmsg" 
1 

二審開始在11:21:03輸出:

一審在11:21:00輸出開始

Started at: 2012-04-12 11:21:00 
Checking if weblog/20120412test.txt.1.wlock exists 
Got lock: weblog/20120412test.txt.1.wlock 
log file not exists, make new 
log file was either appended to or create anew 
Wrote: 2012-04-12 11:21:00 xx.xx.xx.xxx "testmsg" 
1 

因此,有兩件事情錯在這裏。時間戳,以及腳本sais鎖文件的事實並不存在,即使它確實如此。

這就好像腳本的第二個實例只是輸出第一個腳本所做的一樣。

<?php 
function Weblog_debug($input) 
{ 
    echo $input."<br/>"; 
} 
function Weblog($directory, $logfile, $message) 
{ 
    // Created 15 september 2010: Mirco Babin 
    $curtime = time(); 

    $startedat = date('Y-m-d',$curtime) . "\t" . date('H:i:s', $curtime) . "\t"; 
    Weblog_debug("Started at: $startedat"); 

    $logfile = date('Ymd',$curtime) . $logfile; 

    //Set directory correctly 
    if (!isset($directory) || $directory === false) 
    $directory = './'; 
    if (substr($directory,-1) !== '/') 
    $directory = $directory . '/'; 

    $count = 1; 
    while(1) 
    { 
     //*dir*/*file*.*count* 
     $logfilename = $directory . $logfile . '.' . $count; 

     //*dir*/*file*.*count*.lock 
     $lockfile = $logfilename . '.wlock'; 
     $lockhandle = false; 
     Weblog_debug("Checking if $lockfile exists"); 
     if (!file_exists($lockfile)) 
     { 
      $lockhandle = @fopen($lockfile, 'xb'); //lock handle true if lock file opened 
      Weblog_debug("Got lock: $lockfile"); 
     } 
     if ($lockhandle !== false) break; //break loop if we got lock 

     $count++; 
     if ($count > 100) return false; 
    } 

    //log file exists, append 
    if (file_exists($logfilename)) 
    { 
     Weblog_debug("log file exists, append"); 
     $created = false; 
     $loghandle = @fopen($logfilename, 'ab'); 
    } 
    //log file not exists, make new 
    else 
    { 
     Weblog_debug("log file not exists, make new"); 
     $loghandle = @fopen($logfilename, 'xb'); 
     if ($loghandle !== false) //Did we make it? 
     { 
      $created = true; 

      $str = '#version: 1.0' . "\r\n" . 
      '#Fields: date time c-ip x-msg' . "\r\n"; 
      fwrite($loghandle,$str); 
     } 
    } 

    //was log file either appended to or create anew? 
    if ($loghandle !== false) 
    { 
     Weblog_debug("log file was either appended to or create anew"); 
     $str = date('Y-m-d',$curtime) . "\t" . 
     date('H:i:s', $curtime) . "\t" . 
     (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '-') . "\t" . 
     '"' . str_replace('"', '""', $message) . '"' . "\r\n"; 
     fwrite($loghandle,$str); 

     Weblog_debug("Wrote: $str"); 

     fclose($loghandle); 
     //Only chmod if new file 
     if ($created) chmod($logfilename,0644); // Read and write for owner, read for everybody else 

     $result = true; 
    } 
    else 
    { 
     Weblog_debug("log file was not appended to or create anew"); 
     $result = false; 
    } 

    /** 
    Sleep & disable unlinking of lock file, both for testing purposes. 
    */ 
    //Sleep for 10sec to allow other instance(s) of script to run while this one still in progress. 
    sleep(10); 
    //fclose($lockhandle); 
    //@unlink($lockfile); 

    return $result; 
} 

echo Weblog("weblog", "test.txt", "testmsg"); 
?> 

UPDATE:

這裏有一個簡單的腳本,只是顯示了時間戳。我在不同的主機上嘗試過,所以我不認爲這是我的服務器的問題;

<?php 
function Weblog_debug($input) 
{ 
    echo $input."<br/>"; 
} 
$curtime = time(); 
$startedat = date('Y-m-d',$curtime) . "\t" . date('H:i:s', $curtime) . "\t"; 
Weblog_debug("Started at: $startedat"); 

$timediff = time() - $curtime; 
while($timediff < 5) 
{ 
    $timediff = time() - $curtime; 
} 

Weblog_debug("OK"); 
?> 

同樣,如果我開始了劇本的第二個實例,而首先是在while循環,第二個腳本會說明它開始在同一時間爲第一。

回答

0

我不能相信這個我自己,但事實證明這只是Opera中的一個「功能」。該腳本在Firefox中按預期工作。我有點希望在我全力以赴之前對這個問題進行了測試,但是這裏還是有。

相關問題