Correctly outputting JSON with php? - php

New to working with JSON. I have the following XML results. I'd like to offer the same results but in JSON format when requested. My data is coming from a mySQL array.
My problem comes in when I try to have multiple nodes of the same name. Take my XML result for instance:
<results>
<result>
<item_id>1</item_id>
</result>
<result>
<item_id>50</item_id>
</result>
<result>
<item_id>50433</item_id>
</result>
<result>
<item_id>3</item_id>
</result>
</results>
If I simply do something like the following in PHP, my data keeps overwriting eachother.
foreach($result as $key => $value) {
$json["results"]["result"]["item_id"] = $value;
}
It gives me only one line of result which is the last item_id of 3.
What am I overlooking?

You're overwriting your value in your loop because you're not putting it into an array.
$json["results"]["result"]["item_id"] = $value;
should be
$json["results"]["result"]["item_id"][] = $value;

Related

How to move XML file data to PHP array?

This is my xml data
<?xml version="1.0" encoding="iso-8859-1"?>
<smslist>
<sms>
<cid>FIRSTCID</cid>
<mid>FIRSTMID</mid>
<mb>98389923</mb>
</sms>
<sms>
<cid>SECONDCID</cid>
<mid>SECONDMID</mid>
<mb>76445645</mb>
</sms>
...
</smslist>
How to push cid and mid data to php array like $array = array(("FIRSTCID","FIRSTMID"),("SECONDCID","SECONDMID")...)
Excuse if this is some duplicate question. :)
you can try this:
$xml = new SimpleXMLElement($your_xml_string);
$xml_array=[];
foreach ($xml->smslist->sms as $sms) {
$xml_array[]=array($sms->cid,$sms->mid);
}
By using xml_parse_into_struct() you can convert XML to array, for detailed document check below link.
http://php.net/manual/en/function.xml-parse-into-struct.php

Parsing XML API data result from Plesk

I try to get domain name from Plesk API result XML data as below:
<packet version="1.6.7.0">
<site-alias>
<get>
<result>
<status>ok</status>
<info>
<name>example.com</name>
</info>
</result>
<result>
<status>ok</status>
<info>
<name>domain.net</name>
</info>
</result>
</get>
</site-alias>
</packet>
using
$xml= simplexml_load_string($response);
echo $xml['site-alias']['get']['result'][0]['name'];
if there is more better way to do so, please advice, thanks.
There are multiple ways to get the values using SimpleXMLElement.
To get only 1 value, you could for example do it like this:
// Get 1 using SimpleXMLElement
echo $xml->{"site-alias"}->get->result->info->name;
// Get 1 using xpath
echo $xml->xpath('/packet/site-alias/get/result[1]/info/name')[0];
To get multiple values you could do it like this:
// Get multiple using SimpleXMLElement
$items = $xml->{"site-alias"}->get->result;
foreach ($items as $item) {
echo $item->info->name . "<br>";
}
// Get multiple using xpath
$items = $xml->xpath('/packet/site-alias/get/result/info/name');
foreach ($items as $item) {
echo $item . "<br>";
}
The SimpleXMLElement has a method __toString so you can echo the string content.
The xpath method returns an array, so you can get the first value using index 0.
A short way to get your value could be:
echo $xml->xpath('//name')[0];
Demo

PHP getting an API Trying to get property of non-object

I am working on the Zillow API to get search results and I have hit a snag. I am using thier GetSearchResults tool and I get the error:
Trying to get property of non-object
on the line where i use -> notation to get values from XML. I have read discussions on it and maybe I am doing the notation wrong but I am seeing nothing wrong. How can I get data from the this object?
Here is my current code.
<?php
$zillow_id = 'X1-ZWz19g3j9ffabv_7galu';
$search = isset($_GET['5411 lydia ave'])?$_GET['5411 lydia ave']:"";
$citystate = isset($_GET['kansascitymo64110'])?$_GET['kansascitymo64110']:"";
$address = urlencode($search);
$citystatezip = urlencode($citystate);
$url = "http://www.zillow.com/webservice/GetSearchResults.htm?zws-id=$zillow_id&address=$address&citystatezip=$citystatezip";
$result = file_get_contents($url);
$data = simplexml_load_string($result);
$zpid=$data->response->results->result[0]->zpid;
echo $zpid;
?>
Below is the XML I am talking about:
<SearchResults:searchresults xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance" xmlns:SearchResults="http://www.zillow.com/static/xsd/SearchResults.xsd" xsi:schemaLocation="http://www.zillow.com/static/xsd/SearchResults.xsd http://www.zillowstatic.com/vstatic/5b67875/static/xsd/SearchResults.xsd">
<request>...</request>
<message>...</message>
<response>
<results>
<result>
<zpid>2349353</zpid>
<links>...</links>
<address>
<street>5411 Lydia Ave</street>
<zipcode>64110</zipcode>
<city>Kansas City</city>
<state>MO</state>
<latitude>39.02831</latitude>
<longitude>-94.568747</longitude>
</address>
<zestimate>...</zestimate>
<localRealEstate>...</localRealEstate>
</result>
</results>
</response>
</SearchResults:searchresults>
result in this case at least is not an array. So the correct syntax would be
echo $data->response->results->result->zpid;
In case you have more than one result like this :
<response>
<results>
<result>
<zpid>2349353</zpid>
</result>
<result>
<zpid>5676567</zpid>
</result>
<result>
<zpid>987987</zpid>
</result>
</results>
</response>
You should get zpid as follow :
$zpid=$data->response->results->result[0]->zpid; // 2349353
$zpid=$data->response->results->result[1]->zpid; // 5676567
$zpid=$data->response->results->result[2]->zpid; // 987987

