繁体   English   中英

使用PHP从XML文件向MySQL表插入多行

[英]Insert multiple rows to an MySQL table from XML file using PHP

我正在尝试读取XML文件,然后使用PHP将信息存储在MySQL表中

XML看起来像这样:

<areas>
<average_sold_price_1year>1250000</average_sold_price_1year>
<average_sold_price_3year>1250000</average_sold_price_3year>
<average_sold_price_5year>1250000</average_sold_price_5year>
<average_sold_price_7year>1250000</average_sold_price_7year>
<number_of_sales_1year>1</number_of_sales_1year>
<number_of_sales_3year>1</number_of_sales_3year>
<number_of_sales_5year>1</number_of_sales_5year>
<number_of_sales_7year>1</number_of_sales_7year>
<prices_url>
http://www.zoopla.co.uk/home-values/welwyn-garden-city/brockswood-lane/al8-7bu
</prices_url>
<turnover>50.0</turnover>
</areas>

我的代码是:

// specify url of xml file
$url = 'http://api.zoopla.co.uk/api/v1/average_sold_prices?area=AL8&england regionarea_type=postcodes&output_type=outcode&page_size=20&page_number=1';
// get xml file
$values = simplexml_load_file($url);
//loop
foreach($values->areas as $value) {
    $qvalue = mysqli_real_escape_string($link, $value);
    $values[] = "($price1, $price3, $price5, $price7, $sales1, $sales3, $sales5, $sales7, $postcode, $turnover)"; // quoted value, not the raw value
}
// MySQL query
$query_values = implode(',', $values);
$insetquery = "INSERT INTO zoopla (price1, price3, price5, price 7, sales1, sales3, sales5, sales7, postcode, turnover) VALUES $query_values";
$result = @mysqli_query($link,$insetquery);

当我运行代码时,出现以下错误:

致命错误:main()[function.main]:无法在第18行的/home/sustaina/public_html/zoopla.php中创建未命名的属性

如果您考虑插入多行(甚至单行),请考虑使用预处理语句。 让我们一步一步看。

首先,让我们检查连接是否正常:

if ($link->connect_errno) {
    throw new Exception(sprintf("Mysqli: (%d): %s", $link->connect_errno, $link->connect_error));
}

此步骤可能是多余的,因为您已经这样做了。 如果没有,这显示了如何检查$link以获得成功的Mysqli连接。

下一个有用的想法是创建映射。 除示例中的$postcode ,此方法$postcode自动运行。 因此,您可能需要稍微扩展以下代码。 基本上,映射是一个XML元素到Column-Name数组:

$xmlToTableMapping = [
    'average_sold_price_1year' => 'price1',
];

这里, <average_sold_price_1year>元素映射到price1列。 然后使用$poscode所有字段和伪字段扩展该数组。

下一件大事是准备查询。 那就是创建字段,它们的占位符和绑定参数的列表。 这是在刚刚定义的映射的帮助下完成的:

$insertMask  = 'INSERT INTO tablename (%s) VALUES (%s)';
$insertTypes = 's'; // for each column one type needs to be set (s = string)

// bind insert values based on mapping by creating references
$insertValues = [];

foreach ($xmlToTableMapping as $column) {
    $insertValues[$column] = '';
    $insertValues[$column] = & $insertValues[$column]; // make this parameter a reference, mysqli needs references
}

// just a little check in between if there is something to insert at all:
if (!$insertValues) {
    throw new Exception('Nothing to insert.');
}

// create and prepare the query
$query = sprintf(
    $insertMask,
    implode(', ', array_keys($insertValues)),
    implode(', ', array_fill(0, count($insertValues), '?'))
);
$stmt  = $link->prepare($query);
if (!$stmt) {
    throw new Exception(sprintf("Mysqli: (%d): %s", $link->errno, $link->error));
}

// bind parameters
$result = call_user_func_array([$stmt, 'bind_param'], [$insertTypes] + $insertValues);
if (!$result) {
    throw new Exception(sprintf("Mysqli: (%d): %s", $stmt->errno, $stmt->error));
}

这确实构建了SQL字符串并准备了查询-包括所有参数的绑定。 完成此操作后,要插入数据库中所需要做的就是设置$insertValues数组内的变量并执行查询。 同样,借助映射,可以轻松地从XML提取数据:

// execute the statement per each XML element
foreach ($xml->areas as $area) {
    foreach ($xmlToTableMapping as $xml => $column) {
        $value = $area->$xml;
        if ($value->getName() !== $xml) {
            throw new Exception('Element %s not found in %s.', $xml, $area->asXML());
        }
        $insertValues[$column] = trim($value);
    }

    if (!$stmt->execute()) {
        throw new Exception(sprintf("Mysqli: (%d): %s", $stmt->errno, $stmt->error));
    }
}

这几乎是如何完成此操作的高级演示。 Mysqli可能有一个缺点,就是这种动态列表的绑定参数不是那么简单。 但是我可以想象,将其包装在一个或两个函数中或从Mysqli扩展可以为它提供更好的接口。

在最后的foreach循环以及它的动态性质中,可以看出这里概述的这种方法的真正好处。 通常,仅映射应该需要一些修改,而无需其余代码(很多)。

我终于让它像这样工作:

// specify url of xml file
$url = 'http://api.zoopla.co.uk/api/v1/average_sold_prices?area=AL8&area_type=postcodes&output_type=outcode&page_size=20&page_number=1';
// get xml file
echo "Loading XML file...\n";
$xml = simplexml_load_file($url);

// loop
foreach ($xml->areas as $row) {
    $price1 = mysqli_real_escape_string($link,$row->average_sold_price_1year);
    $price3 = mysqli_real_escape_string($link,$row->average_sold_price_1year);
    $price5 = mysqli_real_escape_string($link,$row->average_sold_price_1year);
    $price7 = mysqli_real_escape_string($link,$row->average_sold_price_1year);
    $sales1 = mysqli_real_escape_string($link,$row->number_of_sales_1year);
    $sales3 = mysqli_real_escape_string($link,$row->number_of_sales_1year);
    $sales5 = mysqli_real_escape_string($link,$row->number_of_sales_1year);
    $sales7 = mysqli_real_escape_string($link,$row->number_of_sales_1year);
    $priceurl = mysqli_real_escape_string($link,$row->prices_url);
    $postcode = substr($priceurl,-7);
    $turnover = mysqli_real_escape_string($link,$row->turnover);

$insetquery = "INSERT INTO zoopla (price1, price3, price5, price7, sales1, sales3, sales5, sales7, postcode, turnover)VALUES ('$price1', '$price3', '$price5', '$price7', '$sales1', '$sales3', '$sales5', '$sales7', '$postcode', '$turnover')";
$result = @mysqli_query($link,$insetquery);
}
?>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM