在数组对象中查找值
问题描述:
I have the following code:
function searchObject($obj, $field, $value) {
foreach ($obj as $item){ # gets to products
foreach ($item as $child) { #gets to products, products is an array of products
foreach ($child as $grandchild){ #gets to products array
if (isset($grandchild->$field) && $grandchild->$field == $value) {
return $grandchild;
}
}
}
}
return "Not Found";
}
This is how it's called:
$freetrialobj = searchObject($arr, "pid", 15);
But that doesn't work, reporting an 'invalid argument'. Here is the print_r of the object of arrays:
Array: stdClass Object
(
[result] => success
[clientid] => 706
[serviceid] =>
[pid] =>
[domain] =>
[totalresults] => 1
[startnumber] => 0
[numreturned] => 1
[products] => stdClass Object
(
[product] => Array
(
[0] => stdClass Object
(
[id] => 1014
[clientid] => 706
[orderid] => 902
[pid] => 15
[regdate] => 2013-09-03
[name] =>
[groupname] =>
[domain] =>
[dedicatedip] =>
[serverid] => 0
[servername] =>
[serverip] =>
[serverhostname] =>
[firstpaymentamount] => 0.00
[recurringamount] => 0.00
[paymentmethod] => authorize
[paymentmethodname] => Authorize.net
[billingcycle] => Free Account
[nextduedate] => 0000-00-00
[status] => Pending
[username] =>
[password] =>
[subscriptionid] =>
[promoid] => 0
[overideautosuspend] =>
[overidesuspenduntil] => 0000-00-00
[ns1] =>
[ns2] =>
[assignedips] =>
[notes] =>
[diskusage] => 0
[disklimit] => 0
[bwusage] => 0
[bwlimit] => 0
[lastupdate] => 0000-00-00 00:00:00
[customfields] => stdClass Object
What is the best way to check a nested object like this for a value?
答
There is probably a php function that does this, but rather than brute-forcing it, as your function attempts, lets apply some recursive thinking:
function searchObject($obj, $field, $value) {
if (is_array($obj)) { //Is this object even array?
if( array_key_exists($field, $obj) ) { //Check to see if the object exists
return $obj->$field; //If so, return it
} else {
foreach ($obj as $key => $val) {//Search all sub-objects
$result = searchObject($val, $field, $value);//Make a recursive call
if ($result !== false) {//If not false, we found it!
return $result; //return the result
}
}
return false;//Otherwise we didn't find it, return false
}
} else {
return false;//This isn't an array, so it can't possibly have the field.
}
}
This should be able to (do a depth-first) search an object of any depth for your field, and return it or false
if it's not there. Note that it will return the first such field it finds; if there are multiple matching fields, you will miss anything beyond the first.