What's the best way to process this XML feed? - php

I've got an XML document that gives me addresses. Here's an excerpt:
<ezi:orderaddresses>
<ezi:orderaddress>
<ezi:addresstype>billing</ezi:addresstype>
<ezi:name>Jason Fonseca</ezi:name>
<ezi:companyname>Cyber</ezi:companyname>
<ezi:address1>8 springstein</ezi:address1>
<ezi:division>NT</ezi:division>
<ezi:postalcode>34245</ezi:postalcode>
<ezi:countrycode>AU</ezi:countrycode>
<ezi:email>jason#bigcreative.com.au</ezi:email>
<ezi:phone>89549854</ezi:phone>
<ezi:mobilephone>984590598</ezi:mobilephone>
</ezi:orderaddress>
<ezi:orderaddress>
<ezi:addresstype>shipping</ezi:addresstype>
<ezi:name>Jason Fonseca</ezi:name>
<ezi:companyname>Cyber</ezi:companyname>
<ezi:address1>8 springstein</ezi:address1>
<ezi:division>NT</ezi:division>
<ezi:postalcode>34245</ezi:postalcode>
<ezi:countrycode>AU</ezi:countrycode>
<ezi:email>jason#bigcreative.com.au</ezi:email>
<ezi:phone>89549854</ezi:phone>
</ezi:orderaddress>
</ezi:orderaddresses>
In addition to the above format of two "orderaddress" tags, there can also be one, for example:
<ezi:orderaddresses>
<ezi:orderaddress>
<ezi:addresstype>billing</ezi:addresstype>
<ezi:name>Jason Fonseca</ezi:name>
<ezi:companyname>Cyber</ezi:companyname>
<ezi:address1>8 springstein</ezi:address1>
<ezi:division>NT</ezi:division>
<ezi:postalcode>34245</ezi:postalcode>
<ezi:countrycode>AU</ezi:countrycode>
<ezi:email>jason#bigcreative.com.au</ezi:email>
<ezi:phone>89549854</ezi:phone>
<ezi:mobilephone>984590598</ezi:mobilephone>
</ezi:orderaddress>
</ezi:orderaddresses>
What I find is that when using simple xml to interpret this, in the first instance, I get the following:
[orderaddresses] => SimpleXMLElement Object
(
[orderaddress] => Array
(
[0] => SimpleXMLElement Object
(
[addresstype] => billing
[name] => Jason Fonseca
[companyname] => Cyber
[address1] => 8 springstein
[division] => NT
[postalcode] => 34245
[countrycode] => AU
[email] => jason#bigcreative.com.au
[phone] => 89549854
[mobilephone] => 984590598
)
[1] => SimpleXMLElement Object
(
[addresstype] => shipping
[name] => Jason Fonseca
[companyname] => Cyber
[address1] => 8 springstein
[division] => NT
[postalcode] => 34245
[countrycode] => AU
[email] => jason#bigcreative.com.au
[phone] => 89549854
)
)
)
And in the second instance, I get this:
[orderaddresses] => SimpleXMLElement Object
(
[orderaddress] => SimpleXMLElement Object
(
[addresstype] => billing
[name] => Jason Fonseca
[companyname] => Cyber
[address1] => 8 springstein
[division] => NT
[postalcode] => 34245
[countrycode] => AU
[email] => jason#bigcreative.com.au
[phone] => 89549854
[mobilephone] => 984590598
)
)
The Keen observer will notice that now if I try to access
orderaddresses->orderaddress that this would have a different structure depending on whether there are two addresses (or more) or just one address.
Example 2 it is a numerically index array, example two it is a an associative object.
To standardise this, I've used some code that looks like this :
if(!isset($content['orderlines']['orderline'][0]))
{
$temp = $content['orderlines']['orderline'];
unset($content['orderlines']['orderline']);
$content['orderlines']['orderline'][0] =$temp;
}
(you can ignore the fact that i'm using associative arrays here, i've got a routine that performs a conversion but I've checked and this routine does not change the result).
My question is, how am I supposed to correctly inteperet this data? Having that slice of code everytime I try to access the orderaddress and order lines is really messy. Isn't there a better way?
The thought of editing my conversion routine to handle this has crossed my mind. If you think that is the way to go, then let me know, but I thought to myself surely this problem must come up a lot and someone must have a smart, and brief solution to it?
Thanks

According to the documentation for simplexml you should always be able to iterate over and subscript properties even if there is only one of them, this may be the 'best' way of achieving what you want. e.g. :
for($xml->thingThereMayBeOneOrMoreOf as $item) {
//handle $item
}
or, if you only need to handle the first item
$item=$xml->thingThereMayBeOneOrMoreOf[0];
//handle $item
Also, according to the documentation these properties are not in fact arrays, but accessible (subscriptable) and iterable properties, just that var_dump etc will convert them to / treat them as arrays for the purposes of dumping.
I haven't actually tested this, ymmv.

Related

Getting values nested in multiple arrays

I get the response below from a script, and I need to extract board, model, serial number, current and upgrade.
Net\Response Object
(
[unrecognizedWords:protected] => Array
(
)
[_type:Net\Response:private] => !re
[attributes:protected] => Array
(
[board] => true
[model] => CRD
[serialnumber] => XXXXXXXX
[current] => 5.11
[upgrade] => 5.11
)
[_tag:Net\Message:private] =>
)
I've multiple combinations such as this:
echo unrecognizedWords:protected->attributes:protected->board;
However I can not get the values our of the array.
Can someone help me?
You cann't get any protected or private properties of object (only public). Use public methods (getters) of this object (sure, that it's provided).
Read: PHP: Visibility

