Getting objects instead of object properties in array - php

When I set $sales like so $sales = $response->xml->transactions the contents look like:
SimpleXMLElement Object
(
[transaction] => Array
(
[0] => SimpleXMLElement Object
(
[transId] => 9999999999
[submitTimeUTC] => 2016-03-16T21:57:54Z
[submitTimeLocal] => 2016-03-16T14:57:54
[transactionStatus] => capturedPendingSettlement
[invoiceNumber] => 4b1008a87f5262f0c867
[firstName] => Foo
[lastName] => Bar
[accountType] => Visa
[accountNumber] => XXXX1414
[settleAmount] => 155.00
[marketType] => eCommerce
[product] => Card Not Present
)
[1] => SimpleXMLElement Object
(
[transId] =>
So ->transaction contains an array. But if I do this:
$sales = $response->xml->transactions->transaction;
foreach ($sales as $s) {
$list[]= $s->invoiceNumber;
}
$list contains
Array
(
[0] => SimpleXMLElement Object
(
[0] => ac502c094fe1722ba100
)
[1] => SimpleXMLElement Object
(
[0] => e2eb58351c87155e3720
)
[2] => SimpleXMLElement Object
(
[0] => 0bca2bb6d5a13e641b67
)
What am I doing wrong? Where are the SimpleXMLElement Objects coming from where I just expected the invoiceNumber string?

The reason you are getting the SimpleXMLElement type objects is because when you are doing $list[]= $s->invoiceNumber; you are adding the element as it is. Since it is part of the SimpleXMLElement object it has that type internally. This comes up a lot when working with SimpleXML so its good to keep in mind.
As mentioned in the comments casting to a string will give you just the value:
$list[] = (string) $s->invoiceNumber;

Related

Issue accessing objects within objects in a file with XML format

I have a XML format file which has objects inside objects. This is how I get values of first object, which works fine for me:
$soapclient = new SoapClient('http://anywb/book.asmx?WSDL');
$params = array('ISBN' => "1111");
$response = $soapclient->GetBookByISBN($params);
//This will give me the value "Success"
$result = $response->GetBookByISBNResult->ResponseText;
Now my question is how to access the object which is inside object. For example, how to get "BookID" which is 4 and how to get value of "Type" which is 1?
Any suggestion would be appreciated. Here is the object:
stdClass Object
(
[GetBookByISBN] => stdClass Object
(
[ResponseText] => Success
[SearchResult] => stdClass Object
(
[Search] => Array
(
[0] => stdClass Object
(
[Date] => 2015-10-20
[BookID] => 4
[Discription] => stdClass Object
(
[Type] => 1
)
[Probability] => stdClass Object
(
[Kids] =>
[Adult] => 00
)
)
[1] => stdClass Object
(
[Date] => 2016-11-15
[BookID] => 5
[Discription] => stdClass Object
(
[Type] => 2
)
[Probability] => stdClass Object
(
[Kids] =>
[Adult] => 00
)
)
))))
You do it like this:
$response->GetBookByISBN->SearchResult->Search[0]->BookID;
$response->GetBookByISBN->SearchResult->Search[0]->Discription->Type;
If you would like to have an array containing all book ids you would have something like this:
$BookIDs = array();
foreach($response->GetBookByISBN->SearchResult->Search as $key => $value) {
$BookIDs[$key] = $value->BookID;
}
Or if you would like to be able to modify the values in $response using the $BookIDs (as an example) iot would look like this:
$BookIDs = array();
foreach($response->GetBookByISBN->SearchResult->Search as $key => $value) {
$BookIDs[$key] = &$value->BookID;
}

Returning an array within multiple objects and arrays

I can't seem to figure out the correct syntax to print:
[Agriculture] => AGR
[Animals] => AN
[Arts and Humanities] => ART
within the $TOPIC object.
What makes this a bit more confusing is that $TOPIC is in an object that can be called in a different order than this example. So instead of [3] => stdClass Object, it could be [4] => stdClass Object, (or any number).
Some sample foreach syntax is included below; it doesn't work though.
stdClass Object
(
[123456] => stdClass Object
(
[required_actions] => Array
(
[1] => stdClass Object
(
[maxlength] =>
[value] => $MESSAGE
[options_hash] =>
)
[2] => stdClass Object
(
[maxlength] =>
[value] => $NAME_PREFIX
[options_hash] => stdClass Object
(
[Ms.] => Ms.
[Mrs.] => Mrs.
[Mr.] => Mr.
)
)
[3] => stdClass Object
(
[maxlength] =>
[value] => $TOPIC
[options_hash] => stdClass Object
(
[Agriculture] => AGR
[Animals] => AN
[Arts and Humanities] => ART
)
)
)
)
)
foreach ($json->123456->required_actions as $info) {
echo $info->value => $TOPIC->options_hash;
}
The solution is to search for the parent object by value, and then request the child object's array. Here is what I used:
foreach ($json->123456->required_actions as $info) {
if ('$TOPIC' == $info->value) {
print_r($info->options_hash);
}
}

Sort multidimensional array of objects

I have seen so many example at stackoverflow to sort multidimensional array of object like
Sort array of objects
Sort array of objects by object fields
But none them could help me to sort my multidimensional array of objects given below
SimpleXMLElement Object
(
[request] => SimpleXMLElement Object
(
[address] => test
[citystatezip] => New York
)
[message] => SimpleXMLElement Object
(
[text] => Request successfully processed
[code] => 0
)
[response] => SimpleXMLElement Object
(
[results] => SimpleXMLElement Object
(
[result] => Array
(
[0] => SimpleXMLElement Object
(
[zpid] => 27965224
[links] => SimpleXMLElement Object
(
[homedetails] => test
[graphsanddata] =>test
[mapthishome] => test
[comparables] => test
)
[address] => SimpleXMLElement Object
(
[street] => test
[zipcode] => test
[city] => test
[state] => NY
[latitude] => 29.802114
[longitude] => -95.504244
)
[zestimate] => SimpleXMLElement Object
(
[amount] => 342911
[last-updated] => 11/27/2014
[oneWeekChange] => SimpleXMLElement Object
(
[#attributes] => Array
(
[deprecated] => true
)
)
[valueChange] => 5766
[valuationRange] => SimpleXMLElement Object
(
[low] => 312049
[high] => 373773
)
[percentile] => 0
)
[rentzestimate] => SimpleXMLElement Object
(
[amount] => 5177
[last-updated] => 11/24/2014
[oneWeekChange] => SimpleXMLElement Object
(
[#attributes] => Array
(
[deprecated] => true
)
)
[valueChange] => 370
[valuationRange] => SimpleXMLElement Object
(
[low] => 3417
[high] => 7041
)
)
[localRealEstate] => SimpleXMLElement Object
(
[region] => SimpleXMLElement Object
(
[#attributes] => Array
(
[id] => 271582
[type] => neighborhood
[name] => test
)
[links] => SimpleXMLElement Object
(
[overview] => test
[forSaleByOwner] => test
[forSale] => test
)
)
)
)
[1] => SimpleXMLElement Object
[2] => SimpleXMLElement Object
[3] => SimpleXMLElement Object
..............................
..............................
)
)
)
)
I need to sort the above array on the basis of key amount in descending order. But the problem is amount key exist under two different parent keys "zestimate" and "rentzestimate".
i have tried the following function but it did not work:
public function my_comparison($a, $b) {
if ($a->amount == $b->amount) {
return 0;
}
return ($a->amount < $b->amount) ? -1 : 1;
}
Any help?
Thanks in advance
response->results->result is an array of SimpleXMLElement objects. You want to sort the array based on the inner zestimate->amount property of the element in descending order.
You have to write a comparison function that accepts SimpleXMLElement objects and, because you want a descending order, returns 1 if the zestimate->amount property of the first object is less than that of the second, -1 if it's greater and 0 if it's equal:
public function my_comparison(SimpleXMLElement $a, SimpleXMLElement $b) {
if ($a->zestimate->amount == $b->zestimate->amount) {
return 0;
}
return ($a->zestimate->amount < $b->zestimate->amount) ? 1 : -1; // note the signs
}

I'm trying to find an attribute using simpleXML

I have a simpleXML output of:
SimpleXMLElement Object
(
[#attributes] => Array
(
[version] => 2
)
[currentTime] => 2013-02-05 21:26:09
[result] => SimpleXMLElement Object
(
[rowset] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => characters
[key] => characterID
[columns] => name,characterID,corporationName,corporationID
)
[row] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => Wrytha Cy
[characterID] => 209668693
[corporationName] => Deep Core Mining Inc.
[corporationID] => 1000006
)
)
[1] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => Eve Mae
[characterID] => 624980803
[corporationName] => Viziam
[corporationID] => 1000066
)
)
[2] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => Wrytha
[characterID] => 709227913
[corporationName] => The Flying Tigers
[corporationID] => 669350666
)
)
)
)
)
[cachedUntil] => 2013-02-05 21:35:04
)
I would like to loop through with my php loop and get "name' and "characterID". I've trying something like:
$simpleXML = simplexml_load_string($xml);
foreach ($simpleXML->result->rowset->row as $row) {
print_r($row);
$name = $row['#attributes']['name'];
echo $name.'<br>';
}
but $name is not being set. It's gonna be something simple, just not seeing it in my haste and first time with simpleXML.
Attributes are accessed using the syntax $element['attribute_name'], so in your case, you need $row['name'].
It's important to remember that SimpleXML objects are kind of magic - the $element->child, $element_list[0] and $element['foo'] syntax overloads the normal PHP logic to be useful. Similarly, (string)$element will give you the full textual content of an element, however it is broken up in the actual XML.
As such, the print_r output will not give you a "real" view of the object, so should be used with care. There are a couple of alternative debug functions I've written here which give a more accurate idea of how the object will behave.

