PHP ELSE IF statement - php

unable to get my else if statement to work, does anyone have any ideas? it works without the else if....
$waveFeet = round("$ar2");
if ($waveFeet >= 2) {
echo $waveFeet - 1;
}
else if ($waveFeet > 5) {
echo $waveFeet - 2;
}
else
{
echo "$wavefeet";
}
also as a side question, can anyone tell me how to change my round() to make it always round (down) instead of rounding up or down...?

Using the third argument of round you can round it down
echo $waveFeet = round($ar2, 2, PHP_ROUND_HALF_DOWN);
and for your if your else if condition will never got true as if the $waveFeet is greater than or equal to 2, the first condition will be true hence your elseif condition will never be true.
You should be changing it to
if ($waveFeet > 5) {
echo $waveFeet - 1;
}
else if ($waveFeet >= 2) {
echo $waveFeet - 2;
}
else
{
echo $wavefeet;
}

Try the statement with a particular value, say $waveFeet = 10;, then step through the code. The first condition succeeds, so the later branches are never checked. In fact, the only time the first branch isn't entered is when $waveFeet < 2, in which case the last branch body will be executed. Thus the middle branch is never executed. The more exclusive case should come first:
if (5 < $waveFeet) {
...
} elseif (2 <= $waveFeet) {
...
} else {
# $waveFeet < 2
...
}
To be completely safe, you can specify both boundary conditions:
...
} elseif (2 <= $waveFeet && $waveFeet <= 5) {
...
The inefficiency due to redundancy is minimal and the code is clearer. As you get more experienced, you can leave off this sort of thing.
If you wish to round even negative numbers down, use floor. If you wish to round towards zero (i.e. truncate), cast to an int:
$waveFeet = (int) $ar2;

you can use floor for down round
$waveFeet = floor($ar2);
if ($waveFeet > 5)
echo $waveFeet - 2;
else if ($waveFeet >= 2)
echo $waveFeet - 1;
else
echo $wavefeet;
you have to first check for 5 bcz 5 is big no than 2 and your first condition >= 2 also satisfied if no >5 so control go to first condition rather than second....

Theres nothing wrong in your code ( except that you can pass argument to function without quotes ). The way you are checking it is wrong.
it wont go to else if condition because the condition will be satisfied in the first check itself .

PHP buil-in floor() and ceil() functions round a number down and up respectively. I recommend posting the error you get so we can help you faster =)
Try this:
$waveFeet = floor($ar2);
if ($waveFeet >= 2 && $waveFeet <= 5 ) {
echo $waveFeet - 1;
} else if ($waveFeet > 5) {
echo $waveFeet - 2;
} else {
echo $wavefeet;
}
Note the change in the first condition (added && $waveFeet <= 5)
I think the problem might be that the ranges you use in your first and second conditions are overlapped, and it is very likely that in the case, let's say, $waveFeet == 6 PHP evaluates your first condition (originally $waveFeet >= 2), and it happened to be true, so PHP does not test the else if statement... Whenever it's possible to use disjunct conditions, I recommend you to do it...

Related

Security of a simple numerical comparison

Ok I'm feeling like I'm going back not forward, can't even figure out by myself if a simple if statement is secure or not...
First of all let's say we get a variable from url GET method :
$my_number = $_GET['numb'];
Now we make this simple if statement:
if(($my_number >= 1) && ($my_number <= 12))
{
put $my_number in database without escaping it
}
So the question would be - Can user pass this if condition with something else besides 1-12, I mean using hex numbers, commenting, doing that kind of stuff?
To validate a number use intval()
$my_number = intval($_GET['numb']);
Nothing but a number will be allowed.
This will also insure the value will not create an error in the SQL.
I do not like >= or <=
if(($my_number >= 1) && ($my_number <= 12))
Change to:
if(($my_number > 0) && ($my_number < 13))
Your code is not fully secured. User can pass this if condition with something else besides 1-12.
You can test that with this simple code:
<?php
$my_number = $_GET['numb'];
if(is_numeric($my_number)){
if(($my_number >= 1) && ($my_number <= 12))
{
echo'User Can Pass';
}else{
echo'User Can Not Pass';
}
}else{
echo'User Can Not Pass';
}
?>
Now browse your site like http://example.com/?numb=8 or http://example.com/?numb=15 or http://example.com/?numb=7 Samurai
I think now you can find your answer. Thanks.

php: is valid to use if/else in this way?

