PHP For Loop only running once - php

I have a for loop to cycle through and array, run a database query in relation to each element, then call a function that prints out something in relation to it. The array is 12 elements long but the for loop never gets past element 0. It doesn't error or fail it just doesn't do anything after the first element. I verified that by putting the echo $x; and echo $vendorsname[$x]; at the start of each loop cycle and sure enough it only ever echo's 0 out to the page.
$continuetill = count($vendorsname);
for ($x = 0; $x < $continuetill; $x++)
{
echo $x;
echo $vendorsname[$x];
$sql="SELECT low,mid,high,verlow,vermin,verhigh FROM vendors WHERE vendor = ".$x." ORDER BY id DESC LIMIT 1";
if ($result=mysqli_query($conn,$sql))
{
// Fetch one and one row
while ($row=mysqli_fetch_row($result))
{
$low = $row[0];
$mid = $row[1];
$high = $row[2];
$verlow = $row[3];
$vermid = $row[4];
$verhigh = $row[5];
if(($low > $mid) && ($low > $high))
{
likely295Message($vendorsname[$x]);
}
elseif (($high > $low) && ($high > $mid) && ($high < 15))
{
possibly300Message($vendorsname[$x]);
}
elseif (($high > $low) && ($high > $mid) && ($high >= 15))
{
likely300Message($vendorsname[$x]);
}
elseif (($mid > $low) && ($mid > $high))
{
likely296Message($vendorsname[$x]);
}else
{
unknownMessage($vendorsname[$x]);
}
if(($verlow != 0) || ($vermid != 0) || ($verhigh != 0))
{
if(($verlow > $vermid) && ($verlow > $verhigh))
{
verified295Message($vendorsname[$x]);
changeBackgroundBack($vendorsname[$x]);
changeImage($vendorsname[$x]);
}
elseif (($verhigh > $verlow) && ($verhigh > $vermid))
{
verified300($vendorsname[$x]);
changeBackground($vendorsname[$x]);
changeImage($vendorsname[$x]);
}
elseif (($vermid > $verlow) && ($vermid > $verhigh))
{
verified296($vendorsname[$x]);
changeBackgroundBack($vendorsname[$x]);
changeImage($vendorsname[$x]);
}
}
}
mysqli_free_result($result);
}
}

Make sure you have error displaying turned on. Add at the beginning of your script:
ini_set('display_errors', 1);
to make sure you don't have any errors.

Related

Can I have more than one while(!feof) loop in a program?

