ユーザーがファイルをアップロードするための HTML フォームを生成する PHP スクリプトがあります。そのファイルを使用してサーバーに保存し、使用してmove_uploaded_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";
}
この時点で、ファイル$fname
は問題なく、重複する行はありません。次の部分は、同じ PHP ファイルで宣言された関数として呼び出されます。 $link
、、$fname
および$cart_id
グローバルとして宣言されています
$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);
ファイルには次の情報が含まれています。
これはすべて 99% 以上の時間で機能しますが、過去 2 週間で 2 回、upload_datalog
テーブルのエントリが重複しています。この後に、ファイルを読み取り、さまざまなチェックに基づいて挿入を実行する別の関数があり、それらも複製されます。
これが特殊なケースであることはわかっていますが、php.net または Google でこれが発生する理由に関する情報を見つけることができず、mysqlf で再現できませんでした。しかし、私はそれが野生で発生することを知っています。
ここに表示されていない競合状態はありますか?