【问题标题】:Why XMLReader repeat mysql insert function inside while and can't stop?为什么XMLReader 在while 里面重复mysql insert 函数并且不能停止?
【发布时间】:2017-09-10 13:03:00
【问题描述】:

我正在使用 XMLReader 将大型 xml 文件按元素导入 MySQL 数据库。 Xml 包含 1 547 772 个名为“RECORD”的标签(元素)。

XML 示例

<?xml version="1.0" encoding="utf-8"?>
<RECORD><NAME>ДОШКІЛЬНИЙ НАВЧАЛЬНИЙ ЗАКЛАД №1 ЗАГАЛЬНОГО РОЗВИТКУ УЖГОРОДСЬКОЇ МІСЬКОЇ РАДИ ЗАКАРПАТСЬКОЇ ОБЛАСТІ</NAME><SHORT_NAME>ДНЗ №1</SHORT_NAME><EDRPOU>34888585</EDRPOU><ADDRESS>88000, Закарпатська обл., місто Ужгород, ВУЛИЦЯ М.ВОВЧКА, будинок 47,  "А"</ADDRESS><BOSS>НАКОНЕЧНА ОЛЕНА АНАТОЛІЇВНА</BOSS><KVED>85.10 Дошкільна освіта</KVED><STAN>зареєстровано</STAN><FOUNDERS><FOUNDER>УПРАВЛІННЯ ОСВІТИ УЖГОРОДСЬКОЇ МІСЬКОЇ РАДИ, розмір внеску до статутного фонду - 0.00 грн.</FOUNDER>...</FOUNDERS></RECORD>...

对于 MySQL 连接使用

function connectBase(){

    include __DIR__ . '/../../settings/sql.set.php';
    $mysql = mysqli_connect($_sqlhost, $_sqluser, $_sqlpass, $_sqldb);
    mysqli_query($mysql, "Set charset utf8");
    mysqli_query($mysql, "Set character_set_client = utf8");
    mysqli_query($mysql, "Set character_set_connection = utf8");
    mysqli_query($mysql, "Set character_set_results = utf8");
    mysqli_query($mysql, "Set collation_connection = utf8_general_ci");
    return $mysql;
}

解析的主要函数

function XMLReaderToDB($setting = false)
{

    $mysql = connectBase();
    $dir = __DIR__ . '/../../tmp/';
    $xmlURL = $dir . $setting['file'];
    $xml = new XMLReader();
    $xml->open($xmlURL);

    $start_time = time();
    $start = $setting['start'];
    $limit = $setting['limit'];
    $stop = $start + $limit;

    $i = 0;
    $count = 0;
    $result = 1;

    while($xml->read())
    {
            if ($xml->nodeType == XMLReader::ELEMENT && $xml->name == $setting['tag']) {

                $item[] = "('items', '" . mysqli_real_escape_string($mysql, $xml->readOuterXML()) . "')";
            }

            if ($xml->nodeType == XMLReader::END_ELEMENT && $xml->name == $setting['tag']) {
                $i++;
                $count++;
                if ($count >= 500) {
                    insertXMLtoDB($mysql, $item);
                    $item = array();
                    $count = 0;
                }
            }
        if($i == $stop){
            break;
        }
    }
    $xml->close();
    insertXMLtoDB($mysql, $item);

    $mysql->close();

    $end_time = time();
    $time_elapsed_secs = $end_time - $start_time;
    echo '<br/>Items: ' . $i . '<br/>';
    echo 'Start: ' . date('H:i:s', $start_time) . '<br/>';
    echo 'End: ' . date('H:i:s', $end_time) . '<br/>';
    echo $time_elapsed_secs . ' sec. (' . ($time_elapsed_secs /60) . ' min.)';
    die;
}

对于 MySQL 插入

function insertXMLtoDB($mysql, $data = false){
    mysqli_query($mysql,"INSERT INTO _parse_tmp (parse_key, parse_value) VALUES " . implode(", ", $data));
    $data = array();
    // echo 'Success';
}

但是,MySQL 请求在 1 547 772 次插入后不会停止,“while”会继续运行。我注意到如果取消注释 echo 'Success';在 insertXMLtoDB 函数中,“while”在 1 547 772 次插入处停止并正确完成。 我的函数有什么问题?

【问题讨论】:

  • 你的意思是对insertXMLtoDB($mysql, $item); 的第二次调用,它是在while 循环完成之后被调用以写入最后一块数据。这几乎总是有一些东西要写,因为你只写每 500 条记录。
  • 没错。但是 insertXMLtoDB($mysql, $item);在“一段时间”之后工作正常。删除 whis nubction 并不能解决问题。

标签: php mysql xml while-loop xmlreader


【解决方案1】:

我从未亲自使用过 XMLReader,但我假设您可以尝试在语句中添加另一个条件,例如 while($xml-&gt;read() &amp;&amp; $i != $stop),而不是将其直接放在循环中。啊,在您使用函数insertXMLtoDB 之后,您也注意到您重新声明了$data,尽管您会注意到每次调用该函数时都将其设置为NULL,因此将其设置为数组是没有意义的。

【讨论】:

  • 我尝试用 'while($xml->read() && $i != $stop)' 替换并设置 '$stop = 1600000',但得到相同的结果,“while” don不要停下来。
  • 你确定它已经完成了所有数据的插入?
  • 当 $i 的值达到 1600000 时,函数应该停止。我正在监视数据库。在基础上以 500 个项目为一组添加,但在添加 1600000 'while' 后不会停止并继续添加新元素(重复)。
  • while($xml->read() && $i != $stop) 如果 $i = 5000(例如)工作正常,但不适用于 1000000、1500000 等大值。并且当 xml 中的 'RECORD' 项目(标签)结束时,'while' 不会停止/
  • 这很奇怪,我猜你改变了最大执行时间限制?
【解决方案2】:

我不明白为什么脚本不能正常工作。这就是我决定改变它的原因。

function XMLReaderToDB($setting = false)
{
    $mysql = connectBase();

    $dir = __DIR__ . '/../../tmp/';
    $xmlURL = $dir . $setting['file'];
    $xml = new XMLReader();
    $xml->open($xmlURL);

    $start_time = time();
    $start = $setting['start'];
    $limit = $setting['limit'];
    $stop = $start + $limit;

    $i = 0;
    $count = 0;
    while (($valid = $xml->read()) && $xml->name !== $setting['tag']) ;
    while ($valid) {
        $i++;
        $count++;
        $item[] = "('" . $setting['type'] . "', '" . mysqli_real_escape_string($mysql, $xml->readOuterXML()) . "')";
        if ($count == 500) {
            insertXMLtoDB($mysql, $item);
            $item = array();
            $count = 0;
        }
        $valid = $xml->next($setting['tag']);
    }
    $xml->close();
    insertXMLtoDB($mysql, $item);
    $mysql->close();

    $end_time = time();
    $time_elapsed_secs = $end_time - $start_time;
    echo '<br/>Items: ' . $i . '<br/>';
    echo 'Start: ' . date('H:i:s', $start_time) . '<br/>';
    echo 'End: ' . date('H:i:s', $end_time) . '<br/>';
    echo $time_elapsed_secs . ' sec. (' . ($time_elapsed_secs /60) . ' min.)';
    return;
}

【讨论】:

    猜你喜欢
    • 2020-03-10
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多