How to reformat this array without knowing the keys in advance

I'm querying an API and getting a response back with various countries. Here is the relevant array I'm working with and what it prints out.
print_r($apiResponse['response']['data'][0]['countries']);
prints this:
Array ( [US] => Array ( [id] => 840 [code] => US [name] => United States [regions] => Array ( ) ) [CA] => Array ( [id] => 124 [code] => CA [name] => Canada [regions] => Array ( ) ) )
I am looking to save an array of only the two character country codes from that data. The only thing is the key is unknown to me when I query it so I don't know how to access the [code] section of it to save it to my new array.
I want to end up being able to take whatever amount of countries the API sends back and save the two character codes in a format like this:
'country_codes' => array('US','CA','UK','AU')
Thanks for your help!
Use the array_keys() function. Here you have the documentation.

how to get to a specific part of this nested array/object

This is driving me crazy, I am trying to get to a specific part of this object and it is driving me crazy, here is the object contents:
XMLHandler Object
(
[doc:XMLHandler:private] => SimpleXMLElement Object
(
[#attributes] => Array
(
[state] => Live
)
[newsListItem] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[href] => http://api.contentplus.co.uk/6cb5ea15-d6b1-4c40-9db7-cb2a3315080b/news/800773226/
)
[id] => 800773226
[publishDate] => 2011-10-24T10:04:49
[lastModifiedDate] => 2011-10-24T11:20:40
[headline] => Relationships matter on social media
)
)
)
[format] => html
)
I want to get the value of [id] I am trying to access it like this:
echo $niList->doc->newsListItem[0]->id;
but this is giving me nothing, I know I am close (well I hope I am) but I just cant quite get it right, could anyone help please.
Thanks all.
Your object dump says
doc:XMLHandler:private
which means doc is a private property of XMLHandler. As such, you can only access it from within that object via $this. But you are trying to access it from outside the object when you do
echo $niList->newsListItem[0]->id;
This wont work. Add a method to that XMLHandler object that does what you want to do with that newslistitem id. Also see the chapter on Visibility in the PHP Manual:
http://docs.php.net/manual/en/language.oop5.visibility.php

Having trouble extracting values from the Yelp API via PHP

