【问题标题】:Deal with multiple tables to export mysql db data to xml处理多表导出mysql db数据到xml
【发布时间】:2025-12-01 01:15:02
【问题描述】:

我需要通过解释代码来帮助我理解如何处理多个表:

有几个表叫

公寓、物业、类别、开发商

  1. 公寓列(id、category_id、developer_id、property_id、 标题、价格)
  2. 类别列(id、title)
  3. 开发者栏目(ID、标题)
  4. 属性列(id、title、category_id)

它们之间的关系如下:

  • category_idcategories 表中的id 列同步
  • developer_iddevelopers 表中的id 列同步
  • property_idproperties 表中的 id 列同步

我需要更新下面的 php 代码以使输出像这样

<?xml version="1.0" ?>
<list>  
    <property>
        <title>apartments_title</title >
        <price>apartments_price</price >
        <type>properties_title</type>
        <categoty>categories_title</categoty>
        <developer>developer_title</developer>
   </property>

</list>

我使用此代码从一个表中检索数据

header('Content-type: text/xml');

// INITIALIZE DOM OBJECT
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true;            
$dom->preserveWhiteSpace = false;

// CREATE ROOT AND APPEND TO DOCUMENT
$xmlRoot = $dom->createElement("list");
$xmlRoot = $dom->appendChild($xmlRoot);

// QUERY DATABASE
$db = new PDO('mysql:host=hostname;dbname=dbname','dbusername','password');
$stmt = $db->prepare("select * from apartments");
$stmt->execute();

// FETCH ROWS ITERATIVELY
while($row = $stmt->fetch()){
     // APPEND property AS CHILD OF ROOT
     $propertyNode = $xmlRoot->appendChild($dom->createElement('property'));

     // APPEND CHILDREN TO Property         
     $propertyNode->appendChild($dom->createElement('title', $row['title']));
     $propertyNode->appendChild($dom->createElement('price', $row['price']));
}
$stmt = null; 
$db = null;

// OUTPUT TO SCREEN
echo $dom->saveXML();

【问题讨论】:

  • 与其对公寓中的每一行进行查询,不如对其他表使用 SQL 连接并进行一次查询。

标签: php mysql xml domdocument


【解决方案1】:

如 cmets 中所述,您希望使用连接来获取所需的值。左连接可确保包括 apartments 表中的所有记录,而其他表中的缺失值(如果有)将返回为 NULL。

SELECT a.title AS title, a.price AS price, p.title AS type,
    c.title AS category, d.title AS developer
FROM apartments a
LEFT JOIN properties p ON (a.property_id = p.id)
LEFT JOIN categories c ON (a.category_id = c.id)
LEFT JOIN developers d ON (a.developer_id = d.id);

请注意,我已经为表(以使 SQL 更清晰)和列设置了别名,以便在构建 XML 时使用。您可以只循环结果,而不是为每一列单独调用createElement。这是可能的,因为我已将 fetch 类型指定为关联数组,而不是默认的 fetch 类型,它既是关联的又是数字的。最后一点,如果没有参数,您不需要 prepare()execute() 声明。只需运行 query() 即可获得相同的结果。

<?php
header('Content-type: text/xml');

// INITIALIZE DOM OBJECT
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true;            
$dom->preserveWhiteSpace = false;

// CREATE ROOT AND APPEND TO DOCUMENT
$xmlRoot = $dom->createElement("list");
$xmlRoot = $dom->appendChild($xmlRoot);

// QUERY DATABASE
$db = new PDO('mysql:host=hostname;dbname=dbname','dbusername','password');
$stmt = $db->query("SELECT a.title AS title, a.price AS price, p.title AS type, c.title AS category, d.title AS developer FROM apartments a LEFT JOIN properties p ON (a.property_id = p.id) LEFT JOIN categories c ON (a.category_id = c.id) LEFT JOIN developers d ON (a.developer_id = d.id);");

// FETCH ROWS ITERATIVELY
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
    // APPEND property AS CHILD OF ROOT
    $propertyNode = $xmlRoot->appendChild($dom->createElement('property'));
    foreach ($row as $element=>$value) {
        // APPEND CHILDREN TO Property         
        $propertyNode->appendChild($dom->createElement($element, $value));
    }
}

// OUTPUT TO SCREEN
echo $dom->saveXML();

如果您将此数据提供给您自己的服务,您可能需要考虑 JSON 而不是 XML。 JSON 更简单的数据结构和 PHP 非常简洁的内置函数将使这个程序变得更小:

<?php
header('Content-type: application/json');    

// QUERY DATABASE
$db = new PDO('mysql:host=hostname;dbname=dbname','dbusername','password');
$stmt = $db->query("SELECT a.title AS title, a.price AS price, p.title AS type, c.title AS category, d.title AS developer FROM apartments a LEFT JOIN properties p ON (a.property_id = p.id) LEFT JOIN categories c ON (a.category_id = c.id) LEFT JOIN developers d ON (a.developer_id = d.id);");

// FETCH ROWS
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC));

// OUTPUT TO SCREEN
echo json_encode($rows);

【讨论】: