create php array using simpleXMLobject - php

I'm trying to get this array ($resdata) with object(SimpleXMLElement) into a php array:
$resdata =
array(59) {
[0]=> ...
[10]=> object(SimpleXMLElement)#294 (28) {
["reservation_id"]=> string(7) "8210614"
["event_id"]=> string(6) "279215"
["space_reservation"]=> array(2) {
[0]=> object(SimpleXMLElement)#344 (9) {
["space_id"]=> string(4) "3760"
["space_name"]=> string(9) "205"
["formal_name"]=> string(33) "Center" }
[1]=> object(SimpleXMLElement)#350 (9) {
["space_id"]=> string(4) "3769"
["space_name"]=> string(9) "207"
["formal_name"]=> string(32) "Right" } } }
}
I've tried:
$res = (array)$resdata;
$reservation = $res['reservation'];
$result = array();
foreach ($reservation as $key => $value){
$res = array($value);
$spid = $res[0]->space_reservation->space_id;
echo $value->event_id."<br />";
echo $spid."<br />";
}
This only outputs the first space_id and I need to get all the space_ids within "space_reservation" array. Not all records will have multiple space_ids. Any help pointing me in the right direction is appreciated. Not sure if I should use xpath but I need to re-write my foreach statement regardless.
I was hoping to be able to literally convert all references to "object(SimpleXMLElement)#_ (#)" to "array(#)"
[10]=> array (28) {
["reservation_id"]=> string(7) "8210614"
["event_id"]=> string(6) "279215"
["space_reservation"]=> array(2) {
[0]=> array (9) {
["space_id"]=> string(4) "3760"
["space_name"]=> string(9) "205"
["formal_name"]=> string(33) "Center" }
[1]=> array (9) {
["space_id"]=> string(4) "3769"
["space_name"]=> string(9) "207"
["formal_name"]=> string(32) "Right" } } }
}
the function in my cakephp 1.3 controller is this:
$xml = simplexml_load_string($string);
$this->data['events']= $xml->children();
$resdata = $this->data['events'];
$this->set('resdata',$resdata);

I think this should do what you are looking for:
foreach ($resdata as $res) {
echo $res->event_id . '<br />';
foreach ($res->space_reservation as $reservation) {
echo $reservation->space_id . '<br />';
}
}

Googled it and found a general solution for any SimpleXMLElement to array conversion:
function xml2array($xml) {
$arr = array();
foreach ($xml as $element) {
$tag = $element->getName();
$e = get_object_vars($element);
if (!empty($e)) {
$arr[$tag] = $element instanceof SimpleXMLElement ? xml2array($element) : $e;
}
else {
$arr[$tag] = trim($element);
}
}
return $arr;
}

Related

how to use explode for an array of objects

I have an array like that:
array(5) {
["code"]=>
int(1)
["messageError"]=>
string(27) "La typologie est incorrecte"
["model"]=>
string(3) "lot"
["grp_regles"]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(3) {
["champ"]=>
string(21) "lot_surface_habitable"
["comparaison"]=>
string(7) "between"
["valeurAttendue"]=>
array(2) {
[0]=>
int(16)
[1]=>
int(40)
}
}
}
}
["prerequis"]=>
array(2) {
[0]=>
array(3) {
["champ"]=>
string(6) "typ_id"
["comparaison"]=>
string(1) "="
["valeurAttendue"]=>
int(1)
}
[1]=>
array(3) {
["champ"]=>
string(22) "tranche.fus.fup.fup_id"
["comparaison"]=>
string(1) "="
["valeurAttendue"]=>
int(1)
}
}
}
I want to do a foreach in "prerequis":
$modelRetrieve = $this->retrieveModel($model);
$modelFind = $modelRetrieve::find($id);
$arrayError=[];
$query = '';
$path = storage_path() . "/json/controle.json";
$json = file_get_contents($path);
foreach (json_decode($json,true) as $key => $value) {
$test = true;
var_dump($value);
if($value['model'] === $model ){
foreach ($value['prerequis'] as $key => $value2) {
if( $test && $modelFind[$value2['champ']] == (int)$value2["valeurAttendue"] )
{
$test = true;
}
}
}
}
I need in second foreach to use in $value2['champ'] where $value2['champ'] is "tranche.fus.fup_id. So I need to explode that to have ['tranche']['fus']['fup_id'].
How to use explode with that ?
thanks everyone :)
you can use laravel data_get helper:
data_get($value2, $value2['champ'])
To nest the $segments of the string starting with the innermost item of the result, we have to array_reverse() the $segments so we can loop over it and wrap each iteration's result with another array level in the next iteration until we looped through the whole $segments array.
$exploded = array_reduce(array_reverse(explode('.', $value2['champ'])), function($res, $segment) {
return [ $segment => $res ];
}, []);

