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

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.

Related

PHP: Use the short if-statement without else?

I'm a fan if the short if-version, example:
($thisVar == $thatVar ? doThis() : doThat());
I'd like to cut out the else-statement though, example:
($thisVar == $thatVar ? doThis());
However, it wont work. Is there any way to do it that I'm missing out?
You can't use it without the else. But you can try this:
($thisVar != $thatVar ?: doThis());
or
if ($thisVar == $thatVar) doThis();
The ternary operator is designed to yield one of two values. It's an expression, not a statement, and you shouldn't use it as a shorter alternative to if/else.
There is no way to leave out the : part: what value would the expression evaluate to if you did?
If you're calling methods with side effects, use if/else. Don't take short cuts. Readability is more important than saving a few characters.
hmm interesting, because executing the below code is valid. Observe:
for ($i = 1; $i <=10; $i++) {
if ($i % 2) {
echo $i;
}
}
The above code indeed, will output 13579
Notice no 'else' clause was used in the above.
If you wanted to inform the user of whether $i % 2 == FALSE ($i's divisor yielded remainder 0), you could include an else clause to print out the even numbers like shown below:
for ($i = 1; $i <=10; $i++) {
if ($i % 2) {
echo "$i is odd";
echo "<br />";
} else {
echo "$i is even";
echo "<br />";
}
}
Giving you the output:
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
10 is even
I hope my amazingly easy to understand examples will help all newcomers to PHP, hands down the 'best' server-side scripting language for building dynamic web applications :-)
USE NULL TO SKIP STATEMENTS WHEN IT IS IN SHORTHAND
$a == $b? $a = 10 : NULL;
Just use logical operators : AND, OR, &&, ||, etc.
($thisVar === $thatVar) && doThis();
a frequent use is :
$obj = doSomething($params) or throw new \Exception('Failed to do');
Working for me:
$leftHand != $rightHand?doThis():null;
$leftHand == $rightHand?null:doThis();

A way to summarize many commands like if... and if... do

I've created a question and answer page to determine the level of interest of each user for different products
like this:
how much u like x (betwin 1-10)
These questions are more than 30, and if I want to write a single command line for each possibilities, it's almost impossible.
the commands do like this:
if $a <=5 and $b <=6 and $c <=7 and... do ...
if $a<= 8 and $b <=7 and $c >= 5 and $d <=8 do...
I want the commands to work this way
Is there a better way to do this?
thanks
For this you could use a switch statement. Documentation: http://php.net/manual/en/control-structures.switch.php
Example code:
$i = 10;
switch($i):
case ($i <= 0): // or for example: case (0)
return 'It\'s 0 or lower than 0';
break;
case ($i > 0 && $i < 10):
return 'Number is between 0 and 10';
break;
case ($i >= 10):
return 'Number is 10 or higher';
break;
default:
return false;
endswitch;
// You can use echo instead of return, but i prefer to use these statements in a function instead of the html page.
More information about the differences between if and switch is provided by Masivuye Cokile as a comment in your question: Which is Faster and better, Switch Case or if else if?
I hope this helped. Let me know.

Understanding operator precedence in php

I have the following code in production that appears to be causing an infinite loop.
$z=1;
while (!$apns = $this->getApns($streamContext) && $z < 11)
{
myerror_log("unable to conncect to apple. sleep for 2 seconds and try again");
$z++;
sleep(2);
}
How are the precedence rules getting applied that cause this behavior?
http://php.net/manual/en/language.operators.precedence.php
I see this note in the docs:
Although = has a lower precedence than most other operators, PHP will
still allow expressions similar to the following: if (!$a = foo()), in
which case the return value of foo() is put into $a.
Which makes me think the the = should be evaluated first. then the ! then the &&, which would not cause an infinite loop.
Your code is evaluating like this:
while (!($apns = ($this->getApns($streamContext) && ($z < 11))))
which is why you see the infinite loop (as soon as $z >= 11, $apns is false, so the condition is always true). The reason for this precedence is that the special rules only apply to ! on the left of the assignment being valid (having lower precedence than =). It has no effect on the boolean operator on the right, which behaves as it would in any sane language.
Your style is bad. Try this, which is much more readable and only differs in the final value of $z (and if that's important you can tweak the break statement.
for( $z = 1; $z < 11; ++ $z ) {
// note extra brackets to make it clear that we intend to do assignment not comparison
if( ($apns = $this->getApns($streamContext)) ) {
break;
}
myerror_log("unable to conncect to apple. sleep for 2 seconds and try again");
sleep(2);
}
Your code is clear example of why it's good habit to always put all the conditions in brackets (and the same applies to code block. Even oneliners should be surrounded by { and }). So instead of error-prone:
while (!$apns = $this->getApns($streamContext) && $z < 11)
do
while (!($apns = $this->getApns($streamContext)) && ($z < 11))
and you will be safe.

PHP ELSE IF statement

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...

change a variable based on even/odd status of another variable?

for($i=0;$i<$num;$i++) {
if($i==even) $hilite="hilite";
dothing($i,$hilite);
}
This is basically what I want to accomplish.
What is the most efficient way to determine if $i is even?
I know I could check if half == mod 2 ... but that seems a little excessive on the calculations? Is there a simpler way?
if ($i % 2 == 0)
The already mentioned % 2 syntax is most used, and most readable for other programmers. If you really want to avoid an 'overhead' of calculations:
for($i = 0, $even = true; $i < $num; $i++, $even =! $even) {
if($even) $hilite = "hilite";
dothing($i,$hilite);
}
Although the assignment itself is probably more work then the '%2' (which is inherently just a bit-shift).
It doesn't get any simpler than $i % 2 == 0. Period.
Change the i++ in the loop statement to i+=2, so that you only examine even values of i?
Typically, a number is odd if it's LSB (Least Significant Bit) is set. You can check the state of this bit by using the bitwise AND operator:
if($testvar & 1){
// $testvar is odd
}else{
// $testvar is even
}
In your code above, a more efficient way would be to have $i increment by 2 in every loop (assuming you can ignore odd-values):
for($i=0;$i<$num;$i+=2){
// $i will always be even!
}

Categories