php - 使用 csv 上的文件指针

标签 php mysql csv file-pointer

我想知道如何更改下面的代码以读取x行数仅处理sql插入语句,然后继续按x行读取文件并处理直到文件末尾。我对文件指针的想法很陌生,但我知道使用 fgets 应该可以。

我希望将下面的代码更改为一个函数,我可以在其中传递文件名以及我想要读取和处理的行数。

我目前有: (来自here)

$handle = fopen(dirname(__FILE__)."/files/workorderstest.csv" , "r");

$batch++;

if ($handle) {
    $counter = 0;

    //instead of executing query one by one,
    //let us prepare 1 SQL query that will insert all values from the batch

    $sql ="INSERT INTO workorderstest(id,parentid,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10) VALUES ";

    while (($line = fgets($handle)) !== false) {
       $sql .= "($line),";
       $counter++;
    }

    $sql = substr($sql, 0, strlen($sql) - 1);

    var_dump($sql);

    if ($conn->query($sql) === TRUE) {

    } else {

    }

    fclose($handle);
}

我想将内存占用保持在最低限度。我认为这应该只是跟踪指针 -> 重复直到到达行 -> 处理 sql -> 从指针开始 -> 重复直到 eof 的问题。

  1. fgets() 是最适合用于此目的吗?
  2. 我是否需要合并回调或类似的回调来推迟 sql 处理,直到读取所有行?
  3. 由于我仍在学习 PHP,所以我有点不知道从哪里开始。

**** 更新了下面的已回答脚本(如果它对其他人有帮助的话)...

date_default_timezone_set('Australia/Brisbane');
$date = date('m/d/Y h:i:s a', time());
$timezone = date_default_timezone_get();
$time_start = microtime(true);

$batch_size = 500; // Lines to be read per batch
$batch = 0;
$counter = 0;
$lines = 0;

$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// Remove Existing Data from table
$sql = "TRUNCATE TABLE  `workorderstest`";
$conn->query($sql);

$handle = fopen(dirname(__FILE__)."/files/workorders.csv" , "r");

//instead of executing query one by one,
//let us prepare 1 SQL query that will insert all values from the batch

$sql_prefix ="INSERT INTO workorderstest(id,parentid,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10) VALUES ";
$values = "";

while (($line = fgets($handle)) !== false) {
    $values .= "($line),";
    $counter++;
    $lines++;
    if ($counter == $batch_size) {
        $values = substr($values, 0, strlen($values) - 1);
        $conn->query($sql_prefix . $values) or die($conn->error);
        $counter = 0;
        $values ="";
        $batch++;
    }
}
if ($counter > 0) { // Execute the last batch
    $values = substr($values, 0, strlen($values) - 1);
    $conn->query($sql_prefix . $values) or die($conn->error);
}

// Output results
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "Importing Script running at: $date <br/>";
echo "Timezone: $timezone <br/>";
echo "<br/>";
echo "Script Summary:";
echo "Time running script: " . round($time,3) . " seconds <br/>";
echo "Memory: ".memory_get_usage() . " bytes <br/>";
echo "Records Updated: $lines <br/>";
echo "Batches run: $batch <br/>";

?>

最佳答案

  1. fgets() 是最好的选择吗?这是一个很好的方法。另一种选择是使用 file() 将整个文件读入数组,然后使用 foreach() 循环遍历该数组。

  2. 我需要合并回调吗?不需要。只需在从文件中读取每批行后执行查询即可。

  3. 从哪里开始?当计数器达到批量大小时,执行查询。然后将计数器设置回 0 并将查询字符串设置回初始值。最后,在循环结束时,您需要使用剩余值执行查询(除非文件大小是批处理大小的精确倍数,在这种情况下不会有任何剩余值)。

$batch_size = 100;
$counter = 0;

//instead of executing query one by one,
//let us prepare 1 SQL query that will insert all values from the batch

$sql_prefix ="INSERT INTO workorderstest(id,parentid,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10) VALUES ";
$values = "";

while (($line = fgets($handle)) !== false) {
    $values .= "($line),";
    $counter++;
    if ($counter == $batch_size) {
        $values = substr($values, 0, strlen($values) - 1);
        $conn->query($sql_prefix . $values) or die($conn->error);
        $counter = 0;
        $values ="";
    }
}
if ($counter > 0) { // Execute the last batch
    $values = substr($values, 0, strlen($values) - 1);
    $conn->query($sql_prefix . $values) or die($conn->error);
}

关于php - 使用 csv 上的文件指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41294380/

相关文章:

php - 带有红色错误消息的表单验证不起作用(php、ajax、jquery 和 mysql)

mysql - Rails sql查询中动态传递参数

PostgreSQL COPY csv 包括引号

string - go encoding/csv 中引用字符串的奇怪 CSV 结果

linux - 在 Linux 中,是否有将 CSV 文件转换为 SQLite 文件的命令?

php - 与 Core Data SQLite 文件交互的 Web 服务器代码?

php - Mysql 错误处理

MySQl 查询 : copy a column named 'C' from table2 to column 'C' in table1 without losing any other column data

mysql - 一些代码在 nodejs 中让我困惑

php - 在 Magento 的一页结帐的订单审查部分获取账单信息