For Each Key Isn't A Number - php

So I'm trying to iterate through an XML feed and paginate it but I've run into a problem. When I try to get the index (key) of the current array it outputs a string "campDetails" on every iteration instead of an incrementing integer like 0,1,2,3
Here is a sample of the XML format
<campaigns>
<campDetails>
<campaign_id>2001</campaign_id>
<campaign_name>Video Chat Software</campaign_name>
<url>http://www.fakeurl.com</url>
</campDetails>
<?php
$call_url = "https://www.fakeurl.com";
if($xml = simplexml_load_file($call_url, "SimpleXMLElement", LIBXML_NOCDATA)):
foreach($xml as $i => $offers):
$offer_link = $offers->url;
$offer_raw_name = $offers->campaign_name;
echo $i . " " . $offer_link; ?> </br> <?php echo $offer_raw_name;
endforeach;
endif;
?>
Output to be expected:
0 http://www.fakeurl.com
Video Chat Software
Actual output:
campDetails http://www.fakeurl.com
Video Chat Software
EDIT: Thank you for your answers everyone. It seems I was given incorrect information from another question on here. I was told that $i would keep a numerical index for the current iteration.
print_r($xml); (obviously more results but this is the first)
SimpleXMLElement Object ( [campDetails] => Array ( [0] => SimpleXMLElement Object ( [campaign_id] => 2001 [campaign_name] => Video Chat Software [url] => http://www.fakeurl.com/ )

simplexml_load_file returns an object, a foreach loop will iterate over its fields, and $i will hold the current field's key.
If you want a numeric counter as well, just increment on your own:
$j = 0;
foreach($xml as $i => $offer){
// do your stuff
$j++;
}

Its a bit redundant, but you can use something like:
$x = 0;
foreach($xml as $i => $offers):
// other stuff
echo $x . " " . $offer_link; ?> </br> <?php echo $offer_raw_name;
$x++;
endforeach;
You can also streamline your echo line like so:
echo "$i $offer_link <br> $offer_raw_name";

In this usage of foreach, $i is not a numeric index but a key. In this case, the key for the current object is campDetails.
Alternative Code
$i = 0;
foreach($xml as $offer) {
// your code...
++$i;
}
For more details on the type of object you receive from simplexml_load read the docs or debug with print_r($xml);.

Your $i is not an index. You could do something like:
$index = 0;
foreach($xml as $i => $offers):
$offer_link = $offers->url;
$offer_raw_name = $offers->campaign_name;
echo $index++ . " " . $offer_link; ?> </br> <?php echo $offer_raw_name;
endforeach;

Instead of using the current foreach and associative array, I pushed all values to an indexed array.

Related

Get input avg(example:2,4,3) to find the average

I'm trying to figure out how if the user input like : avg(2,3,6,1)
and then the server will respond with the answer which is : Average of (2,3,6,1) is 3.
Here is my simple work and got stuck about the next implementation.
if($r['$msg']="avg(".$i")"){ //if message is avg(2,3,6,1)
$i = array($i);
$avg = array_sum($i) / count($i);
echo "<div class='msg'>Server : $avg</div>";
How to make it works? Sorry for the 'noob' code.
You can do it with explode function in php. Convert the String to array. Check the below code, it will helps.
In your code $i = array($i); will output like Array ( [0] => 2,3,6,1 )
instead of creating 1-D array, you are creating 2-D array.
$i = "2,3,6,1";
//$r['$msg'] = "avg(".$i.")";
$i= explode(",",$i);
//$i = array($i);
print_r($i);
$avg = array_sum($i) / count($i);
echo "<div class='msg'>Server : </div>";
echo $avg;

How to access elements inside MultiDimensional Array in php

How to access all the elements under each key of multidimensional array.
$multi = array
(
"Abhishek" => array("Choudhary", "Bunta", "Popy"),
"Bond" => array("One", "two", "three", "four"),
"Super" => array("T1", "T2")
);
$data = array("Abhishek","Bond","Super");
for($j = 0;$j<count($data);$j++)
{
echo "<br/>Main Array Value ".$data[$j]."<br/>";
for($i = 0;$i<count($data[$j]);$i++)
{
echo "sub Value ".$multi[$data[$j]][$i]." count ".count($data[$j]) ;
}
}
Now I want to iterate through each element of Abhishek , Bond and Super , so we can see Abhishek has 3 elements inside it but $data[$j] always return 1. If I increment then I can access Bunta
Currently the output is -
Main Array Value Abhishek
sub Value Bunta
Main Array Value Bond
sub Value two
Main Array Value Super
sub Value T2
and expected is:
**
Main Array Value Abhishek
sub Value choudhary
sub Value Bunta
sub Value Popy
:
:
Main Array Value Bond
sub Value two
Main Array Value Super
sub Value T2
**
Disclaimer : I am super new to PHP so may be my expectation can be invalid or I am missing some very silly thing.
i recommend you read some articles about multidim arrays, anyway your needs could be done with following code:
foreach($multi as $key => $value) {
echo "<br/>Main Array Value ".$key."<br/>";
for($i = 0; $i < sizeof($value); $i++) {
echo "sub Value ".$value[$i]." count ".sizeof($value) ;
}
}
PS: you don't need $data array
#bunta please check this out: PHP Foreach
You could use foreach instead.
Also:
PHP foreach loop through multidimensional array
HTH.
Using foreach() would be easier
foreach ($multi as $key => $subarray)
{
echo $key . '<br />';
foreach ($subarray as $subvalue)
{
echo ' - '.$subvalue . '<br />';
}
}
Will output
Abhishek
- Choudhary
- Bunta
- Popy
Bond
- One
- two
- three
- four
Super
- T1
- T2
Try this :
<?php
foreach($multi as $key => $value) {
echo "<br/>Parent Value ".$key."<br/>";
for($i = 0; $ < sizeof($value); $++) {
echo "Child Value ".$value[$i]." count ".sizeof($value) ;
}
}
?>
You are using wrong syntax to access it.
Thanks
All you need is use foreach to iterate on $multi array (if you just want to know the number of subelements for each element level 1):
<?php
echo "<br\>multiDimensional Array<br\>";
$multi = array("Abhishek" =>array
("Choudhary",
"Bunta",
"Popy"),
"Bond" => array
("One",
"two",
"three",
"four"),
"Super" => array
("T1",
"T2")
);
foreach( $multi as $value ){
echo " count ".count($value) ;
}

How to add variables that are passed on through the URL to an array?

<?php
$i = $_GET['i'];
echo $i;
$values = array();
while ($i > 0)
{
$expense = $_GET['expense_' + i];
$amount = $_GET['amount_' + i];
$values[$expense] = $amount;
i--;
print_r($values);
}
?>
i represents the number of sets of variables I have that have been passed through from the previous page. What I'm trying to do is add the expenses to the amounts and put them in an array as (lets just say for this example there were 3 expenses and 3 amounts) [expense_3 => amount_3, expense_2 => amount_2, expense_1 => amount_1]. The names of the variables are successfully passed through via the url as amount_1=50, amount_2=50, expense_1=food, expense2=gas, etc... as well as $i, I just dont know how to add those variables to an array each time.
Right now with this code I'm getting
4
Array ( [] => ) Array ( [] => ) Array ( [] => ) Array ( [] => )
I apologize if I'm not being clear enough, but I am pretty inexperienced with PHP.
The syntax error you're getting is because you're using i instead of $i - however - that can be resolved easily.
What you're looking to do is "simple" and can be accomplished with string-concatenation. It looks like you're attempting this with $_GET['expense'] + i, but not quite correct.
To properly build the parameter name, you'll want something like $_GET['expense_' . $i], here you can see to concatenate strings you use the . operator - not the + one.
I'm going to switch your logic to use a for loop instead of a while loop for my example:
$values = array();
for ($i = $_GET['i']; $i > 0; $i--) {
$expense = $_GET['expense_' . $i];
$amount = $_GET['amount_' . $i];
$values[$expense] = $amount;
}
print_r($values);
This is following your original logic, but it will effectively reverse the variables (counting from $i down to 1). If you want to count up, you can change your for loop to:
$numVariables = $_GET['i'];
for ($index = 1; $index <= $numVariables; $index++) {
$expense = $_GET['expense_' . $index];
...
Or just serialize the array and pass it to the next site, where you unserialize the array
would be much easier ;)

How to count order number of values in an array?

I have an array with a few values and want to do something like this:
$arrayvalues = array_reverse(explode(', ', somefunction()));
foreach ( $arrayvalues as $arrayvalue ) :
printf('<li class="'.$countvalue.'">'.$arrayvalue.'</li>');
endforeach;
I want to have in $countvalue the number of the value in the array
ie... the array will be something like this: ("apple", "orange", "grapefruit")
I want the number to match the order number of these values
apple = 1, orange = 2, grapefruit = 3
or actually even if it's just an incremental number according to the values echoed it doesn't matter, I just need to insert a css class represented by an incremembtal number
I tried playing $i... count... but I don't know how to achieve what I want; I'm more a designer than a coder, I looked in the PHP help but couldn't find a clear solution for my case
thank you
You already have an incremental number based on order. Keep in mind, this only works if your key's are 0-based. If you use an associative array you will need to use a for loop instead (as suggested by nickb).
$arrayvalues = array_reverse(explode(', ', somefunction()));
foreach ( $arrayvalues as $key => $arrayvalue ){
echo "<li class='$key'>$arrayvalue</li>";
}
$arrayvalues = array_reverse(explode(', ', somefunction()));
$i = 0;
foreach ( $arrayvalues as $arrayvalue )
{
$i++;
printf('<li class="'.$i.'">'.$arrayvalue.'</li>');
}
Use a for loop to iterate over your array, like so:
for( $i = 0, $j = count( $arrayvalues); $i < $j; $i++) :
printf('<li class="' . ($i + 1) . '">' . $arrayvalues[$i] . '</li>');
endfor;
If you want the index $i to start at one, you need to add one in the printf statement.
Side note: You don't need printf here if you're not actually generating formatted output.
$arrayvalues = array_reverse(explode(', ', somefunction()));
$i=0;
foreach ( $arrayvalues as $arrayvalue ) :
++$i;
$countvalue = $i;
printf('<li class="'.$countvalue.'">'.$arrayvalue.'</li>');
endforeach;
We (or I) advise you use a normal for loop.
for($i = 0; $i < count($arrayvalues); $i++) {
printf('<li class="'.($i+1).'">'.$arrayvalue.'</li>');
}

associative array pointers / traversing associative array

Does next() and prev() work on associative arrays?
I'm trying to traverse through a dataset that uses two records to describe one "game" if you will. So when I'm on the second record w/ matching id i need to look at the record before and grab eg_item['final_score'].
{"id":"75", "team_name":"TEAM1", "home_team_name":"TEAM1", "image":"TEAM1_HOME.png", "final_score":"37"},
{"id":"75", "team_name":"TEAM2", "home_team_name":"TEAM2", "image":"TEAM2_AWAY.png", "final_score":"10"},
{"id":"76", "team_name":"TEAM1", "home_team_name":"TEAM1", "image":"TEAM1_HOME.png", "final_score":"10"},
{"id":"76", "team_name":"TEAM2", "home_team_name":"TEAM2", "image":"TEAM2_AWAY.png", "final_score":"14"},
All of the examples I'm finding use lame array('one','two',three') type examples that just don't help.
code sample:
foreach( $json_output as $eg_item ) :
if( $this_game_id == $last_game_id ) :
// get this records info
$b_score = $eg_item['final_score'];
$b_team_name = $eg_item['team_name'];
prev( $json_output );
// get previous records info
$a_score = $eg_item['final_score'];
$a_team_name = $eg_item['team_name'];
$a_game_id = $eg_item['id'];
// put pointer back
next( $json_output );
else :
// skip next record
endif;
endforeach;
That looks like an array of associative arrays, right? If so, loop through them by index 2 at a time, then you can look at the current inner array and the previous inner array in each iteration of the loop:
for ($i = 1; $i < count($array); $i+= 2) {
$current = $array[$i];
$last = $array[$i-1];
//$current['final_score'], $last['final_score'], etc
}
Yes they work just fine, heres a small test case i have done:
<?php
$sample = array(
"first" => Array("a","d","c"),
"second" => Array("a","d","c"),
"third" => Array("a","d","c"),
"fourth" => Array("a","d","c")
);
while(next($sample))
{
$item = current($sample);
echo key($sample) . "\n";
if(is_array($item))
{
echo "\t" . current($item) . "\n";
while(next($item))
{
echo "\t" . current($item) . "\n";
}
}
}
?>
output: http://codepad.org/2ZeqzWcx

Categories