Find duplicate elements in an array

I got an array of coins with many details, that looks partially like that:
array(360) {
["VEN/USDT"]=>
array(15) {
["tierBased"]=>
bool(false)
}
["id"]=>
string(7) "VENUSDT"
["symbol"]=>
string(8) "VEN/USDT"
["base"]=>
string(3) "VEN"
["quote"]=>
string(4) "USDT"
["lot"]=>
float(0.01)
["active"]=>
bool(true)
}
All I need is this part:
["id"]=>
string(7) "VENUSDT"
["symbol"]=>
string(8) "VEN/USDT"
["base"]=>
string(3) "VEN"
["quote"]=>
string(4) "USDT"
if "base" is more often than once in the entire array.
The final code was:
$base_array = array();
foreach ($markets as $key=>$value) {
echo "1. Key = " . $key . "\n";
foreach ($value as $key => $value) {
if ($key == "base") {
echo "Base = " . $value . "\n";
array_push($base_array, $value);
}
}
}
// Duplicates we need only!
$unique = array_unique($base_array);
$duplicates1 = array_diff_assoc($base_array, $unique);
$duplicates = array_unique($duplicates1);
var_dump($duplicates);

PHP - get unique values in while loop

I have the following code:-
if( $featured_query->have_posts() ): $property_increment = 0;
while( $featured_query->have_posts() ) : $featured_query->the_post();
$town = get_field('house_town');
$a = array($town);
$b = array_unique($a);
sort($b);
var_dump($b);
$property_increment++; endwhile; ?>
<?php endif; wp_reset_query();
var_dump(b) shows:-
array(1) { [0]=> string(10) "Nottingham" } array(1) { [0]=> string(9) "Leicester" } array(1) { [0]=> string(9) "Leicester" } array(1) { [0]=> string(11) "Mountsorrel" } array(1) { [0]=> string(12) "Loughborough" } array(1) { [0]=> string(12) "Loughborough" }
var_dump($town) shows:-
string(10) "Nottingham" string(9) "Leicester" string(9) "Leicester" string(11) "Mountsorrel" string(12) "Loughborough" string(12) "Loughborough"
var_dump($a) shows:-
array(1) { [0]=> string(10) "Nottingham" } array(1) { [0]=> string(9) "Leicester" } array(1) { [0]=> string(9) "Leicester" } array(1) { [0]=> string(11) "Mountsorrel" } array(1) { [0]=> string(12) "Loughborough" } array(1) { [0]=> string(12) "Loughborough" }
What I want to do is get the unique vales of $town and output them into a select option:-
<select>
<option value="Leicester">Leicester</option>';
<option value="Loughborough">Loughborough</option>';
<option value="Mountsorrel">Mountsorrel</option>';
</select>';
In alpha as above, any help would be much appreciated.
#collect all get_field('house_town') in while
$collect[] = get_field('house_town');
#then do the work
$html = implode('',
array_map(
function($a){
return "<option value='{$a}'>{$a}</option>";
},
array_unique($collect)
)
);
Your array needs to be un-nested with array_column before you sort it and make it unique. So after you initialised $a, continue like this:
$b = array_unique(array_column($a, 0));
sort($b);
and then make the HTML:
$html = "";
foreach($b as $town) {
$html .= "<option value='$town'>$town</option>";
}
echo "<select>$html</select>";
If you don't have array_column, then you can use this replacement:
function array_column($arr, $column) {
$res = array();
foreach ($arr as $el) {
$res[] = $el[$column];
}
return $res;
}
Here's a summary of Chris G's comment and trincot's code snippet for generating the HTML code.
Note: for testing purposes I have created the $town array manually here. Replace it by your statement $town = get_field('house_town');
<?php
$town = array(
"Nottingham",
"Leicester",
"Leicester",
"Mountsorrel",
"Loughborough",
"Loughborough"
);
// $town = get_field('house_town');
$html = "";
$town = array_unique($town);
sort($town);
foreach($town as $xtown) {
$html .= "<option value='$xtown'>$xtown</option>";
}
echo "<select>$html</select>";
?>
Basic/ General unique usage in while/ foreach loop
// refer to
$a = array($town); // $a in while/ foreach loop
if(current($a) != next($a)) {
// do your query here // get required unique here
}
// Note: caring and sharing

