If , Else If need assistance please


#1

Hi guys

Trying to display stars with the below code, my If and elseif is causing me endless frustration.
it needs to display the number of stars that the $starNumber variable is. if i do it one by one without IF`s and Else Ifs it works perfectly but with the below code it always will just give me 1 star.
any help with the logic will be highly appreciated.

<?php
  if($starNumber == 0){
       echo '<span class="stars-container stars-0">★★★★★</span>'; //0 stars
  }elseif($starNumber > 1 || $starNumber < 2 ) {
     echo '<span class="stars-container stars-20">★★★★★</span>'; //1 star
  }elseif($starNumber > 2 || $starNumber <3){
      echo '<span class="stars-container stars-40">★★★★★</span>'; //2 stars
  }elseif($starNumber > 3 || $starNumber < 4){
      echo '<span class="stars-container stars-60">★★★★★</span>'; //4 stars
  } 
 ?>

#2

If you’re using integers, this sounds like an excellent case for a switch statement…

Also, consider this:
$starNumber > 1 || $starNumber < 2 )…

($starNumber > 2 || $starNumber <3)

What happens if the number is EXACTLY 2? Which of your cases matches? (EDIT: Actually, it does catch, but it shouldnt

Let’s try cleaning this up a bit at least. We need to redefine our cases.

Your cases currently are:
Number = 0
Number > 1 OR Number < 2
Number > 2 OR Number < 3
Number > 3 OR Number < 4

There’s some gaps here, and some massive overlaps.

Lets consider your second condition: Number > 1 OR Number < 2.

Welll… every number greater than 1 makes the first half of the condition True.
every number less than 2 makes the second half of the condition True.

Consider 0.5.
It’s not greater than 1. So False.
If IS less than 2. So True.
False OR True = True. So 0.5 is a 1 star.

Consider -50
It’s not greater than 1. So False.
It IS less than 2. So True.
False OR True = True. So -50 is a 1 star.

Consider 100
It’s IS greater than 1. So True.
It is not less than 2. So False.
True OR False = True. So 100 is a 1 star.

So… EVERYTHING that isnt 0, will be a 1 star in your system.

What do we change?

Well, we can start by making the OR’s into AND’s. That will solve the huge over-steps, because True AND False is False.

Our next step is to include the lower boundary in the logic; namely a 1 should be a 1-star, so we dont want to look for things that are greater than 1, we want to look for things that are greater than or equal to 1.

Our next step is to determine than 0-star scores actually account for anything less than 1, and not just 0.

The fourth step is a logical flow connection of if-elseif-else statements.

if the score is 2.5, we start at the beginning of the if
if (score < 1) {....} It’s not less than 1, so we move to the next elseif.
elseif (score >= 1 && score < 2) perfectly valid line, but here’s the thing: We already KNOW it’s not < 1, or we wouldnt have gotten here. So the first bit is actually redundant; everything that is not < 1, is >= 1. So we only actually need to test elseif (score < 2).


#3

Thanks alot for this in depth explanation, i will get started on it now , will let you know how it goes.

Logic is a funny thing :slight_smile:


#4

That looks like a lot of redundant code for just assigning a class-name. Why don’t you just round($starNumber) and validate it

<?php

$starNumbers = [0, .3, .4, .5, 1, 1.3, 1.4, 1.5, 1.99, 2, 3, 4, 5, 6 ,7];

foreach($starNumbers as $starNumber){
    $number = round($starNumber);
    switch(true){
        case $number < 1:
            $class = 'a';
            break;
        case $number < 2:
            $class = 'b';
            break;
        case $number < 3:
            $class = 'c';
            break;
        case $number < 4:
            $class = 'd';
            break;
        case $number < 5:
            $class = 'e';
            break;
		default:
            $class = 'f';
    }
    echo $class, "\n";
}

#5

(Why would you have <'s if you’ve rounded the number to an integer?)


#6

Thanks all who helped. it is working perfectly even for my 1s, 2.s,3s, etc and even my half stars.

i will still need to carefully go through my logic to make sure i grasp the IF ELSE and Cases. the small things in life always the hardest

:):grinning:


#7

oh yes, that would make the checks obsolete.


#8
 $starNumber = 3;
 if ($starNumber == 0) {echo '<span class="stars-container stars-0">No Start</span>';}
 elseif ($starNumber >= 1 && $starNumber < 2) { echo '<span class="stars-container stars-20">one ★</span>';}
 elseif ($starNumber >= 2 && $starNumber < 3) { echo '<span class="stars-container stars-40">Two ★★</span>';}
 elseif ($starNumber >= 3 && $starNumber < 4) { echo '<span class="stars-container stars-60">Three ★★★</span>';}
 else {echo "Other Case";}
 ?>

#9

Indeed, or round the number, validate it, then call your classes “star1”, “star2” and so on.


#10

Or use a whitelist

$classes = [0 => 'star0', 1 => 'star1', ... ]

with a default value via caoalesce ?? operator.

Or you just append the rating-number to your class and handle it via CSS.


#11

Gentlemen, you all are over complicating a simple task. This can be very simply done with HTML and CSS (& 1 dynamic value) and will handle any fraction of a star all the way to complete stars. Simply set the % accordingly. In this example it will show 2.5 stars (50% of 5 stars). 1 full star = 40%, 2 stars=60%, 3 stars=80%…

<style type="text/css">
 .containerdiv {
  border: 0;
  float: left;
  position: relative;
  width: 300px;
}
.cornerimage {
  border: 0;
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
 }
 img{
   max-width: 300px;
 }
</style>

<div class="containerdiv">
    <div>
    <img src="https://image.ibb.co/jpMUXa/stars_blank.png" alt="img">
    </div>
    <div class="cornerimage" style="width:50%;">
    <img src="https://image.ibb.co/caxgdF/stars_full.png" alt="">
    </div>
</div>