PHP:写入文件时缺少记录

时间:2013-01-29 21:31:32

标签: php fwrite http-get missing-data

每次收到消息时,我的电信供应商都会向我发送报告。我编写了一个非常简单的PHP脚本,它通过HTTP GET接收值。使用fwrite我将查询参数写入CSV文件。文件名为report.csv,当前日期为前缀。

以下是代码:

<?php
error_reporting(E_ALL ^ E_NOTICE);
date_default_timezone_set('America/New_York'); 
//setting a the CSV File
$fileDate = date("m-d-Y") ;
$filename = $fileDate."_Report.csv";

$directory = "./csv_archive/";

//Creating handle
$handle = fopen($filename, "a");

//These are the main data field
$item1 = $_GET['item1'];
$item2 = $_GET['item2'];
$item3 = $_GET['item3'];

$mydate = date("Y-m-d H:i:s") ;
$pass = $_GET['pass'];

//testing the pass
if (isset($_GET['pass']) AND $_GET['pass'] == "password")
    {
    echo 'Login successful';
    // just making sure the function could write to it
    if (!$handle = fopen($directory.$filename, 'a')){
         echo "Cannot open file ($filename)";
         exit;
    }

    //writing the data I receive through query string
    if (fwrite($handle, "$item1,$item2,$item3,$mydate \n") === FALSE) {
        echo "Cannot write to file ($filename)";
        exit;
    }

    fclose($handle); 
    }
else{
    echo 'Login Failure please add the right pass to URL';   
    }   
?>

脚本做我想要的,但唯一的问题是不一致,这意味着缺少大部分记录(约占报告的一半)。当我登录我的帐户时,我可以获得完整的报告。

我不清楚我需要做些什么来解决这个问题,请提供建议。

1 个答案:

答案 0 :(得分:1)

我对此脚本有几点建议。

要解决Andrew Rhyne的建议,请将从每个$ GET变量读取的代码更改为:

$item1 = (isset($_GET['item1']) && $_GET['item1']) ? $_GET['item1'] : 'empty';

这将告诉您是否正在填充所有字段。

我怀疑你的问题是别的。听起来您正在为要保存的每条记录单独请求。也许这些请求中的一些发生在一起并且正在弄乱彼此打开和写入文件的能力。要检查是否发生这种情况,您可以尝试使用以下代码检查是否正确打开了文件。 (请注意,您在脚本中首次使用'fopen'没有任何效果,因为您在第二次使用'fopen'时会覆盖$ handle,它也会打开错误的文件...)

if (!$handle = fopen($directory.$filename, 'a')){
     $handle = fopen($directory.date("Y-m-d H:i:s:u").'_Record_Error.txt', 'a');
     exit;
}

这将确保您不会因为并发写入尝试而丢失数据。如果您发现这确实是问题,则可以延迟后续写入尝试,直到文件不忙。

$tries = 0;
while ($tries < 50 && !$handle = fopen($directory.$filename, 'a')){
     sleep(.5);//wait half a second
     $tries++;
}
if($handle){
    flock($handle);//lock the file to prevent other requests from opening the file until you are done.
} else {
    $handle = fopen($directory.date("Y-m-d H:i:s:u").'_Record_Error.txt', 'a');//the 'u' is for milliseconds
    exit;
}

这将花费25秒,尝试每半秒打开一次文件,并且每次仍然无法打开要写入的文件时,仍会将记录输出到唯一文件。然后你可以安全地fwrite()和fclose()$ handle。