PHP: Combining data with a shared key from a single array into new array

I have this array:
array(5) {
[0]=>
array(4) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTextSeq"]=>
string(1) "1"
["productTxtVal"]=>
string(5) "Text1"
}
[1]=>
array(4) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTextSeq"]=>
string(1) "2"
["productTxtVal"]=>
string(5) "Text2"
}
[2]=>
array(4) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTextSeq"]=>
string(1) "3"
["productTxtVal"]=>
string(5) "Text3"
}
[3]=>
array(4) {
["productCode"]=>
string(4) "X002"
["productUPC"]=>
string(3) "262"
["productTextSeq"]=>
string(1) "1"
["productTxtVal"]=>
string(5) "Text1"
}
[4]=>
array(4) {
["productCode"]=>
string(4) "X002"
["productUPC"]=>
string(3) "262"
["productTextSeq"]=>
string(1) "2"
["productTxtVal"]=>
string(5) "Text2"
}
}
With the above input, I want the output array to look like this:
array(2) {
[0]=>
array(3) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTxtVal"]=>
string(17) "Text1 Text2 Text3"
}
[1]=>
array(3) {
["productCode"]=>
string(4) "X002"
["productUPC"]=>
string(3) "262"
["productTxtVal"]=>
string(11) "Text1 Text2"
}
}
The resulting array does not need the productTextSeq key, just the combined values of productTextVal, when the productCode is the same. I've searched SO for examples of this but it seems every example I've found are based on multiple input arrays. I know I can brute force this with nested foreach functions but would love a more elegant solution.
I ended up just doing it the brute force method, here is my solution if anyone's interested:
$productData = array();
$sortedData = array();
$comments = '';
$saveKey = '';
$appendComment = false;
$idx = 0;
foreach ($data as $key=>$value) {
foreach ($value as $k=>$v) {
if ($k == 'productCode') {
if ($v == $saveKey) {
$appendComment = true;
} else {
$appendComment = false;
$saveKey = $v;
if ($idx !== 0) { // Don't write to array on first iteration!
$productData['productTxtVal'] = $comments;
$sortedData[] = $productData;
}
}
}
if ($k == 'productTxtVal') {
if ($appendComment == true) {
$comments .= ' ' . trim($v);
} else {
$comments = trim($v);
}
}
}
$productData = $value;
$idx++;
}
Not "elegant" but it works. I also have a check after this logic in case only one productCode is in the original array, as it won't be written to the $sortedData array since the key never changes.
The following code assumes you control the contents of the original data array (due to risk of injection using extract() function) and that no 2 items with the same productCode have the same productTextSeq.
$products = [];
foreach ($data as $item) {
// extract contents of item array into variables
extract($item);
if (!isset($products[$productCode])) {
// create product array with code, upc, text as array
$products[$productCode] = compact('productCode', 'productUPC') + ['productTxtVal' => []];
}
// add text value to array with sequence as index
$products[$productCode]['productTxtVal'][$productTextSeq] = $productTxtVal;
}
$products = array_values( // ignore array keys
array_map(function($product) {
ksort($product['productTxtVal']); // sort text as array by index/ sequence
$product['productTxtVal'] = implode(' ', $product['productTxtVal']); // implode into string
return $product;
}, $products)
);
You can run the code here: https://repl.it/BWQL

