2

On a php script, how does one do a foreach loop using a string to output XML data that gets values from a msql database? I took some code from the while loop that's inside the simpleXmlElement hoping it would output xml but it did not work. The server i'm working on doesn't allow the class SimpleXMLElement so i need to use the string to do a foreach loop and output the xml as needed.

What i have so far: Edited:

<?php
#Programmer: Moses

require('./.env');

// Opens a connection to a mySQL server
try {
    $db = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME. ';charset=utf8',  DB_USERNAME, DB_PASSWORD);
} catch (PDOException $e) {
    echo "An Error occured, could not connect!";
}

$statement = $db->query('SELECT * FROM markers');
//$result = $statement->fetchAll(PDO::FETCH_ASSOC);

$xmlWriter = new XMLWriter();
$xmlWriter->openUri('php://stdout');

$xmlWriter->startDocument();
$xmlWriter->setIndent(2);
$xmlWriter->startElement('markers');
foreach ($statement as $row) {
  $xmlWriter->startElement('marker');
  $xmlWriter->writeAttribute('name', $row['name']);
  $xmlWriter->writeAttribute('address', $row['address']);
  $xmlWriter->writeAttribute('lat', $row['lat']);
  $xmlWriter->writeAttribute('lng', $row['lng']);
  $xmlWriter->writeAttribute('type', $row['type']);
  $xmlWriter->endElement();
}
$xmlWriter->endElement();
$xmlWriter->endDocument();


/**
$str = <<<XML
<xml>
       <marker name="Walvis Bay Live"   lat="-22.956112" lng="14.508056" address="Walvis bay namibia Africa" type="Weather Station"></marker>
       <marker name="Centro Surf Bracciano" lat="11.588599" lng="43.145851" address="djibouti djibouti" type="Weather Station"></marker>
       <marker name="Bashewa Weather" lat="-25.825212" lng="28.312128" address="Garstfontein Rd Pretoria" type="Weather Station"></marker>
       <marker name="Nelspruit Live" lat="-25.475298" lng="30.969416" address="nelspruit south africa" type="Weather Station"></marker>
       <marker name="Richards Bay Live" lat="-28.780727" lng="32.038284" address="richards bay south africa" type="Weather Station"></marker>
       <marker name="Cape Town Live" lat="-33.923775" lng="18.423346" address="cape town south africa" type="Weather Station"></marker>
</xml>
XML;

header("Content-type: text/xml");
echo $str;
exit;
*/


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

while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
    $node = $xml->addChild('marker');
    $node->addAttribute('name', $row['name']);
    $node->addAttribute('address', $row['address']);
    $node->addAttribute('lat', $row['lat']);
    $node->addAttribute('lng', $row['lng']);
    $node->addAttribute('type', $row['type']);
}

header('Content-type: text/xml');
print($xml->asXML());
exit;
*/
5
  • I will chock pretty much everyone here but.. what have you tried? Commented Jul 3, 2016 at 0:42
  • Just edited my post @D4V1D Commented Jul 3, 2016 at 0:52
  • Must it be xml? JSON is easier to work with on both ends. Note: foreach doesn't return anything to $str Commented Jul 3, 2016 at 1:28
  • Either need to find an xml class library that works or manually (uggh) create the xml as string Commented Jul 3, 2016 at 1:42
  • Can you please provide me an example? @charlietfl Commented Jul 3, 2016 at 3:10

1 Answer 1

0

foreach can iterate any array or object that implements traversable. The result of PDOStatement::fetch() is the record/row. Just provide the statement to foreach.

foreach($statement as $row) { ...   

The better API for dumps like that is XMLWriter. It writes the result directly to a stream, without storing the whole document in memory first. Using an XML API will take care of the escaping as needed, too. Here is a small example:

$statement = [
  [ 'name' => 'one', 'location' => '...', /* ... */],
  [ 'name' => 'two', 'location' => '...', /* ... */]
];

$xmlWriter = new XMLWriter();
$xmlWriter->openUri('php://stdout');

$xmlWriter->startDocument();
$xmlWriter->setIndent(2);
$xmlWriter->startElement('markers');
foreach ($statement as $row) {
  $xmlWriter->startElement('marker');
  $xmlWriter->writeAttribute('name', $row['name']);
  /* other attributes ... */
  $xmlWriter->endElement();
}
$xmlWriter->endElement();
$xmlWriter->endDocument();

Output:

<?xml version="1.0"?>
<markers>
 <marker name="one"/>
 <marker name="two"/>
</markers>

In DOM you create, append and configure nodes. Here is a small example: https://stackoverflow.com/a/21760903/2265374

Sign up to request clarification or add additional context in comments.

5 Comments

Amazing! I have a few questions, firstly what does this mean "$xmlWriter->openUri('php://stdout'); " especiall the stdout part. Also, if I just want to use the data from the database instead of writing the data in the xml file, should i replace the code in $statement to an sql command like what i have in my example?
openUri() opens the stream specified by the URI (This could be a filename, too). php://stdout is the php standard output, the stream you're writing to using print or echo. Yes, replace the array definition with the actual, executed PDO statement object.
I just made changes (see my post above), but for some reason it didn't output to xml the php file couldn't load on the browser. Do i have to change: $xmlWriter->openUri('php://stdout'); to something else?
nevermind it's because i don't have the libxml extension
ext/domxml? That would be the old PHP 4 DOM extension, do you really program for PHP 4 or do you mean the PHP 5 ext/dom extension? Here is an example for ext/dom stackoverflow.com/a/21760903/2265374

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.