Is there a way to optimize something like this?
I have already tried and it doesn't work (at least in php)
$foo = 6;
if ($foo != (3 or 5 or 10)) echo "it work";
elseif($foo < (5 or 10)) echo "it work again";
else echo "it doesn't work;"
I want to know if there's a better way to write that kind of validations.
But if something like this work in other langs, please let me know.
EDIT:
answer for this
($foo != (3 or 5 or 10)) -> in_array($foo,array(3,5,10))
does the same work if i want something like
($foo != (3 and 5 and 10))
No. It's not. You're testing your $foo value against the BOOLEAN result of those or operations. It'll boil down to
if ($foo != (true or true or true))
which is simply
if ($foo != true)
if (!$foo)
If you want to test a single value against multiple values, you can try
if(!in_array($foo, array(3,5,10))) { ... }
instead. For your < version, this won't work. You'll have to test each value individually:
if (($foo < 5) or ($foo < 10)) { ... }
though technically this is somewhat redundant, since if $foo is less than 5, it's already less than 10.
For the first you can use
if(!in_array($foo, [5,10,15]))
The second thing doesn't work in any language cause less then 5 or 10 is true for every thing less than 10. So no need for the 5. But I get your point. I don't know a fast way doing this
In python you can do this:
if(5 < x < 10)
a, b = b, a // swapping these two
I agree with the other answers and also, if you have more processing to do, you could also do something like this:
<?php
$x = 3;
switch ($x)
{
case 6:
$x = 5;
case 3:
case 7:
$x = 5;
case 5:
echo 'It is working' . PHP_EOL;
break;
}
EDIT: Thanks DanFromGermany for pointing the stacked cases. Added them as an example.

php if-else failing

What is wrong with this if-else statement.
if((strlen($objectData['pss'] >= 8))AND(strlen($objectData['pss'] <= 20)))
{
//do my bidding
}
else
{
echo "String to short or to long";
}
Ultimately I am trying to find if the variable is greater than or equal to 8 chars while being under or equal to 20 chars. My test string is 11 char, and I am seeing string to short/to long. I've done similar to this in the past, so I dunno what I mucked up at the moment (maybe Im just to tired to realize it)
if (strlen($objectData['pss']) >= 8 && strlen($objectData['pss']) <= 20)
if ((strlen($objectData['pss']) >= 8) and (strlen($objectData['pss']) <= 20))
{
//do my bidding
}
else
{
echo "String to short or to long";
}
I have corrected you brackets
Yes you are indeed "to tired".. You are basically counting the length of an expression instead of the string itself:
if((strlen($objectData['pss']) >= 8)AND(strlen($objectData['pss']) <= 20))

How to accomplish this if then statement with less repetition?