If I'm trying to display a table (which I've accomplished with a while loop) but also display a count underneath it. Do I add another while loop? Or a seperate for loop? How would I do that? I need to count the number of performances (Ive got that working) but it wont tally the number of performances in Asheville. How do I target that variable by itself?
> <?php print ("<h1>Upcoming Performances in 2015</h1>"); print
> ("<table border =\"1\">"); print("<tr><th align =
> \"left\">Date</th><th align = \"left\">Venue</th><th align =
> \"left\">City</th><th align = \"right\">Ticket Price</th></tr>");
>
> $count = 0; $ashevilleCount = 0; $eventFile =
> fopen("performances.txt", "r"); $schedule = fgets($eventFile);
>
>
> while(!feof($eventFile)) { list($date, $venue, $city, $ticketPrice) = explode(":", $schedule);
> print("<tr><td>$date</td>"); print("<td>$venue</td>"); print("<td>$city</td>"); print("<td>$ticketPrice</td>");
> $schedule = fgets($eventFile);
> }
>
> for($count = 1; $count <= 5; $count = $count + 1) { $total = fgets($eventFile); $count = $count + $total;
> }
> if ($city == Asheville)
> $ashevilleCount = $ashevilleCount + $count;
>
>
>
>
>
> fclose($eventFile);
> print ("</table>");
>
> print ( "<p class=\"alert\">Lower cost venues are marked with
> *</p>"); print ("<p>NUMBER OF PERFORMANCES: $count</p>"); print ("<p>NUMBER OF PERFORMANCES IN ASHEVILLE: $ashevilleCount</p>");
>
>
>
>
> ?>
You need to take a look at your if statements.
if($condition === true){
//executes if $condition is true
} elseif($condition === 1) {
//executes if $condition is 1
} elseif($condition === 2 || $condition === 3){
//executes if $condition is 2 OR condition is 3
} elseif($condition === 4 && $otherCondition !== "foo"){
//executes if $condition is 4 AND $otherCondition is NOT "foo"
} else {
//executes if no other statements are true
}
This piece of code:
elseif
($charType == human or dwarf and $goldSpent <= 10)
$supplyTokens = $_POST['supplyTokens'] + 10;
Needs to look like:
} elseif( ( $charType=="human" || $charType=="dwarf" ) && $goldSpent <= 10) {
$supplyTokens = $_POST['supplyTokens'] + 10;
}
Remember:
|| = "or"
&& = "and"
test != "test" - make sure your strings are enclosed in quotation marks
See:
http://php.net/manual/en/control-structures.if.php
http://php.net/manual/en/control-structures.elseif.php
http://php.net/manual/en/language.operators.comparison.php
Here's your code cleaned up. What was done:
Changed all the print() commands to concatenated echos.
Fixed the conditionals
You don't need to check for $goldSpent <= 10 in your elseifs as you have already checked that by not being in $goldSpent > 10
I personally prefer || and && as opposed to or and and
Added curly brackets {}
Thing to consider:
What would happen if any of those $_POST values are empty??
<?php
$charName = $_POST['charName'];
$charType = $_POST['charType'];
$healthTokens = $_POST['healthTokens'];
$expTokens = $_POST['expTokens'];
$supplyTokens = $_POST['supplyTokens'];
$goldSpent = $healthTokens / 10 + $expTokens / 2 + $supplyTokens / 25;
if ($goldSpent > 10) {
echo "<h1>HEY THERE, $charName!</h1>" .
"<p>YOU SPENT MORE GOLD THAN YOU HAVE!</p>" .
"<p>GO BACK AND TRY THAT AGAIN - YOU HAVE 10 GOLD PIECES..</p>";
} elseif ($charType == 'elf') {
$healthTokens = $_POST['healthTokens'] + 5;
} elseif ($charType == 'wizard') {
$expTokens = $_POST['expTokens'] + 2;
} elseif ($charType == 'human' || $charType == 'dwarf') {
$supplyTokens = $_POST['supplyTokens'] + 10;
}
$totalGold = 10;
$goldLeft = $totalGold - $goldSpent;
echo "<h1>You have created $charName the $charType!</h1>" .
"<p>$charName has <strong>$healthTokens</strong> health tokens," .
"<strong>$expTokens</strong> experience tokens, and" .
"<strong>$supplyTokens</strong> supply tokens.</p>" .
"<p>You received some bonus tokens! :)</p>" .
"<p>$charName has spent <strong>$goldSpent</strong> gold pieces, " .
"and has <strong>$goldLeft</strong> gold pieces left.</p>";

Why doesn't subtraction sign work on while loop in php?

