PHP脚本处理文件的所有行两次

PHP脚本处理文件的所有行两次,php,mysql,Php,Mysql,我有一个PHP脚本,它生成一个HTML表单,供用户上传文件。我使用move\u upload\u file将该文件保存在服务器上,然后使用fgets()读取该文件,并根据特定检查执行数据库插入。下面是代码的简化版本: $cart_id = 18566; if (empty($_POST)) { echo "<form name=\"upload\" action=\"myscan.php\" id=\"myScan\" method=\"POST\" enctype=\"multip

我有一个PHP脚本,它生成一个HTML表单,供用户上传文件。我使用
move\u upload\u file
将该文件保存在服务器上,然后使用
fgets()
读取该文件,并根据特定检查执行数据库插入。下面是代码的简化版本:

$cart_id = 18566;
if (empty($_POST))
{
  echo "<form name=\"upload\" action=\"myscan.php\" id=\"myScan\" method=\"POST\"  enctype=\"multipart/form-data\">";
  echo "Choose the file to upload:<br>\r\n";
  echo "<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"300000\" form=\"myScan\" />";
  echo "<input type=\"file\" name=\"file\" form=\"myScan\" id=\"fileUp\"  /><br>";
  echo "<input type=\"submit\" value=\"Upload\" name=\"sub\" form=\"myScan\" />";
  echo "<input type=\"hidden\" name=\"ck\" form=\"myScan\" value=\"".$cart_id."\" />";
  echo "</form><br>";
}
else
{
  // link to cart goes here
}

$fname = "1SCAN20131031123456";
if (!empty($_POST))
{
  $allowedExts = array("txt", "csv");
  $extension = end(explode(".", $_FILES["file"]["name"]));
  if ( ($_FILES["file"]["type"] == "text/plain" 
      || $_FILES["file"]["type"] == "application/vnd.ms-excel")
    && array_search(strtolower($extension), array_map('strtolower', $allowedExts)) !== FALSE )
  {
    if ($_FILES["file"]["error"] > 0)
    {
      echo "Error: " . $_FILES["file"]["error"] . "<br>";
    }
    else
    {
      echo "Upload: " . $_FILES["file"]["name"] . "<br>";
      echo "Type: " . $_FILES["file"]["type"] . "<br>";
      echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
      echo "Stored in: " . $_FILES["file"]["tmp_name"]."<br>";
      if (file_exists("upload/" . $_FILES["file"]["name"]))
      {
        echo $_FILES["file"]["name"] . " already exists. ";
      }
      else
      {
        move_uploaded_file($_FILES["file"]["tmp_name"], $fname);
        echo "Moved to: " . $fname . "<br>";
      }
    }
  }
  else
  {
  echo "Invalid file<br>";
  echo "Type: " . $_FILES["file"]["type"] . "<br>";
  echo "Upload: " . $_FILES["file"]["name"] . "<br>";
  echo "Extension: " . $extension . "<br>\n";
}
该文件包含以下信息:

所有这些都在99%以上的时间内有效,但在过去两周内,
upload\u datalog
表中的条目有两次被复制。之后还有另一个函数,它也读取文件并根据不同的检查执行插入,这些检查也会重复

我知道这是一个边缘案例,但我无法在php.net上或通过谷歌找到任何关于为什么会发生这种情况的信息,我也无法在mysqlf中复制它。但我知道它发生在野外


这里有我没有看到的竞争条件吗?

你在while循环中插入,所以你在该循环中运行了两次?
对于调试,在循环中添加一个计数器,并创建一个小的调试函数和调试表。在调试表中插入计数器和数据。将这些值与您的期望值进行比较

在用户上传csv文件后,您是否正在读取该文件并对其进行解析?您的上传程序是只接受csv文件还是同时接受其他文件?如果是csv,你能把一些示例数据发布到Yes吗?用户上传后,我复制文件,然后读取并解析它。我试图编写它,使*.csv或*.txt文件可以工作。下面是输入文件的一个示例。是的,
while(fgets($sfd))
是一个循环,但所有测试都是互斥的<代码>if(){…}else if(){…}else if(){…}这意味着只有一个插入或没有插入,对吗?在循环中,测试是exlusive的,只执行其中的一个。但是你得到2个插入,所以唯一可能的方法是循环运行两次。我不能说发生了什么,我只是说,检查发生了什么,然后构建那个小测试工具。你需要检查到底发生了什么,否则你会不断猜测答案。我想你是对的,我必须写一个检查,当错误发生时,将每个变量转储到一个文件中进行后期检查。这将是我追踪问题原因的唯一方法。
$bn = basename($fname);
$sfd = fopen($fname, "r");
$store_number = "$bn[0]";
if(is_numeric($bn[1]))
  $store_number .= $bn[1];
$a = stripos($bn, "SCAN");
$a += 4;
$dt = substr($bn, $a);
//  echo "Date = $dt \n";
$fy = substr($dt, 0, 4);
$fM = substr($dt, 4, 2);
$fd = substr($dt, 6, 2);
$fh = substr($dt, 8, 2);
$fm = substr($dt, 10, 2);
$fs = substr($dt, 12, 2);
$fdate = "$fy-$fM-$fd $fh:$fm:$fs";
//  echo $fname . ",";
//  echo $store_number . ",";

while ($line = fgets($sfd))
{
  $li = explode(",", $line);
  if (sizeof($li) == 5)
  {
    $scan = $li[0];
    $poQty = $li[1];
    $cntQty = $li[2];
    $limd = $li[3];
    $lihms = $li[4];
    $query = "INSERT INTO upload_datalog (file_name, store, filedate, scan, po_qty, cnt_qty, scan_md, scan_hms, cart_id)\n"
    . "VALUES (\"$bn\", $store_number, \"$fdate\", \"$scan\", $poQty, $cntQty, \"$limd\", \"$lihms\", $cart_id)";
  mysqli_query($link, $query);
  }
  else if ($fM < 8 || ($fM == 8 && $fd < 16 ))
  {
    $scan = $li[0];
    $poQty = $li[2];
    $cntQty = $li[1];
    $limd = $li[3];
    $lihms = $li[4];
    $query = "INSERT INTO upload_datalog (file_name, store, filedate, scan, po_qty, cnt_qty, scan_md, scan_hms, cart_id)\n"
    . "VALUES (\"$bn\", $store_number, \"$fdate\", \"$scan\", $poQty, $cntQty, \"$limd\", \"$lihms\", $cart_id)";
    mysqli_query($link, $query);
  }
  else if (sizeof($li) == 3 && $li[0] != "" && $li[1] != "" &&$li[2] != "" )
  {
    $scan = $li[0];
    $poQty = $li[2];
    $cntQty = $li[1];
    $query = "INSERT INTO upload_datalog (file_name, store, filedate, scan, po_qty, cnt_qty)\n"
    . "VALUES (\"$bn\", $store_number, \"$fdate\", \"$scan\", $poQty, $cntQty)";
    mysqli_query($link, $query);
  }
}
fclose($sfd);