PHP newbie- specific scenario on how to parse an XML value stored in a variable using SimpleXML [duplicate]

This question already has an answer here:
php simple xml parse problem on invalid tags
(1 answer)
Closed 9 years ago.
I want to parse an XML data stored in a variable, using Simple XML.
THis is the data I am talking about:
<SearchResults:searchresults xsi:schemaLocation="http://www.zillow.com/static/xsd/SearchResults.xsd /vstatic/ae1bf8a790b67ef2e902d2bc04046f02/static/xsd/SearchResults.xsd">
<request>
<address>2114 Bigelow Ave</address>
<citystatezip>Seattle, WA</citystatezip>
</request>
<message>
<text>Request successfully processed</text>
<code>0</code>
</message>
<response>
<results>
<result>
<zpid>48749425</zpid>
<links>
<homedetails>http://www.zillow.com/homedetails/2114-Bigelow-Ave-N-Seattle-WA-98109/48749425_zpid/</homedetails>
<graphsanddata>http://www.zillow.com/homedetails/charts/48749425_zpid,1year_chartDuration/?cbt=7522682882544325802%7E9%7EY2EzX18jtvYTCel5PgJtPY1pmDDLxGDZXzsfRy49lJvCnZ4bh7Fi9w**</graphsanddata>
<mapthishome>http://www.zillow.com/homes/map/48749425_zpid/</mapthishome>
<comparables>http://www.zillow.com/homes/comps/48749425_zpid/</comparables>
</links>
<address>
<street>2114 Bigelow Ave N</street>
<zipcode>98109</zipcode>
<city>Seattle</city>
<state>WA</state>
<latitude>47.63793</latitude>
<longitude>-122.347936</longitude>
</address>
<zestimate>
<amount currency="USD">1219500</amount>
<last-updated>11/03/2009</last-updated>
<oneWeekChange deprecated="true"/>
<valueChange duration="30" currency="USD">-41500</valueChange>
<valuationRange>
<low currency="USD">1024380</low>
<high currency="USD">1378035</high>
</valuationRange>
<percentile>0</percentile>
</zestimate>
<localRealEstate>
<region id="271856" type="neighborhood" name="East Queen Anne">
<zindexValue>525,397</zindexValue>
<zindexOneYearChange>-0.144</zindexOneYearChange>
<links>
<overview>http://www.zillow.com/local-info/WA-Seattle/East-Queen-Anne/r_271856/</overview>
<forSaleByOwner>http://www.zillow.com/homes/fsbo/East-Queen-Anne-Seattle-WA/</forSaleByOwner>
<forSale>http://www.zillow.com/east-queen-anne-seattle-wa/</forSale>
</links>
</region>
<region id="16037" type="city" name="Seattle">
<zindexValue>381,764</zindexValue>
<zindexOneYearChange>-0.074</zindexOneYearChange>
<links>
<overview>http://www.zillow.com/local-info/WA-Seattle/r_16037/</overview>
<forSaleByOwner>http://www.zillow.com/homes/fsbo/Seattle-WA/</forSaleByOwner>
<forSale>http://www.zillow.com/seattle-wa/</forSale>
</links>
</region>
<region id="59" type="state" name="Washington">
<zindexValue>263,278</zindexValue>
<zindexOneYearChange>-0.066</zindexOneYearChange>
<links>
<overview>http://www.zillow.com/local-info/WA-home-value/r_59/</overview>
<forSaleByOwner>http://www.zillow.com/homes/fsbo/WA/</forSaleByOwner>
<forSale>http://www.zillow.com/wa/</forSale>
</links>
</region>
</localRealEstate>
</result>
</results>
</response>
</SearchResults:searchresults>
Now the above type of XML is stored in variable named $zillow_data
First I load it using SimpleXML using the code
$xml = simplexml_load_string($zillow_data);
Now, I want to get the "message" value as shown in the XML data above.
When I try
foreach($xml->message[0]->text[0] as $response)
It does not work.
When I try something like the below code I get an error in Netbeans IDE
foreach($xml->SearchResults:searchresults[0]->message[0]->text[0] as $response)
The error I get is "unexpected : "
How do I correctly fetch the message in above XML data?
Also how do I parse through all the "result" elements, one by one?
If You use the code:
$xml = simplexml_load_string($string);
while the $string variable contains the XML, the first element <SearchResults:searchresults> becomes the main $xml SimpleXMLElement object, while the child tags <request>, <message> and <response> are its properties.
Thus, forgetting about the undefined namespace warnings, You should be able to do e.g.:
foreach($xml->response->results->result as $result) {
echo (string) $result->zpid;
}
There is only one message with only one text element, thus if You want to echo this one, You should only do:
echo (string) $xml->message->text;
Do a var_dump($xml); to understand the XML structure being transformed into objects and arrays after loading it with SimpleXML.