I have something simple I'm trying to accomplish with less repetition.
By default, I want a div to be shown, however if $x == 1, then check to see if $y != 1, and if $y doesn't, then don't show the block.
However the best I can come up with is the following:
if($x) {
if($y != 1) {
echo '<div>display block</div>';
}
} else {
echo '<div>display block</div>';
}
This seems a bit repetitive.
I know I can tweak it a bit and do something like:
$displayBlock = '<div>display block</div>';
if($x) {
if($y != 1) {
echo $displayBlock;
}
} else {
echo $displayBlock;
}
But even still, I have a feeling that there is a way to do this whole if if else thing which I can't see right now.
How do you accomplish the above with less if statements? So: if $x != 1 (default), then show the displayBlock. if $x == 1, and $y != 1, then show the display block. If $x == 1 && $y == 1, then do not show the displayBlock.
if (!$x || $y != 1) echo $displayBlock;
+1 to zerkms's answer - it's on the money. To help you solve problems like this in the future, it might be handy to look at truth tables Karnaugh maps.
You essentially have two checks:
a) $x (coerced to true or false)
b) $y != 1
$y != 1
T F
$x T 1 0
F 1 1
So, from that you can see that if $x is falsey, or $y != 1 is true, then you should show the display block, hence:
if (!$x || $y != 1) echo $displayBlock;
In order to keep the amount of code down, you could use a more mathematical approach rather than logic; e.g.
<?php
if($x+$y != 2){echo $displayBlock;}
?>
The display box only stays off when the sum of x and y equals 2.
Check these out. http://www.php.net/manual/en/language.operators.logical.php
$displayBlock = '<div>display block</div>';
if((($x) && ($y != 1)) || (!$x)) {
echo $displayBlock;
}
How did we come to this solution?
Look at your statement, and dissect it logically:
If x is true ... and ... y is 1... then print.
Which brings us to:
(($x) && ($y != 1))
See? X is truth AND y is one. That brigns you down to
if (($x) && ($y != 1)) {
//Do that thing
} else {
if (! $x) {
//Do that thing
}
}
Which we can write simply as...
if (($x) && ($y != 1)) {
//Do that thing
} else { if (! $x) {
//Do that thing
}
Okay, so what's this say?
If conditionA do something, or if condition B do something.
Oh, there's an OR.
So, condtion A || condition B
Which of course, brings us back to...
if((($x) && ($y != 1)) || (!$x)) {
I put in more braces than required in there so you can see the flow of things.

PHP, Generating Primes, What's Wrong

What's wrong with this? The conditional statement looks solid enough, yet all numbers are included
function generate_primes(){
$max = 100;
$primes = array();
for($current_pointer = 1; $current_pointer <= $max; $current_pointer++){
for($divider = 1; $divider <= $current_pointer; $divider++){
//if(in_array($divider, $primes)){
if(($current_pointer % $divider === 0) && ($divider !== 1) && ($divider === $current_pointer)){
$primes[] = $current_pointer;
}
//}
}
}
print_r($primes);
}
generate_primes();
You need to deal with the case that your divider does divide evenly into your current_pointer but the divider doesn't equal the current pointer. In that case, you need to jump out of the loop (i.e. you've found something that divides evenly, so the number isn't prime). As written, all loops eventually hit the case of dividing the number by itself, so all numbers succeed.
In other words, you're trying to test for the FIRST successful divider being the number itself, but to do that, you have to stop trying when you hit a different successful divider.
if(($current_pointer % $divider === 0) && ($divider !== 1)){
if ($divider === $current_pointer)
$primes[] = $current_pointer;
} else {
continue; // the continue makes you stop testing the current pointer and go on to the next
}
Re-think your algorithm. A prime number is a natural number > 1 that is not evenly divisible by any other natural number except itself and 1. So, if $current_pointer % $divider === 0, the number in question can't be a prime number, becauseit is divisible by $divider. So why do you add it to the array?
Edit in response to comments: To clarify, this means that you have to check for all possible divisors (from 2 to the number itself -1) and make sure that not a single of them divides the number in question without a remainder. In and only this case the number is a prime.
You can optimize this algorithm slightly (i.e. the root of your number can be the upper bound for the inner loop), but first try to get things working in the basic case.
I believe your last condition should be:
$divider !== $current_pointer
Two wrong things: 1) $divider === $current_pointer) should be $divider != $current_pointer) and 2) you are adding the number to the $primes array after each and every iteration.
Suggestions: 1) start the second loop by 2, since you want $divider not to be 1 in the first place, and 2) make $divider < $current_pointer (instead of <=), since you also want $divider not to be itself.
Try this:
function generate_primes(){
$max = 100;
$primes = array();
for($current_pointer = 1; $current_pointer <= $max; $current_pointer++){
$prime = true;
for($divider = 2; $divider < $current_pointer; $divider++){
if($current_pointer % $divider == 0) $prime = false;
}
if($prime == true) array_push($primes, $current_pointer);
}
print_r($primes);
}
generate_primes();
First off, your loop is a bit funny ;) If you want to exclude 1, don't start with 1
Second, I don't understand the last clause of your conditional. You are saying you will only consider it a prime if the divider is === to current pointer. I think you mean != to current pointer.
Look at your if statement. It essentially says:
Mark a number as prime if:
current_pointer equals 0.
divider doesn't equal 0.
divider equals current_pointer.
The only time all 3 of those conditionals will be true is when the final conditional is true (divider equals current_pointer.)
If the current pointer is 6, then when the divider equals 6, you'll store it as a prime (obviously not true.)
See this example as a simple (although expensive implementation) function for testing if a number is prime (you could easily use the logic to make a generator.)
Prime number checker
I'd suggest you look up the Sieve of Eratosthene algorithm. It's for getting a list of primes, and is very fast compared to the brute force approach you are taking. While your code will run fine for smaller numbers, you'll find as you try to, for example, get all primes < 10,000,000 it will take a long time.
The problem is that
if( ($current_pointer % $divider === 0) &&
($divider !== 1) &&
($divider === $current_pointer)){
will always be true when $divider == $current_pointer
A better approach is to use a is_prime flag initiated to true. Set it to false if any number smaller than it divides it.
A further enhancement would be to add the number two, and then only check non even numbers.
function generate_primes($max = 100){
$primes = array(2);
for($current_pointer = 3; $current_pointer <= $max; $current_pointer += 2){
if(is_odd_number_a_prime($current_pointer)){
$primes[] = $current_pointer;
}
print_r($primes);
return $primes
}
function is_odd_number_a_prime($n){
if(is_int($n)){
for($divider = 3; $divider < $n; $divider +=2 ){
if($current_pointer % $n == 0){
return false;
}
}
}else{
return false;
}
return true;
}
$primes = generate_primes();
You could further enhance things by using a sieve.

Categories