簡體   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