Adding Nodes to Existing XML

The problem i was having is the Root XML was being produced every time it writes to the XML.
The Main issue was setting up Child and Defining the Root. From the help of Łza
I now understand the Root XML Node is ignored.
So then you setup and create a Child and then add your content, And example of the correct format is.
$xml = simplexml_load_file('FILENAME.xml'); // Load XML File Need to add IF Statment to create if does not exist
$result = $xml->addchild('Result'); // Ignore Root NODE and Add Child Results
$result->addChild('Time', gmdate('D-M-Y -H:i:s')); // Rest of the below adds Child to Result and outputs results
$result->addChild('Channel', $Site);
$result->addChild('Type', '**');
$result->addChild('Process', $Status);
$result->addChild('SKU', $code->SKU);
$result->addChild('item', $item);
$result->addChild('Status', '$Feedback');
$result->addChild('ErrorID', '$Error');
$result->addChild('Message', '$Message');
$xml->asXml('FILENAME.xml'); //Write to file would be
// All of the above Code is using variables from another part of the script
The output would be
<Root>
<Result>
<Time>Fri-May-2013 -09:15:22</Time>
<Channel>20</Channel>
<Type>**</Type>
<Process>Update</Process>
<SKU>98746524765</SKU>
<Item/>
<Status>Problem</Status>
<ErrorID>999-Error</ErrorID>
<Message>Unknown file format support</Message>
</Result>
<Result>
<Time>Fri-May-2013 -09:15:22</Time>
<Channel>20</Channel>
<Type>**</Type>
<Process>Update</Process>
<SKU>5412254785</SKU>
<Item/>
<Status>Problem</Status>
<ErrorID>123-Error</ErrorID>
<Message>Invalid Item</Message>
</Result>
</Root>
Thanks
Try to use SimpleXMLElement library instead hardcoded xml creation. This is maybe more complicate to use at the begining, but much more safe (I mean avoid possible errors in xml structure when you hardcode the xml) and easy to use when you just get start to use it.
And easy to add/remove nodes, childnodes.
This is an example for your code:
$xml = new SimpleXMLElement('<xml/>');
$data = $xml->addChild('data');
$result = $data->addChild('Result');
$result->addChild('Time', gmdate('D-M-Y -H:i:s'));
$result->addChild('Channel', $SiteID);
// ... and the same way create all your xml nodes.
// if you want add next <result> node witch all elements repeat the code, (or put it in loop if you want more <result> elements):
$result = $data->addChild('Result');
$result->addChild('Time', gmdate('D-M-Y -H:i:s'));
$result->addChild('Channel', $SiteID);
// and after create all nodes save the file:
$xml->asXml('DHError.xml');
above code will create xml:
<xml>
<data>
<Result>
<Time>Fri-May-2013 -12:14:39</Time>
<Channel>data</Channel>
</Result>
<Result>
<Time>Fri-May-2013 -12:14:39</Time>
<Channel>data</Channel>
</Result>
</data>
</xml>
Thats it. Then if you need to load and process the xml it would be easy:
To load the File simply use:
$xml2 = simplexml_load_file('DHError.xml');
// to add new node <Result>:
$resultNext = $xml2->data->addchild('Result');
$resultNext->addChild('Time', gmdate('D-M-Y -H:i:s'));
$resultNext->addChild('Channel', $SiteID);
//and save file
$xml2->asXml('DHError.xml');
this create a xml:
<?xml version="1.0" ?>
<xml>
<data>
<Result>
<Time>Fri-May-2013 -12:27:24</Time>
<Channel>data</Channel>
</Result>
<Result>
<Time>Fri-May-2013 -12:27:24</Time>
<Channel>data</Channel>
</Result>
<Result>
<Time>Fri-May-2013 -12:27:24</Time>
<Channel>data</Channel>
</Result>
</data>
</xml>

Categories