My request PHP file elaborates some Ajax POST data:
POST data
data[0][id]:359
data[0][position]:1
data[1][id]:321
data[1][position]:2
data[2][id]:354
data[2][position]:3
Request.php
if(isset($_POST['data'])) {
if(isset($_SESSION['username']) && isset($_SESSION['password'])) {
$verify = $loggedIn->verify();
if($verify['username']) {
$Profile = new Profile();
$Profile->db = $db;
//Call my function
$messages = $Profile->setOrder($_POST['data']);
}
}
}
Profile.php
function setOrder($post) {
var_dump($post);
foreach($post as $item)
{
return "Area ID ".$item["id"]." and person located ".$item["position"]."<br />";
}
}
My function returns nothing and the dump of $post is as below
array(3) {
[0]=>
array(2) {
["id"]=>
string(3) "359"
["position"]=>
string(1) "1"
}
[1]=>
array(2) {
["id"]=>
string(3) "321"
["position"]=>
string(1) "2"
}
[2]=>
array(2) {
["id"]=>
string(3) "354"
["position"]=>
string(1) "3"
}
}
Inside my function I can dump correctly something like var_dump($post[0]["id"]); so why my foreach loop is empty?
It is because you are using return inside loop. It will terminate the loop after first iteration. You need to do something like this.
$return = null;
foreach($data as $item)
{
$return .= "Area ID ".$item["id"]." and person located ".$item["position"]."<br />";
}
return $return;
Related
I try to iterate through an array by using this function:
public static function getDataForChartAlexaDailyRank($data)
{
$asd = [];
$new = [];
$site = [];
for ($x = 0; $x < sizeof($data->data); $x++) {
foreach ((array)#$data->data->{$x} as $value) {
array_push($site, intval($value->{"Response"}->{"TrafficHistoryResult"}->{"Alexa"}->{"TrafficHistory"}->{"Site"}));
}
foreach ((array)#$data->data->{$x} as $value) {
array_push($new, intval($value->{'Response'}->{'TrafficHistoryResult'}->{'Alexa'}->{'TrafficHistory'}->{'HistoricalData'}->{'Data'}->{'Rank'}));
}
$asd[] = ['name' => $site, 'data' => $new];
$new = [];
}
return json_encode($asd);
}
The array looks like this:
["data"]=>
object(stdClass)#229 (2) {
["mainUrl"]=>
object(stdClass)#235 (1) {
["Response"]=>
object(stdClass)#238 (2) {
["OperationRequest"]=>
object(stdClass)#237 (1) {
["RequestId"]=>
string(36) "1d7824a5-dc09-4efb-9f2a-b35055abc04d"
}
["TrafficHistoryResult"]=>
object(stdClass)#241 (1) {
["Alexa"]=>
object(stdClass)#242 (1) {
["TrafficHistory"]=>
object(stdClass)#243 (4) {
["Range"]=>
string(2) "31"
["Site"]=>
string(25) "https://app.klipfolio.com"
["Start"]=>
string(10) "2016-07-01"
["HistoricalData"]=>
object(stdClass)#244 (1) {
["Data"]=>
array(31) {
[0]=>
object(stdClass)#245 (4) {
["Date"]=>
string(10) "2016-07-01"
["PageViews"]=>
object(stdClass)#246 (2) {
["PerMillion"]=>
string(3) "2.5"
["PerUser"]=>
string(4) "5.50"
}
["Rank"]=>
string(5) "30467"
["Reach"]=>
object(stdClass)#247 (1) {
["PerMillion"]=>
string(2) "30"
}
}
}
}
}
}
}
}
}
["competitorUrl1"]=>
object(stdClass)#338 (1) {
["Response"]=>
object(stdClass)#339 (2) {
["OperationRequest"]=>
object(stdClass)#340 (1) {
["RequestId"]=>
string(36) "ac7ba0b9-c789-5f6a-f1c8-714587b494e9"
}
["TrafficHistoryResult"]=>
object(stdClass)#341 (1) {
["Alexa"]=>
object(stdClass)#342 (1) {
["TrafficHistory"]=>
object(stdClass)#343 (4) {
["Range"]=>
string(2) "31"
["Site"]=>
string(23) "http://onlinesupport.io"
["Start"]=>
string(10) "2016-07-01"
["HistoricalData"]=>
object(stdClass)#344 (0) {
["Data"]=>
array(31) {
[0]=>
object(stdClass)#245 (4) {
["Date"]=>
string(10) "2016-07-01"
["PageViews"]=>
object(stdClass)#246 (2) {
["PerMillion"]=>
string(3) "2.5"
["PerUser"]=>
string(4) "5.50"
}
["Rank"]=>
string(5) "30467"
["Reach"]=>
object(stdClass)#247 (1) {
["PerMillion"]=>
string(2) "30"
}
}
}
}
}
}
}
}
}
}
The array is stored in the variable $data (hence the $data-data to access the array) and I have to iterate through both objects (["mainUrl"] and ["competitorUrl1"] to get the ["Site"] and ["Rank"] and store them into the variable $asd. The function I have written tries to do this. I say tries because I don't know how to properly iterate thorugh objects with different names (["mainUrl"] and ["competitorUrl1"]). I am sorry if I did not explain it well enough but I am a noob in php, so if you have any questions please ask. Thank you very much for your time.
foreach ((array)#$data->data[$x]->{'Response'}->{'TrafficHistoryResult'}->{'Alexa'}->{'TrafficHistory'}->{'HistoricalData'}->{'Data'} as $value) {
Did you forget ->{'mainUrl'} there? So it would be something like follows:
public static function getDataForChartAlexaDailyRank($data)
{
$asd = [];
$new = [];
for ($x = 0; $x < sizeof($data->data); $x++) {
$site = $data->data[$x]->{'mainUrl'}->{'Response'}->{'TrafficHistoryResult'}->{'Alexa'}->{'TrafficHistory'}->{'Site'};
foreach ($data->data[$x]->{'mainUrl'}->{'Response'}->{'TrafficHistoryResult'}->{'Alexa'}->{'TrafficHistory'}->{'HistoricalData'}->{'Data'} as $value) {
array_push($new, intval($value->{'Rank'}));
}
$asd[] = ['name' => $site, 'data' => $new];
$new = [];
}
return json_encode($asd);
}
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
Suppose I have a JSON string:
$json = '{"lemon":"test",
"orange":["toto", "tata", "tete"],
"zob":[{"id":"0"}, {"id":"1"}]}';
I'd like to cycle through that encoded object to modify every string in it, so I have a recursive function:
function doObject($__obj){
$__obj = cycleObject($__obj);
return $__obj;
}
function cycleObject($__obj){
$type = gettype($__obj);
foreach($__obj as $var => &$val){
switch(gettype($val)){
case 'object':
cycleObject($val);
break;
case 'array':
cycleObject($val);
break;
case 'string':
if($type == 'object'){
$__obj->$var = $val.'-ok';
}else{
if($type == 'array'){
$__obj[$var] = $val.'-ok';
}
}
break;
}
}
return $__obj;
}
And I call the function:
$obj = doObject(json_decode($json));
var_dump($obj);
Which gives :
object(stdClass)#1 (3) {
["lemon"]=> string(7) "test-ok"
["orange"]=> array(3) {
[0]=> string(4) "toto"
[1]=> string(4) "tata"
[2]=> string(4) "tete" }
["zob"]=> array(2) {
[0]=> object(stdClass)#2 (1) {
["id"]=> string(4) "0-ok" }
[1]=> object(stdClass)#3 (1) {
["id"]=> string(4) "1-ok" }
}
}
Now my problem is, for some reason, I am unable to modify directly inside an array composed by string, or should I say, the modified string inside an array (and not inside an object inside an array) because the array loses its reference. How do I fix that so in orange I instead obtain:
[0]=> string(7) "toto-ok"
[1]=> string(7) "tata-ok"
[2]=> string(7) "tete-ok"
Your array of strings isn't being scrutinized correctly by your function. Basically, in each array you need a second check to see if you are dealing with another array/object or a string, otherwise regular arrays of strings are being bypassed....oddly enough. The following should work for you:
$json = '{"lemon":"test",
"orange":["toto", "tata", "tete"],
"zob":[{"id":"0"}, {"id":"1"}]}';
function doObject($__obj){
$__obj = cycleObject($__obj);
return $__obj;
}
function cycleObject($__obj){
foreach($__obj as $key => &$val){
if(is_object($val)) {
cycleObject($val);
}
if(is_array($val)) {
foreach($val as &$v) {
if(is_object($v) || is_array($v)) {
cycleObject($v);
} else {
$v .= '-ok';
}
}
}
if(is_string($val)) {
$val .= '-ok';
}
}
return $__obj;
}
$obj = doObject(json_decode($json));
var_dump($obj);
This produced the results you were looking for in my local environment.
object(stdClass)#1 (3) {
["lemon"]=>
string(7) "test-ok"
["orange"]=>
array(3) {
[0]=>
string(7) "toto-ok"
[1]=>
string(7) "tata-ok"
[2]=>
string(7) "tete-ok"
}
["zob"]=>
array(2) {
[0]=>
object(stdClass)#2 (1) {
["id"]=>
string(4) "0-ok"
}
[1]=>
object(stdClass)#3 (1) {
["id"]=>
string(4) "1-ok"
}
}
}
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;
}
I am calling a webservice and I am getting a complex object back. I need to display variables reg_no, opening_inventory_weight.
RESULT:-
object(stdClass)#12 (3) {
["TxnErrors"]=> object(stdClass)#13 (0) { }
["TxnStatus"]=> bool(true)
["headers"]=> object(stdClass)#14 (1) {
["RPMHeader"]=> array(1) {
[0]=> object(stdClass)#15 (7) {
["opening_inventory_weight"]=> int(1001)
["prepared_by"]=> string(5) "James"
["reg_no"]=> string(7) "5000005"
["reporting_period"]=> string(19) "2010-02-01T00:00:00"
["rsid"]=> int(49) ["status"]=> string(1) "D"
["web_user_id"]=> string(1) "0" } } } }
I am calling it like
$result = call_search_existing_manufacturer();
$rows = array();
foreach ($result->RPMHeader as $data)
{
$rows[] = array(
$data->reg_no,
$data->opening_inventory_weight,
$data->status
);
}
But its not working. Any Idea what am I missing? Thank you in advance
I think it should be
$result = call_search_existing_manufacturer();
$rows = array();
foreach ($result->headers->RPMHeader as $data)
{
$rows[] = array(
$data->reg_no,
$data->opening_inventory_weight,
$data->status
);
}
Your result dump isn't esay too read, so I may be wrong, but it looks like RPMHeader is part of headers field, so you should access it like
$result->headers->RPMHeader