Traverse non-numerical indexes of an array

Think I'm missing a basic concept. I want to generate html by traversing through a few different arrays of data. They don't use numbers as indexes so numerical looping doesn't work. I cant figure out how to use a foreach() here either. How can I traverse $price and $description when the indexes aren't numbers?
Sample:
$traverser= 0;
while($traverser < $number_of_records)
{
print $traverser . " - " . $price[$traverser] . "<br />";
print $description[$traverser];
$traverser++;
}
Partial Sample of the Array Structure:
object(phpQueryObject)#2799 (13) { ["documentID"]=> string(32) "1d62be942498df890cab4ccb78a007a2" ["document"]=> &object(DOMDocument)#3 (0) { } ["charset"]=> &string(5) "utf-8" ["documentWrapper"]=> &object(DOMDocumentWrapper)#2 (17) { ["document"]=> &object(DOMDocument)#3 (0) { } ["id"]=> string(32) "1d62be942498df890cab4ccb78a007a2" ["contentType"]=> string(9) "text/html" ["xpath"]=> &object(DOMXPath)#4 (0) { } ["uuid"]=> int(0) ["data"]=> array(0) { } ["dataNodes"]=> array(0) { } ["events"]=> array(0) { } ["eventsNodes"]=> array(0) { } ["eventsGlobal"]=> array(0) { } ["frames"]=> array(0) { } ["root"]=> &object(DOMElement)#5 (0) { } ["isDocumentFragment"]=> &bool(true) ["isXML"]=> bool(false) ["isXHTML"]=> bool(false) ["isHTML"]=> bool(true) ["charset"]=> &string(5) "utf-8" } ["xpath"]=> &object(DOMXPath)#4 (0) { } ["elements"]=> array(560) { [0]=> object(DOMElement)#2239 (0) { } [1]=> object(DOMElement)#2240 (0) { } [2]=> object(DOMElement)#2241 (0) { } [3]=> object(DOMElement)#2242 (0) { } [4]=> object(DOMElement)#2243 (0) { } [5]=> object(DOMElement)#2244 (0) { } [6]=> object(DOMElement)#2245 (0) { } [7]=> object(DOMElement)#2246 (0) { } [8]=> object(DOMElement)#2247 (0) { }
Since it looks like you need the array keys as well, since you're referencing multiple different arrays, you want the $a as $k => $v syntax for foreach:
foreach($description as $key => $desc)
{
print $key . " - " . $price[$key] . "<br />";
print $desc;
}
You can take your pic as to how you want to iterate them:
<?php
$ary = array( // demo array
'apple' => 'Apple',
'orange' => 'Orange',
'grape' => 'Grape'
);
// show the structure
var_dump($ary); echo "\r\n";
// use a foreach with the key and value
foreach ($ary as $key => $val)
printf("%s => %s\r\n", $key, $val);
echo "\r\n";
// just get the raw keys
$keys = array_keys($ary);
var_dump($keys); echo "\r\n";
output:
array(3) {
["apple"]=>
string(5) "Apple"
["orange"]=>
string(6) "Orange"
["grape"]=>
string(5) "Grape"
}
apple => Apple
orange => Orange
grape => Grape
array(3) {
[0]=>
string(5) "apple"
[1]=>
string(6) "orange"
[2]=>
string(5) "grape"
}
There's always array_map & array_walk.
I'm not sure I get the question, but it's really as simple as:
<?php
$array = array('foo', 'bar');
foreach ($array as $element) {
echo "{$element}\n";
}
This should output "foo" and "bar".

Categories