Array scope within PHP foreach loop - php

I am learning PHP and have been agonizing over how to write my code properly. I have a textarea that accepts user input which is several lines of coordinates (PT# Northing Easting) separated by spaces.
I have the form pass the textarea input to a php script to handle it.
I can get a foreach loop to do exactly what I want but only local to the foreach loop, the variables do not get passed to the outside of the loop.
I know this is a global variable scope issue, for the life of me I can't resolve this...
Below is my PHP code, I left out the HTML form I have no issues with it and know the textarea is being passed properly.
**Sample data that I am inputing:
1 728258.24000 774337.29700
2 728232.15735 774277.54650
3 728326.39614 774216.82428**
<?php
$i = 0;
$j = 0;
//The code below explodes my textarea into a string array
//of separated lines.
$textArea = explode("\r", $_POST['textArea']);
$textNum = array();
//The code below works internally, but the values remain here
//I wanted to get them to the variables below so I can do work
//to them.
foreach ($textArea as $textRows) {
//The code below explode the lines into elements separated by a space
$textRow = explode(" ", $textRows);
foreach ($textRow as $textItem) {
$textNum[i][j] = $textItem;
//The code below works within a local context
echo "(" . $i . " " . $j . ")" . $textNum[i][j] . "</br>";
$j++;
}
$i++;
$j = 0;
}
//The code below is not receiving values from the foreach loop
//I know this has something to do with the variable scope
//I must be way off in my approach any help would be appreciated!
echo "</br>";
echo "</br> 0 0 " . $textNum[0][0];
echo "</br> 0 1 " . $textNum[0][1];
echo "</br> 0 2 " . $textNum[0][2];
echo "</br> 1 0 " . $textNum[1][0];
echo "</br> 1 1 " . $textNum[1][1];
echo "</br> 1 2 " . $textNum[1][2];
echo "</br> 2 0 " . $textNum[2][0];
echo "</br> 2 1 " . $textNum[2][1];
echo "</br> 2 2 " . $textNum[2][2];
echo "</br> 3 0 " . $textNum[3][0];
echo "</br> 3 1 " . $textNum[3][1];
echo "</br> 3 2 " . $textNum[3][2];
?>
I hope I have explained this well enough, and appreciate any help I can get! Thanks!

There is an error in your second loop:
$textNum[i][j] = $textItem;
have to be:
$textNum[$i][$j] = $textItem;

You, need to prepend $ before your variables, i.e $textNum[$i][$j] instead of $textNum[i][j], also, it's best to initialize $i and $j and set them to 0 before the foreach loop.

Related

simplexml loop, loop count good data bad

Trying my first simplexml loop
I have got to this:
foreach ($xml->GetCapabilityResponse->Srvs->Srv as $rows)
{
echo $xml->GetCapabilityResponse->Srvs->Srv->GlobalProductCode . " ";
echo $xml->GetCapabilityResponse->Srvs->Srv->MrkSrv->LocalProductCode . " " ;
echo $xml->GetCapabilityResponse->Srvs->Srv->MrkSrv->ProductShortName . "<br>";
}
It returns the correct amount of rows '6' but all 6 are the same data from the first row, how do I adjust to show the 6 different rows own data, it's not limited to 6, could be 12 or more etc
thanks
Mazz
so if $rows is an array, you should rely on the item you are processing
$row->GlobalProductCode . " ";

How a string of text every other two lines in a foreach loop in PHP? (retrieving records from a database)

I am working on a "boxing records" database for a school project. The loop retrieves records from a SQL statement. I want to add a "VS" string of text between every other two lines in order to show records outputted somewhat like this.
Upcoming Fights
Sergey Kovalev (28-0-25)
VS
Jean Pascal (30-3-17)
Another Boxer (123-0-5)
VS
Some Boxer (123-3-1)
However, my current loop outputs like this
Sergey Kovalev (28-0-25)
VS
Jean Pascal (30-3-17)
VS
Another Boxer (123-3-1)
VS
Some Other Boxer (123-3-1)
VS
The loop I currently have is the following
foreach($records as $record) {
$i = 0;
echo $record['name'] . " (" . $record['wins'] . "-" . $record['losses'] . "-" . $record['kos'] . ")" . "<br>";
$i=$i*2;
if($i%2 == 0)
{
echo "VS <br/>";
}
else{
echo "<br />";
}
I know I could probably change the SQL in order to display two fighters in the same row, and then append "vs" on the echo, but I thought that just modifying the for loop would work by using a variable counter $i. I thought it would be pretty easy to make the "VS" appear between every two rows but im missing something in my logic.
You need to increment value of $i by one rather than multiplying it by 2 and initialize $i outside foreach loop.
$i = 0; // Initialize counter here
foreach($records as $record) {
echo $record['name'] . " (" . $record['wins'] . "-" . $record['losses'] . "-" . $record['kos'] . ")" . "<br>";
if($i%2 == 0)
{
echo "VS <br/>";
}
else
{
echo "<br />";
}
$i++; // Increment counter here
}

Division with php

Im trying to get out an average value from a vote function.
<?php
$file = file("textfile.txt");
$textfil = file_get_contents("textfile.txt");
$textfill = str_split($textfil);
echo "Number of votes: " . count($textfill) . "<br>";
$sum = 0;
foreach ($textfill as $vote) {
$sum = $sum + intval($vote);
}
echo "Average: " . $sum;
?>
Simple by substitute (+) with a (/), and even tried a (%). But still getting error message.
Would appreciate alot if anyone could help me out and tell me what im doing wrong.
/thanks
Edit
Sidenote: Please read an explanation under "First answer given" further down below.
This version will take into account any blank lines in a file, if the content looks like:
1
2
3
// <- blank line
Sidenote: Please provide a sample of your text file. A comment has already been given to that effect.
PHP
<?php
// first line not required
// $file = file("textfile.txt");
$textfil = file_get_contents("textfile.txt");
$textfill = array_filter(array_map("trim", file("textfile.txt")), "strlen");
echo "Number of votes: " . count($textfill) . "<br>";
$sum = 0;
foreach ($textfill as $vote) {
$sum += intval($vote);
}
$avg = $sum / count($textfill);
echo "Average: " . $avg;
?>
First answer given
Using the following in a text file: (since no example of file content was given)
5
5
5
IMPORTANT NOTE: There should not be a carriage return after the last entry.
produced
Number of votes: 5
Average: 3
which is false, since there are 3 entries in the text file.
explode() should be used, and not str_split()
The following using the same text file produced:
Number of votes: 3
Average: 5
which is correct. In simple mathematics, averages are done by adding all numbers then dividing them by how many numbers there are.
In this case it's 3 numbers (all 5's) added equals 15, divided by 3 is 5.
Sidenote: The first line is not required $file = file("textfile2.txt");
<?php
// first line not required
// $file = file("textfile.txt");
$textfil = file_get_contents("textfile.txt");
$textfill = explode("\n", $textfil);
echo "Number of votes: " . count($textfill) . "<br>";
$sum = 0;
foreach ($textfill as $vote) {
$sum += intval($vote);
}
$avg = $sum / count($textfill);
echo "Average: " . $avg;
?>
Footnotes:
If the average comes out to 8.33333 and you would like it to be rounded off to 8, use:
echo "Average: " . floor($avg);
If the average comes out to 8.33333 and would like it to be as 9 you would use:
echo "Average: " . ceil($avg);
ceil() function
floor() function
You may be mixing in stuff that can't be divided, like text, etc. I don't know what your text file looks like. intval may be having a problem with arrays. You may try:
foreach ($textfill as $vote) {
if(is_int($vote) {
$sum += $vote;
}
}
echo "Average: " . $sum;
Lower school math says:
foreach ($textfill as $vote) {
$sum += intval($vote);
}
$avg = $sum / count($textfill);
The average value is calculated by divide the sum with the number of votes. This line will print the average value:
echo "Average: " . $sum/count($textfill);

combining arrays to get 3rd array value

I am doing a profile quiz. This is just an example of code. Ultimately I will do a loop for all possible combinations. Basically, if the student chooses answer 3 to question 1 (what is your height - small, medium, large, xl, xxl) I want their pgheight to be stored as 4, sgheight as 9, cheight as 4, etc... My final array will consist of 16 $pos and 16 $attr with 5 scores for each combination. Hope this makes sense. Thanks for any help.
e.g.
function height(){
$pos=array("pg","sg","c");
$attr=array("height","weight","strength");
$pgheight=array(1,2,3,4,5);
$sgheight=array(6,7,8,9,10);
$cheight=array(1,2,3,4,5);
$ans=3;
$i=0;
// THIS IS THE CODE THAT DOESN'T SEEM TO WORK.
// My logic is $pgheight=$pgheight[3];
$pos[$i].$attr[$i]=$pos[$i].$attr[$i]."[".$ans."]";
echo $pgheight;
}
you either want to eval the statement or use two dollar signs. you're reusing the variable pgheight so its a bit confusing. let me give you an example instead.
$fruit = array("apples", "oranges", "pears");
$drinks = array("beer", "cider", "wine");
$krislikes = "drinks";
$whichone = 0;
echo "Kris likes " . ${$krislikes}[$whichone] . "<br>";
// or
$answer = $$krislikes;
echo "Kris likes " . $answer[$whichone] . "<br>";
// or
eval('$the_answer=$' . $krislikes . '[' . $whichone . '];');
echo "Kris likes " . $the_answer . "<br>";
hope that helps.

MySQL/PHP mysql_fetch_array() keeps missing first row

Good eve everyone!
For some reason Database::fetchArray() is skipping the first $row of the query result set.
It prints all rows properly, only keeps missing out the first one for some reason, I assume there's something wrong with my fetchArray() function?
I ran the query in phpMyAdmin and it returned 4 rows, when I tried it on my localhost with the php file (code below) it only printed 3 rows, using the same 'WHERE tunes.riddim'-value ofcourse. Most similiar topics on google show that a common mistake is to use mysql_fetch_array() before the while(), which sets the pointer ahead and causes the missing of the first row, unfortunately I only have one mysql_fetch_array() call (the one within the while()-head).
<?php
$db->query("SELECT " .
"riddims.riddim AS riddim, " .
"riddims.image AS image, " .
"riddims.genre AS genre, " .
"tunes.label AS label, " .
"tunes.artist AS artist, " .
"tunes.tune AS tune, " .
"tunes.year AS year," .
"tunes.producer AS producer " .
"FROM tunes " .
"INNER JOIN riddims ON tunes.riddim = riddims.riddim " .
"WHERE tunes.riddim = '" . mysql_real_escape_string(String::plus2ws($_GET['riddim'])) . "'" .
"ORDER BY tunes.year ASC");
$ar = $db->fetchArray();
for($i = 0; $i < count($ar) - 1; $i++)
{
echo $ar[$i]['riddim'] . " - " . $ar[$i]['artist'] . " - " . $ar[$i]['tune'] . " - " . $ar[$i]['label'] . " - " . $ar[$i]['year'] . "<br>";
}
?>
Database::fetchArray() looks like:
public function fetchArray()
{
$ar = array();
while(($row = mysql_fetch_array($this->result)) != NULL)
$ar[] = $row;
return $ar;
}
Any suggestions appreciated!
You should remove -1 from the for loop
The problem's in your while loop:
for($i = 0; $i < count($ar) - 1; $i++)
if count ($ar) is 1, because there's one entry, your loop will never be called; try tweaking the check part:
for($i = 0; $i < count($ar) ; $i++)
You can also use a simple foreach:
foreach($db->fetchArray() as $row)
{
echo $row['riddim'] # ...
}
It'll make your code more readable too.

Categories