0

This file is supposed to output a series of concatenated strings like the following:

"id number" "name of the fruit" "color of the fruit"

But when I test this out it just gives me a blank screen unless I use var_dump() to echo out the information. This information comes from a database and is assembled in a file called fruitxml.php. That's the file where my $contents variable comes from.

Even the echo $xml doesn't do anything. That should at least work. But it doesn't. What am I doing wrong which is giving me a blank screen?

   <?php

    $contents = file_get_contents("http://localhost:8888/SSL/Week3/Activity%203-3/fruitxml.php");

    $xml = new SimpleXMLElement($contents);

    echo $xml;

    foreach($xml->fruits as $fruit) {
        echo $fruit->fruitid . $fruit->fruitcolor . $fruit->fruitname . '.<br />';
    } ?>

    <pre><?php var_dump($xml) ?></pre>

When I use var_dump(), like I said, I get all my information but in JSON arrays and not in strings as I wanted.

 object(SimpleXMLElement)#1 (3) {
  ["fruitid"]=>
  array(5) {
    [0]=>
    object(SimpleXMLElement)#3 (1) {
      ["id"]=>
      string(1) "1"
    }
    [1]=>
    object(SimpleXMLElement)#5 (1) {
      ["id"]=>
      string(1) "4"
    }
    [2]=>
    object(SimpleXMLElement)#8 (1) {
      ["id"]=>
      string(1) "6"
    }
    [3]=>
    object(SimpleXMLElement)#11 (1) {
      ["id"]=>
      string(1) "8"
    }
    [4]=>
    object(SimpleXMLElement)#14 (1) {
      ["id"]=>
      string(1) "9"
    }
  }
  ["fruitname"]=>
  array(5) {
    [0]=>
    object(SimpleXMLElement)#2 (1) {
      ["name"]=>
      string(6) "Orange"
    }
    [1]=>
    object(SimpleXMLElement)#6 (1) {
      ["name"]=>
      string(6) "Grapes"
    }
    [2]=>
    object(SimpleXMLElement)#9 (1) {
      ["name"]=>
      string(5) "Apple"
    }
    [3]=>
    object(SimpleXMLElement)#12 (1) {
      ["name"]=>
      string(10) "Grapefruit"
    }
    [4]=>
    object(SimpleXMLElement)#15 (1) {
      ["name"]=>
      string(4) "Lime"
    }
  }
  ["fruitcolor"]=>
  array(5) {
    [0]=>
    object(SimpleXMLElement)#4 (1) {
      ["color"]=>
      string(6) "Orange"
    }
    [1]=>
    object(SimpleXMLElement)#7 (1) {
      ["color"]=>
      string(6) "Purple"
    }
    [2]=>
    object(SimpleXMLElement)#10 (1) {
      ["color"]=>
      string(3) "Red"
    }
    [3]=>
    object(SimpleXMLElement)#13 (1) {
      ["color"]=>
      string(14) "Pinkish Orange"
    }
    [4]=>
    object(SimpleXMLElement)#16 (1) {
      ["color"]=>
      string(5) "Green"
    }
  }
}

And here is the file with the XML that takes the info from the database.

<?php

$dbh = new PDO("mysql:host=localhost;port=8889;dbname=ssl", "root", "root");

$sth = $dbh->prepare('SELECT fruitid, fruitname, fruitcolor FROM fruitapp');
$sth->execute();
$result = $sth->fetchall();

header("Content-type: application/xml");
$xmlfile = '<?xml version="1.0" encoding="UTF-8"?>';
$xmlfile .= "<fruits>";

foreach($result as $user) {
    $xmlfile .= '<fruitid>';
    $xmlfile .= "<id>" . $user['fruitid'] . "</id>";
    $xmlfile .= '</fruitid>';
    $xmlfile .= '<fruitname>';
    $xmlfile .= "<name>" . $user['fruitname'] . "</name>";
    $xmlfile .= '</fruitname>';
    $xmlfile .= '<fruitcolor>';
    $xmlfile .= "<color>" . $user['fruitcolor'] . "</color>";
    $xmlfile .= '</fruitcolor>';
};

$xmlfile .= "</fruits>";

echo $xmlfile;

$dom = new DOMDocument("1.0");
$dom->loadXML($xmlfile);
$dom->save("myfruitxml.xml");

?>
NineBerry
  • 26,306
  • 3
  • 62
  • 93
Matt Lee
  • 521
  • 2
  • 5
  • 16

2 Answers2

0

Generate the xml like this:

function escapeXml($input)
{
    return htmlspecialchars($input, ENT_XML1, 'UTF-8');
}

$xmlfile = '<?xml version="1.0" encoding="UTF-8"?>';
$xmlfile .= "<fruits>";

foreach($result as $user) {
    $xmlfile .= '<fruit>';
    $xmlfile .= "<id>" . escapeXml($user['fruitid']) . "</id>";
    $xmlfile .= "<name>" . escapeXml($user['fruitname']) . "</name>";
    $xmlfile .= "<color>" . escapeXml($user['fruitcolor']) . "</color>";
    $xmlfile .= '</fruit>';
};

$xmlfile .= "</fruits>";

And output like this:

foreach($xml->fruit as $fruit) {
    echo $fruit->id . $fruit->color . $fruit->name . '.<br />';
} 

Explanations:

The root node of the document is represented by the SimpleXmlElement itself. So you don't have to use $xml->fruits. $xml already represents the fruits-node.

In order to access the individual fruits, place them in a <fruit> node each.

Putting the properties of a fruit in two nested nodes is not necessary. Use a single node for each property.

Use htmlspecialchars to escape special characters so that there are no syntax errors when for example the fruit name would contain a < or a &.

// Code not tested

NineBerry
  • 26,306
  • 3
  • 62
  • 93
  • Thank you! You are the first person to make any sense of this and actually got something displayed in my browser. Who knew all I had to do was simplify my XML. – Matt Lee Jan 22 '17 at 10:25
  • Note: instead of building the xml as a string, better use a library to do that as explained here http://stackoverflow.com/q/143122/101087 – NineBerry Jan 22 '17 at 10:41
-1

This is mostly because you're using file_get_contents, the url looks suspicious (because of the 8888 port used).

Consider using CURL instead and it should work :

<?php
$curl = curl_init('http://localhost/SSL/Week3/Activity%203-3/fruitxml.php'); 
curl_setopt($curl, CURLOPT_PORT, 8888); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 8888); 
$contents = curl_exec($curl);

$xml = new SimpleXMLElement($contents);

echo $xml;

foreach($xml->fruits as $fruit) {
    echo $fruit->fruitid . $fruit->fruitcolor . $fruit->fruitname . '.<br />';
} ?>

<pre><?php var_dump($xml) ?></pre>
mrbm
  • 2,164
  • 12
  • 11
  • Yeah my apache is on port 8888. My MySQL is on 8889. That's never been a problem before. Also I used the way you did it and it's still a blank screen. – Matt Lee Jan 21 '17 at 21:21