2012-04-12 61 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中按预期工作。我有点希望在我全力以赴之前对这个问题进行了测试,但是这里还是有。

相关问题