<?php
$hp = 0;
while($hp < 50) {
$flip = rand(0,2);
if ($flip == 1) {
echo "<p>X-Ray</p>";
$hp += 15;
} elseif ($flip == 2) {
echo "<p>Special Move</p>";
$hp += 10;
} else {
echo "<p>Punch</p>";
$hp += 5;
}
echo "<p>Total so far: $hp</p>";
echo "</br>";
}
?>
This is a PHP code. When I run it, it works fine. However, when I change it to this code below it doesn't.
<?php
$hp = 50;
while($hp > 1) {
$flip = rand(0,2);
if ($flip == 1) {
echo "<p>X-Ray</p>";
$hp -= 15;
} elseif ($flip == 2) {
echo "<p>Special Move</p>";
$hp -= 10;
} else {
echo "<p>Punch</p>";
$hp -= 5;
}
echo "<p>Total so far: $hp</p>";
echo "</br>";
}
?>
Please help. tHE CHANGES I MADE ARE THE HIGHLIGHTED ONES.
You never created $hp properly in the second version:
50;
doesn't do anything. It just tells php "here, have a 50", and php goes "gee, thanks, ok, whatever" and moves onwards. Then you have
while($hp > 1) {
Since $hp is undefined, it's null, and the code parses/executes as:
while($hp > 1) {
while(null > 1) {
while(0 > 1) {
FALSE -> exit loop
You never created $hp properly in the second version:
50;
If you do change it to $hp = 50;

Why isn't count counting anything?

I'm having trouble making a simple count work. Right now 0 is constantly displayed when I run the code and I know it's because I set count to 0. But it should be displaying the number of times "Fizz" is displayed.
I'm sure it's simple but I just can't see what!
public function __construct($firstParam, $secondParam, $firstSound = "Fizz", $secondSound = "Buzz", $numbers = 100) {
$this->firstParam = $firstParam;
$this->secondParam = $secondParam;
$this->firstSound = $firstSound;
$this->secondSound = $secondSound;
$this->numbers = $numbers;
$this->numsArray = $numsArray;
}
public function __toString() {
$count = 0;
for ($i = 0; $i < count($this->numsArray); $i++){
$val = $this->numsArray[$i];
if ($val == $this->firstSound) {
$count++;
}
}
$print = "Number of Fizzes: ".$count;
return $print;
}
public function execute() {
$this->numsArray = array();
if ($this->secondParam > $this->firstParam) {
for ($i = 1; $i <= $this->numbers; $i++){
if ($i % $this->firstParam == 0 && $i % $this->secondParam == 0) {
$this->numsArray[] = "\n".$this->firstSound.$this->secondSound."\n";
} elseif ($i % $this->firstParam == 0) {
$this->numsArray[] = "\n".$this->firstSound."\n";
} elseif ($i % $this->secondParam == 0) {
$this->numsArray[] = "\n".$this->secondSound."\n";
} else {
$this->numsArray[] = "\n".$i."\n";
}
echo $this->numsArray[$i-1];
}
} else {
echo "\n".' First Number Bigger Than Second '."\n";
}
}
In your execute you are not assigning the values to numsArray[i] also you inject new line characters that will not match the equality you just when checking $val. Also I notice you use zero index to check them and index 1 to load it. Change execute to:
for ($i = 0; $i < $this->numbers; $i++){
if ($i % $this->firstParam == 0 && $i % $this->secondParam == 0) {
$this->numsArray[i] = $this->firstSound.$this->secondSound;
} elseif ($i % $this->firstParam == 0) {
$this->numsArray[i] = $this->firstSound;
} elseif ($i % $this->secondParam == 0) {
$this->numsArray[i] = $this->secondSound;
} else {
$this->numsArray[i] = $i;
}
echo $this->numsArray[$i];
This is a better binary string comparison for php...
if (strcmp($val, $this->firstSound) == 0)

Sorting arrays with uncertain data

I am crafting a script for a browser game that will generate a random animal for the player to battle with anywhere from 0-5 markings. The markings on that animal are randomly generated and are fed into a custom imagick function, which will add them in order as they appear in the array.
While the markings are randomly decided, there are a lot of rules to how they are supposed to appear on an animal, for instance markings in the "full body" region show above markings in the "belly" region. To better explain, I'll attach an image of the tester so far:
So to break down the 5 markings on this randomly generated animal, the eyeshadow marking belongs to eye region, undertail belongs to tail, streaks belongs to fullbody, appaloosa belongs to back, and okapi belongs to legs. The order right now is just added as the script looped through the database and randomly selected markings, so okapi (the stripes on the legs) is on top since it was the last on in the array, and the last one added. But following the order rules, the last one in the array should have been streaks (the horizontal streaks across the body), since fullbody markings go on top.
Here is the code the selects markings, this is done using the Laravel engine:
// Determine number of markings
$num = mt_rand(1,10);
if ($num == 1) {
$markingNum = 0;
} elseif ($num > 1 && $num < 4) {
$markingNum = 1;
} elseif ($num > 4 && $num < 6) {
$markingNum = 2;
} elseif ($num > 6 && $num < 8) {
$markingNum = 3;
} elseif ($num > 8 && $num < 10) {
$markingNum = 4;
} else {
$markingNum = 5;
}
// Calculate Marking type and color
$markings = array();
if ($markingNum > 0) {
for ($m = 0 ; $m < $markingNum; $m++) {
// Set color values (pulls from the "pallet" selected earlier in the code, which will determine the range of color that marking can be)
if ($m == 1) {
$pal = $pallet->marking1;
} elseif ($m == 2) {
$pal = $pallet->marking2;
} elseif ($m == 3) {
$pal = $pallet->marking3;
} elseif ($m == 4) {
$pal = $pallet->marking4;
} else {
$pal = $pallet->marking5;
}
// Pull previous marking info
if (count($markings) != 0) {
$previous = DataMarking::whereIn('name', array_keys($markings))->get();
// This pulls the regions of the current markings in the array so it won't select a region that already has a marking.
foreach ($previous as $p) {
$regions[$p->region] = $p->name;
}
// Uncommon marking (10% chance)
$r = mt_rand(1, 10);
if ($r == 10) {
$marking = DataMarking::where('rarity', 1)
->where('public', 1)
->whereNotIn('name', array_keys($markings))
->whereNotIn('region', array_keys($regions))
->orderByRaw("RAND()")
->first();
// Common markings
} else {
$marking = DataMarking::where('rarity', 0)
->where('public', 1)
->whereNotIn('name', array_keys($markings))
->whereNotIn('region', array_keys($regions))
->orderByRaw("RAND()")
->first();
}
// Colors marking
if ($pal == 0) {
$markingColor = rand_color();
} else {
$range = ColorRange::where('id', $pal)->firstOrFail();
$markingColor = "#" . mixRange(substr($range->start_hex, 1), substr($range->end_hex, 1));
}
$markings[$marking->name] = $markingColor;
} else {
// Uncommon marking (10% chance)
$r = mt_rand(1, 10);
if ($r == 10) {
$marking = DataMarking::where('rarity', 1)
->where('public', 1)
->orderByRaw("RAND()")->first();
// Common marking
} else {
$marking = DataMarking::where('rarity', 0)
->where('public', 1)
->orderByRaw("RAND()")->first();
}
// Colors marking
if ($pal == 0) {
$markingColor = rand_color();
} else {
$range = ColorRange::where('id', $pal)->firstOrFail();
$markingColor = "#" . mixRange(substr($range->start_hex, 1), substr($range->end_hex, 1));
}
$markings[$marking->name] = $markingColor;
}
}
}
I figure I can accomplish this with a lot of complex if statements but it just doesn't seem like an elegant solution to me. In addition, there is an exception: 'Gradient', a fullbody marking, goes underneath everything even though it is a full body marking. So far it is the only marking with this sort of exception to it, though.
I have tried using various sort functions offered by PHP but I am not having much luck. uksort seems the most promising, but since the value we are sorting by exists in the database and not in the array we are sorting (the imagick function has to be fed a marking => color array format), it's proving difficult to work with.
Tl;dr: I need to reorder an array that an uncertain amount of data based off of values that exist in the DB for the keys (the region for the markings). What's the most elegant way to accomplish this?
Here are some optimizations to your code, there are comments inline to describe what was done. This is obviously not finished as there are some things Marcin pointed out in his answer that would be better.
// Determine number of markings
$num = mt_rand(1,10);
// Removed redundent $num > X as the conditions were already meet that it was > X by the previous if statement
if ($num == 1) {
$markingNum = 0;
} else if ($num < 4) {
$markingNum = 1;
} else if ($num < 6) {
$markingNum = 2;
} else if ($num < 8) {
$markingNum = 3;
} else if ($num < 10) {
$markingNum = 4;
} else {
$markingNum = 5;
}
// Calculate Marking type and color
$markings = array();
if ($markingNum > 0) {
for ($m = 1 ; $m <= $markingNum; $m++) { // incrimented to 1 and <= so we can dynamically select elements
// Set color values (pulls from the "pallet" selected earlier in the code, which will determine the range of color that marking can be)
$pal = $pallet->{'marking' . $m}; // Removed if/else and replaced with a dynamic variable
// Uncommon marking (10% chance)
$r = mt_rand(1, 10);
// removed duplicate database selections for a simple $rarity variable that accomplishes the same task
if ($r == 10) {
$rarity = 1;
} else {
$rarity = 0;
}
$marking = DataMarking::where('rarity', $rarity)
->where('public', 1)
->whereNotIn('name', array_keys($markings))
->whereNotIn('region', $regions)
->orderByRaw("RAND()")
->first();
// Colors marking
if ($pal == 0) {
$markingColor = rand_color();
} else {
$range = ColorRange::where('id', $pal)->firstOrFail();
$markingColor = "#" . mixRange(substr($range->start_hex, 1), substr($range->end_hex, 1));
}
$markings[$marking->name] = $marking; // adds all of the marking data, this is where you could have a z-index in the database
$markings[$marking->name] = $markingColor; // add your color to your marking data
$regions[] = $marking->region;
}
}
I won't answer your question, but looking at your code there are a lot of space for improvements.
Consider this:
if ($m == 1) {
$pal = $pallet->marking1;
} elseif ($m == 2) {
$pal = $pallet->marking2;
} elseif ($m == 3) {
$pal = $pallet->marking3;
} elseif ($m == 4) {
$pal = $pallet->marking4;
} else {
$pal = $pallet->marking5;
}
It could be changed for something much simpler:
$pa1 = (in_array($m,range(1,4))) ? $pallet->marking{$m} : $pallet->marking5;
Same for:
if ($r == 10) {
$marking = DataMarking::where('rarity', 1)
->where('public', 1)
->whereNotIn('name', array_keys($markings))
->whereNotIn('region', array_keys($regions))
->orderByRaw("RAND()")
->first();
// Common markings
} else {
$marking = DataMarking::where('rarity', 0)
->where('public', 1)
->whereNotIn('name', array_keys($markings))
->whereNotIn('region', array_keys($regions))
->orderByRaw("RAND()")
->first();
}
if could be rewritten to:
$marking = DataMarking::where('rarity', ($r == 10) ? 1 : 0)
->where('public', 1)
->whereNotIn('name', array_keys($markings))
->whereNotIn('region', array_keys($regions))
->orderByRaw("RAND()")
->first();
Of course in above ORDER BY RAND() might be not the best solution because of performance reasons.
You should really care about amount of your code and duplication or you'll soon be lost in what you are doing

Wrong Standard Deviation result in PHP

I have a problem with calculating the standard deviation in php. But it's generating the wrong result.
e.g. I am getting as result for (4+4+4+4+4+4) = 1.40 instead of 0.
Please help.
function std_dev ($attr, $test1,$test2,$test3,$test4,$test5,$test6) {
//$items = array($test1->$attr,$test2->$attr,$test3->$attr,$test4->$attr,$test5->$attr,$test6->$attr);
$items[] = array();
if (isset($test1) && $test1->$attr != 9 && $test1->$attr != 0) {
$items[] = $test1->$attr;
}
if (isset($test2) && $test2->$attr != 9 && $test2->$attr != 0) {
$items[] = $test2->$attr;
}
if (isset($test3) && $test3->$attr != 9 && $test3->$attr != 0) {
$items[] = $test3->$attr;
}
if (isset($test4) && $test4->$attr != 9 && $test4->$attr != 0) {
$items[] = $test4->$attr;
}
if (isset($test5) && $test5->$attr != 9 && $test5->$attr != 0) {
$items[] = $test5->$attr;
}
if (isset($test6) && $test6->$attr != 9 && $test6->$attr != 0) {
$items[] = $test6->$attr;
}
$sample_square[] = array();
$item_count = count($items);
for ($current = 1; $item_count > $current; ++$current) $sample_square[$current] = pow($items[$current], 2);
$standard_deviation = sqrt(array_sum($sample_square) / $item_count - pow((array_sum($items) / $item_count), 2));
return round($standard_deviation,2);
}
$items = array();
$sample_square = array();
no [] when you define those variables as arrays.
for ($current = 0; $item_count > $current; ++$current)
start from 0 not 1 if you want to iterate over all the elements (otherwise you'll miss item at index 0)
Wondering what this is for...
if (isset($test1) && $test1->$attr != 9 && $test1->$attr != 0) {
$items[] = $test1->$attr;
}
and how you pass input values to the function. This may also cause wrong result...

Categories