Let me be up front: I'm a PHP hack. There's probably some stupid mistakes in here. Please point them out if you see them.
What I'm trying to do: I'm creating a page for a restaurant that would like their Yelp reviews displayed. I'm using the Yelp Phone API to grab the reviews for the specific business. Please view the sample response on the Yelp API documentation located here: http://www.yelp.com/developers/documentation/phone_api#sampleResponse
What I've done:
Successfully connected to the API and returned a response
echoed values from the response array in a foreach loop.
If you view the documentation, you can see there are a few levels of the response. I can easily print, echo, whatever values from the second tier, but what I'm really after is all nested in the "reviews" section of the response. I'm having trouble figuring out how to echo the values within the reviews section (eg user_name, review_excerpt etc).
My Code:
$yelpstring = file_get_contents("http://api.yelp.com/phone_search?phone=[redactedphonenumber]&ywsid=[redactedapikey]", true);
$obj = json_decode($yelpstring);
foreach($obj->businesses as $key => $business)
{
$reviews = $business->reviews;
//print_r($reviews);
echo $reviews['user_name'];
}
If I echo $reviews, I just get the word "Array". If I print_r($reviews), I get an expected list of keys and values. If I try to echo a specific value from the array(echo $reviews['user_name'], I get nothing. Any light shed on what I'm doing wrong would be greatly appreciated. I'm sure I'm missing something simple. Thank you for your time!
Edit: print_r($reviews) output:
Array ( [0] => stdClass Object ( [rating_img_url_small] => http://media4.px.yelpcdn.com/static/201012164278297776/img/ico/stars/stars_small_2.png [user_photo_url_small] => http://media2.px.yelpcdn.com/static/201012162819681786/img/gfx/blank_user_extra_small.gif [rating_img_url] => http://media4.px.yelpcdn.com/static/201012163489049252/img/ico/stars/stars_2.png [rating] => 2 [user_url] => http://www.yelp.com/user_details?userid=vZbcPrYPSMFIDIfTub5H1g [url] => http://www.yelp.com/biz/jelly-cafe-denver#hrid:u9ckRV6tKApe6Bu93M93CA [mobile_uri] => http://m.yelp.com/biz/5G2X2q9p7QFdm-LbyutltQ?srid=u9ckRV6tKApe6Bu93M93CA [text_excerpt] => I wanted to like this place. It's got the contemporary name and it's full of hipsters. The place looked clean and the style was fun and cute. I felt like... [user_photo_url] => http://media3.px.yelpcdn.com/static/201012161186834854/img/gfx/blank_user_small.gif [date] => 2011-09-07 [user_name] => boycott p. [id] => u9ckRV6tKApe6Bu93M93CA ) [1] => stdClass Object ( [rating_img_url_small] => http://media4.px.yelpcdn.com/static/201012164278297776/img/ico/stars/stars_small_2.png [user_photo_url_small] => http://media1.px.yelpcdn.com/upthumb/MWu84G5QtmBmT9GoqjT_kg/ss [rating_img_url] => http://media4.px.yelpcdn.com/static/201012163489049252/img/ico/stars/stars_2.png [rating] => 2 [user_url] => http://www.yelp.com/user_details?userid=izF2cGrmqt-u_Z2tDZ8dbg [url] => http://www.yelp.com/biz/jelly-cafe-denver#hrid:OYLeeCMgnpZkk1c9LWu97g [mobile_uri] => http://m.yelp.com/biz/5G2X2q9p7QFdm-LbyutltQ?srid=OYLeeCMgnpZkk1c9LWu97g [text_excerpt] => Food is decent and overpriced, but service is a joke. Your food will take a minimum of 20 minutes, for the basic breakfast. Then when your food does come... [user_photo_url] => http://media1.px.yelpcdn.com/upthumb/MWu84G5QtmBmT9GoqjT_kg/ms [date] => 2011-09-06 [user_name] => April H. [id] => OYLeeCMgnpZkk1c9LWu97g ) [2] => stdClass Object ( [rating_img_url_small] => http://media2.px.yelpcdn.com/static/20101216418129184/img/ico/stars/stars_small_4.png [user_photo_url_small] => http://media1.px.yelpcdn.com/upthumb/3euzdGdLZRFxImY68MSg7w/ss [rating_img_url] => http://media2.px.yelpcdn.com/static/201012164084228337/img/ico/stars/stars_4.png [rating] => 4 [user_url] => http://www.yelp.com/user_details?userid=bHR9UU4vtx2QKZD44O0E5g [url] => http://www.yelp.com/biz/jelly-cafe-denver#hrid:njvNAzfSII3PxXyUymLZ1w [mobile_uri] => http://m.yelp.com/biz/5G2X2q9p7QFdm-LbyutltQ?srid=njvNAzfSII3PxXyUymLZ1w [text_excerpt] => Stopped here for breakfast on a friday morning. We were seated immediately and had a really friendly waitress. I ordered a side order of the Chai french... [user_photo_url] => http://media1.px.yelpcdn.com/upthumb/3euzdGdLZRFxImY68MSg7w/ms [date] => 2011-09-05 [user_name] => Diane F. [id] => njvNAzfSII3PxXyUymLZ1w ) )
Based on the output of print_r you can't reference $reviews['user_name'];
Note that $reviews is an Array of objects. So to access user_name you need to use
echo $reviews[0]->user_name;
And if you have more than one item in the array, you will need a loop like
for ($i = 0; $i<count($reviews); $i++) {
echo $reviews[$i]->user_name;
}
I hope this helps.
$reviews is an array of review objects. You'll need to loop over it to get to the data you're after.

fastest way to get element values from an array object in php

I have something like this
Array
(
[0] => stdClass Object
(
[CustomerID] => 14
[Email] => joe.blogs#example.com
[LastName] => Blogs
[BirthDayOfMonth] => 29
[Gender] =>
[Occupation] =>
[SendSpecialOffers] => 1
[SendReminderNotes] => 1
)
[1] => stdClass Object
(
[CustomerID] => 1460
[Email] => example#example.com
[LastName] => Example
[BirthDayOfMonth] => 5
[Gender] => F
[Occupation] =>
[SendSpecialOffers] => 1
[SendReminderNotes] => 1
)
);
I would like get Email address of each separated by commas, something like this
'joe.blogs#example', 'example#example.com'
I know i could iterate it through foreach but i got a really big list, is there anyway to do it faster? thanks
Now, how can i remove the indexes based some email addresses?
You can do this with array map and a function but this will also iterate your array
echo implode(',',array_map('getEmail',$array));
function getEmail($obj)
{
return $obj->Email;
}
The simplest solution would indeed be a foreach() to iterate over all the items of your array ; adding, for each item, the email to a another resulting array.
Maybe you could replace the foreach by a call to array_walk(), but it probably wouldn't change much :
You wouldn't loop in PHP, as array_walk is coded in C (could be a bit faster than foreach -- not sure, though)
But a function would be called for each item, instead of just a couple of PHP instructions.
You'd have to benchmark, to see if there is a significant difference in your specific case -- but I personnaly would go for the foreach, without thinking much more.
array_filter is best..see the examples on manual

Categories