How can I properly parse a SimpleXML Object in PHP?

I'm using the CloudFusion class to get Amazon.com data and my code is simple:
$items = $pas->item_search( "shoes", array(
"ResponseGroup" => "Small",
"SearchIndex" => "Blended" ));
$items = $items->body->Items;
echo "<pre>";
print_r( $items );
echo "</pre>";
This returns the following:
SimpleXMLElement Object (
[Request] => SimpleXMLElement Object
(
[IsValid] => True
[ItemSearchRequest] => SimpleXMLElement Object
(
[Keywords] => shoes
[ResponseGroup] => Small
[SearchIndex] => Blended
)
)
[TotalResults] => 737435
[TotalPages] => 245816
[SearchResultsMap] => SimpleXMLElement Object
(
[SearchIndex] => Array
(
[0] => SimpleXMLElement Object
(
[IndexName] => Kitchen
....
)
[Item] => Array
(
[0] => SimpleXMLElement Object
(
[ASIN] => B0001Z95QY
[DetailPageURL] => http://www.amazon.com/Household-Essentials-MS6030-Seasonal-Storage/dp/B0001Z95QY%3FSubscriptionId%3D0WASFFPR5B82TH4ZQB82%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB0001Z95QY
[ItemLinks] => SimpleXMLElement Object
(
[ItemLink] => Array
(
[0] => SimpleXMLElement Object
(
[Description] => Technical Details
[URL] => http://www.amazon.com/Household-Essentials-MS6030-Seasonal-Storage/dp/tech-data/B0001Z95QY%3FSubscriptionId%3D0WASFFPR5B82TH4ZQB82%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB0001Z95QY
) ....................
)
[1] => SimpleXMLElement Object
(
[ASIN] => B001ACNBZ8
[DetailPageURL] => http://www.amazon.com/Peet-Shoe-Dryer-Boot-Original/dp/B001ACNBZ8%3FSubscriptionId%3D0WASFFPR5B82TH4ZQB82%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB001ACNBZ8
[ItemLinks] => SimpleXMLElement Object
(...................
)
)
What I'd like to do is get down to the "Item" level, then run a foreach to get each individual entry. I tried $items = $items->Item, but this returns only the first entry.
Any ideas?
First of all, you should avoid using print_r() on SimpleXMLElement, instead just take a look at the XML using asXML(). That's also what you should post here, instead of print_r()'s output.
I can't decipher the code you have posted so I'll take a wild guess and suggest that you try something like:
foreach ($items->body->Items->Item as $Item)
{
}
At any rate, if you want to iterate over something, foreach is the answer.

Categories