Php 如何执行查询、将结果集行分组并转换为XML?
我有个问题。我编写了以下代码来为我想要的XML创建一个数组:Php 如何执行查询、将结果集行分组并转换为XML?,php,arrays,xml,mysqli,Php,Arrays,Xml,Mysqli,我有个问题。我编写了以下代码来为我想要的XML创建一个数组: $BusinessId = $_GET["businessid"]; $CustomerCode = $_GET["customerid"]; $sql = "SELECT * FROM Customers WHERE Code=".$CustomerCode." AND BusinessId=".$BusinessId; $result = $conn->query($sql); $row = mysqli_fetch_as
$BusinessId = $_GET["businessid"];
$CustomerCode = $_GET["customerid"];
$sql = "SELECT * FROM Customers WHERE Code=".$CustomerCode." AND BusinessId=".$BusinessId;
$result = $conn->query($sql);
$row = mysqli_fetch_assoc($result);
$CustomerId = $row["Id"];
$sql = "SELECT * FROM Albums WHERE CustomerId=".$CustomerId." ORDER BY Id DESC";
$result1 = $conn->query($sql);
$arr_albums = array();
while ($row1 = mysqli_fetch_assoc($result1))
{
$arr_images = array();
$sql = "SELECT * FROM ImagesWithAlbum WHERE AlbumId=".$row1["Id"]." ORDER BY ImageId ASC";
$result2 = $conn->query($sql);
while ($row2 = mysqli_fetch_assoc($result2))
{
$sql = "SELECT * FROM Images WHERE Id=".$row2["ImageId"];
$result3 = $conn->query($sql);
$row3 = mysqli_fetch_assoc($result3);
$image_array = array(
array(
'Id'=>$row3["Id"],
'Name'=>$row3["Name"])
);
$arr_images[] = $image_array;
}
$album_array = array(
array(
'Id'=>$row1["Id"],
'Image'=>$arr_images)
);
$arr_albums[] = $album_array;
}
现在我想从这个数组中创建一个XML,所以我创建了以下代码:
function toXml(SimpleXMLElement $xml, array $data, $mainKey = null)
{
foreach ($data as $key => $value) {
// if the key is an integer, it needs text with it to actually work.
if (is_numeric($key)) {
$key = $mainKey ? : "key_$key";
}
if (is_array($value)) {
$childXml = $xml->addChild($key);
toXml($childXml, $value);
} else {
$xml->addChild($key, $value);
}
}
return $xml;
}
// Pretty print Xml
function formatXml($simpleXMLElement)
{
$xmlDocument = new DOMDocument('1.0');
$xmlDocument->preserveWhiteSpace = false;
$xmlDocument->formatOutput = true;
$xmlDocument->loadXML($simpleXMLElement->asXML());
return $xmlDocument->saveXML();
}
$xml = toXml(new SimpleXMLElement('<Albums/>'), $arr_albums, 'Album');
$output = $xml->asXML();
header('Content-Type: text/xml');
print formatXml($xml);
函数toXml(simplexmlement$xml,数组$data,$mainKey=null)
{
foreach($key=>$value形式的数据){
//如果键是一个整数,它需要有文本才能实际工作。
如果(是数字($key)){
$key=$mainKey?:“key_u$key”;
}
if(是_数组($value)){
$childXml=$xml->addChild($key);
toXml($childXml,$value);
}否则{
$xml->addChild($key,$value);
}
}
返回$xml;
}
//漂亮的打印Xml
函数formatXml($simpleXMLElement)
{
$xmlDocument=新的DOMDocument('1.0');
$xmlDocument->preserveWhiteSpace=false;
$xmlDocument->formatOutput=true;
$xmlDocument->loadXML($simplexmlement->asXML());
返回$xmlDocument->saveXML();
}
$xml=toXml(新的simplexmlement(“”),$arr_albums,'Album');
$output=$xml->asXML();
标题('Content-Type:text/xml');
打印格式xml($xml);
问题是xml几乎和我想要的方式一样,只是xml中有一个标记。标签如下所示:
<Albums>
<Album>
<Id>4</Id>
<Images>
<key_0>
<Image>
<Id>2</Id>
<Name>viktor_rood.png</Name>
</Image>
</key_0>
<key_1>
<Image>
<Id>5</Id>
<Name>viktor_geel.png</Name>
</Image>
</key_1>
<key_2>
<Image>
<Id>7</Id>
<Name>viktor_paars.png</Name>
</Image>
</key_2>
<key_3>
<Image>
<Id>8</Id>
<Name>viktor_aqua.png</Name>
</Image>
</key_3>
</Images>
</Album>
</Albums>
4.
2.
viktor_rood.png
5.
viktor_geel.png
7.
viktor_paars.png
8.
viktor_aqua.png
现在,我如何删除key_x
标记,因为我不需要它
我做错了什么?您正在将不必要的数组级别推送到
$image\u array
和$album\u array
,这就是导致键*
标记的原因。如果删除,则应删除这些密钥:
$image_array = array(
'Id'=>$row3["Id"],
'Name'=>$row3["Name"]
);
$album_array = array(
'Id'=>$row1["Id"],
'Images'=>$arr_images
);
您还需要更改toXML
函数,以便在递归时提供$mainkey
值。在这个版本中,我选择从当前键中去掉最后一个字符(因此对于图像
,您将在它们下面得到图像
标记):
对于您的数据,您应该得到如下结果:
<?xml version="1.0"?>
<Albums>
<Album>
<Id>4</Id>
<Images>
<Image>
<Id>2</Id>
<Name>viktor_rood.png</Name>
</Image>
<Image>
<Id>5</Id>
<Name>viktor_geel.png</Name>
</Image>
<Image>
<Id>7</Id>
<Name>viktor_paars.png</Name>
</Image>
<Image>
<Id>8</Id>
<Name>viktor_aqua.png</Name>
</Image>
</Images>
</Album>
</Albums>
- 准备好的声明检查。
- 连接子句检查。
- 嵌套循环走了。
- 迭代查询走了。
- 临时按键操作走了。
- 递归走了。
TBH,我没有测试查询,也没有做很多XML工作。如果有什么不对劲,我很乐意修复它。看看你的脚本有多干净、安全和可读性
部分代码:()()
函数formatXml($simpleXMLElement){
$xmlDocument=新的DOMDocument('1.0');
$xmlDocument->preserveWhiteSpace=false;
$xmlDocument->formatOutput=true;
$xmlDocument->loadXML($simplexmlement->asXML());
返回$xmlDocument->saveXML();
}
如果(isset($\u GET[“businessid”],$\u GET[“customerid”])){
$sql=“选择Albums.Id、Images.Id、Images.Name
来自客户
加入Customer.Id=Albums.CustomerId上的相册
在相册上加入ImagesWithAlbum.Id=ImagesWithAlbum.AlbumId
在ImagesWithAlbum.ImageId=Images.Id上连接图像
其中Customers.Code=?和Customers.BusinessId=?
按Id描述、图像Id排序”;
$stmt=$conn->prepare($sql);
$stmt->bind_-param(“ss”、$\u-GET[“businessid”]、$\u-GET[“customerid”]);//如果两个整数
$stmt->execute();
$stmt->bind_result($albumId、$imageId、$imageName);
$albums=新的SimpleXMLElement(“”);
$currentAlbumId=null;
而($stmt->fetch()){
如果($currentAlbumId!==$albumId){
$album=$albums->addChild('album');
$album->addChild('Id',$albumId);
$images=$album->addChild('images');
}
$image=$images->addChild('image');
$image->addChild('Id',$imageId)
$image->addChild('Name',$imageName);
$currentAlbumId=$albumId;
}
echo formatXml($albums);
}
输出:
<?xml version="1.0"?>
<Albums>
<Album>
<Id>4</Id>
<Images>
<Image>
<Id>2</Id>
<Name>viktor_rood.png</Name>
</Image>
<Image>
<Id>5</Id>
<Name>viktor_geel.png</Name>
</Image>
<Image>
<Id>7</Id>
<Name>viktor_paars.png</Name>
</Image>
<Image>
<Id>8</Id>
<Name>viktor_aqua.png</Name>
</Image>
</Images>
</Album>
</Albums>
4.
2.
viktor_rood.png
5.
viktor_geel.png
7.
viktor_paars.png
8.
viktor_aqua.png
警告:您的代码容易受到SQL注入攻击。您应该使用参数化查询和准备好的语句来帮助防止攻击者使用恶意输入值破坏您的数据库。给出了风险的解释,以及如何使用PHP/mysqli安全地编写查询的一些示例。切勿将未初始化的数据直接插入SQL。按照现在编写代码的方式,有人可能很容易窃取、错误地更改甚至删除您的数据。您可以使用join
s通过1或2次查询来完成这一切。不过,请参数化您的查询。无论如何,我怀疑您的问题在于array_merge()并不像您认为的那样。这里有一个线索:“如果输入数组具有相同的字符串键,则该键的后一个值将覆盖前一个”(我的粗体)。我假设您真正想做的是向数组中添加另一项,而不是合并/覆盖它。但是是的,这里不需要这么多单独的查询-了解SQL中的内部连接
。谢谢,我将对此进行研究,但我更新了我的代码。我让它工作了,但还是有一个小问题。我的XML中有一个来自该数组的奇怪标记?在您的视图中哪一个是“奇怪的”?你的意思可能是
等等?对不起,现在标签
不见了。还是
标签@A.Vreeswijk我没有在你的代码中向下滚动足够远,你的$album\u array
也有同样的问题。看到我的编辑…现在我已经包围了所有的图像,仍然是每个图像<代码>4 2 viktor_rood.png 5 viktor_geel.png 7 viktor_paars.png 8 viktor_aqua.png我想
放在
@A.Vreeswijk的位置,我想这是个问题
function formatXml($simpleXMLElement) {
$xmlDocument = new DOMDocument('1.0');
$xmlDocument->preserveWhiteSpace = false;
$xmlDocument->formatOutput = true;
$xmlDocument->loadXML($simpleXMLElement->asXML());
return $xmlDocument->saveXML();
}
if (isset($_GET["businessid"], $_GET["customerid"])) {
$sql = "SELECT Albums.Id, Images.Id, Images.Name
FROM Customers
JOIN Albums ON Customer.Id = Albums.CustomerId
JOIN ImagesWithAlbum ON Albums.Id = ImagesWithAlbum.AlbumId
JOIN Images ON ImagesWithAlbum.ImageId = Images.Id
WHERE Customers.Code = ? AND Customers.BusinessId = ?
ORDER BY Id DESC, ImageId";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ss", $_GET["businessid"], $_GET["customerid"]); // use 'ii' if both integers
$stmt->execute();
$stmt->bind_result($albumId, $imageId, $imageName);
$albums = new SimpleXMLElement('<Albums/>');
$currentAlbumId = null;
while ($stmt->fetch()) {
if ($currentAlbumId !== $albumId) {
$album = $albums->addChild('Album');
$album->addChild('Id', $albumId);
$images = $album->addChild('Images');
}
$image = $images->addChild('Image');
$image->addChild('Id', $imageId)
$image->addChild('Name', $imageName);
$currentAlbumId = $albumId;
}
echo formatXml($albums);
}
<?xml version="1.0"?>
<Albums>
<Album>
<Id>4</Id>
<Images>
<Image>
<Id>2</Id>
<Name>viktor_rood.png</Name>
</Image>
<Image>
<Id>5</Id>
<Name>viktor_geel.png</Name>
</Image>
<Image>
<Id>7</Id>
<Name>viktor_paars.png</Name>
</Image>
<Image>
<Id>8</Id>
<Name>viktor_aqua.png</Name>
</Image>
</Images>
</Album>
</Albums>