【问题标题】:inserting records from database in multiple xml files in php在php中的多个xml文件中插入数据库中的记录
【发布时间】:2014-07-16 14:19:30
【问题描述】:

我正在尝试将数据库记录放在多个 xml 文件中,但我无法做到这一点。基本上我在 db 表中有 200 行,我必须将它们放在 4 个不同的 xml 文件中,每个文件有 50 个。就像以前一样跨越 50 行,应该会自动生成一个新的 xml 文件。 但我无法开发 for 循环逻辑。

<?php

//Create Database connection
$mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');

if (mysqli_connect_errno()) {
    echo "Connection Failed: " . mysqli_connect_errno();
}
$query = 'select * from tablename';

$result = mysqli_query($mysqli, $query);

//Create SimpleXMLElement object
$xml = new SimpleXMLElement('<xml/>');

//Add each column value a node of the XML object
while ($row = mysqli_fetch_array($result)) {
    $counter = 0;
    if (count($row) % 50) {
        $mydata = $xml->addChild('mydata');


        $mydata->Id = $row['PID'];
        $fp         = fopen("sitemap$counter.xml", "wb");

        //Write the XML nodes
        fwrite($fp, $xml->asXML());
        $xml = new XML();
    } else {
        $counter++;
    }
}

mysqli_close($mysqli);
//Create the XML file
//Close the database connection
fclose($fp);

现在 db 表中有 200 行,我想制作 4 个不同的 xml 文件,每个 50 行。

我做不到。请帮忙

【问题讨论】:

  • 将您的fwrite 内容放入循环中并跟踪您已加载的记录数。当你达到 50 时,你将 xml 转储到一个文件中,然后启动一个新文件并将计数器重置为 0。
  • inside loop 意味着在 while 循环中?我只会更新我得到的代码。请检查它是否正确?
  • 您是否还有其他未在代码中显示的循环?
  • 不,我没有任何其他循环。我刚刚用你所说的更新了我的代码。请检查它是否正确。如果不正确,请帮忙
  • 您需要在每次将 $xml 对象转储到文件时重置它,否则您只会转储 50 条记录,然后转储 100 条记录,等等...另外,您使用的是 SAME文件名每次,所以你只是要删除你以前转储的记录。换句话说,除了现在多次写入文件而不是一次之外,您并没有取得太多成就。

标签: php mysql sql xml mysqli


【解决方案1】:

您所拥有的是一个 Traversable,您希望将其切割成每块 50 次迭代的块。

为了简洁起见,我将其更改为四个结果行,并且我希望每个有两次迭代,也就是说,创建两个包含两个条目的文件。

您可以通过编写一个在 Generator 的帮助下将 Iterator 分块的小函数来轻松完成此操作:

/**
 * @param Iterator $iterator
 * @param int      $size
 *
 * @return Generator
 */
function ChunkGenerator(Iterator $iterator, $size) {
    $size = max(0, (int) $size);
    while ($size-- && $iterator->valid()) {
        yield $iterator->key() => $iterator->current();
        $size && $iterator->next();
    }
}

这个小函数以 Generator 的形式再次返回 Traversale,它将从 $iterator 迭代 $size 迭代。

由于您的 $resultTraversable 而不是 Iterator,因此您需要先将其包装在 IteratorIterator 中。然后您可以对其进行迭代,然后在该块的迭代中进行迭代。看例子:

$iterator = new IteratorIterator($result);

foreach ($iterator as $void) {
    echo "new chunk:\n";
    foreach (ChunkGenerator($iterator, 2) as $row) {
        echo $row['PID'], "\n";
    }
}

我的示例输出从 PID 1000 开始,然后给出:

new chunk:
1000
1001
new chunk:
1002
1003

正如您在堆叠的foreach 中看到的那样,内部循环提供每个文件的行。外循环代表文件。现在很容易将 XML 输出逻辑放入这样的循环中:

foreach ($iterator as $void) {

    //Create SimpleXMLElement object
    $xml = new SimpleXMLElement('<xml/>');

    foreach (ChunkGenerator($iterator, 2) as $row) {
        $xml->addChild('row')->Id = $row['PID'];
    }

    // output the file
    $xml->saveXML('php://output'); // place your filename here
}

输出(我使用示例标准输出作为“文件名”,你可以把你的文件名放在那里)然后是:

<?xml version="1.0"?>
<xml><row><Id>1000</Id></row><row><Id>1001</Id></row></xml>
<?xml version="1.0"?>
<xml><row><Id>1002</Id></row><row><Id>1003</Id></row></xml>

虽然这个例子有点复杂(你有两个循环在彼此内部),但它仍然很好地代表了你所拥有的建模:文件,然后是每个文件的行。

您也可以玩在线演示:https://eval.in/173066

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多