I'm currently working on a foreach loop with nested if statements but I'm pretty sure there's a better way of writing these chunks of if statements.
I found this post: PHP if shorthand and echo in one line - possible?
Though this post is for single conditions, I would like to write mine in the same way(single lined).
I'm not that experienced in PHP myself so I'm sort of stuck on doing it the old fashioned way:
if(($colorLevel['name'] === 'ATTR_VPMCV13') && ($colorLevel['level'] >= 80))
{
$prominentSideNumberArray[] = 10;
}
elseif(($colorLevel['name'] == 'ATTR_VPMCV13') && ($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)){
$prominentSideNumberArray[] = 8;
}
If someone could properly explain what code to use where and why, that could really help me, and/or others, out. I've looked at the manual but I just can't figure out what to use where.
There is no such thing like an "if shorthand".
?: is an operator, if is a control structure. They are different language concepts that have different purposes and do different things. An expression that contains the ternary conditional operator (?:) can always be rewritten as two expressions and an if/else statement. The vice-versa is usually not possible.
The code you posted can be written to be much easier to read if you extract the common checking of $colorLevel['name'] into a separate if that includes the rest of the tests, extract $colorLevel['level'] into a new variable with shorter name and make the conditions that use $colorLevel['level'] use the same rule:
$level = $colorLevel['level'];
if ($colorLevel['name'] == 'ATTR_VPMCV13') {
// Don't mix '<=' with '>=', always use '<='...
if (60 <= $level && $level <= 70) {
$prominentSideNumberArray[] = 8;
// ... and put the intervals in ascending order
} elseif (80 <= $level) {
$prominentSideNumberArray[] = 10;
}
}
If there are multiple if statements that verify different values of $colorLevel['name'] then the intention is more clear if you use a switch statement:
$level = $colorLevel['level'];
switch ($colorLevel['name'])
{
case 'ATTR_VPMCV13':
if (60 <= $level && $level <= 70) {
$prominentSideNumberArray[] = 8;
} elseif (80 <= $level) {
$prominentSideNumberArray[] = 10;
}
break;
case '...':
// ...
break;
default:
// ...
break;
}
You can achieve this by using a ternary operator. Look at the following code:
$prominentSideNumberArray[] = ((($colorLevel['name'] === 'ATTR_VPMCV13') &&
($colorLevel['level'] >= 80) )? 10 : (($colorLevel['name'] == 'ATTR_VPMCV13') &&
($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)?8:"")) ;
EDIT As per comments and you have to compare same value its better to define name
$color_name = "ATTR_VPMCV13";
if($colorLevel['name'] == $color_name )
$prominentSideNumberArray[] = (($colorLevel['level'] >= 80)? 10 : (
($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)?8:"")) ;
DEMO with different approach
EDIT
Keep in mind that this solution is less readable than if-else statement.
Related
I am trying to get rooms that are not written already to a residential apartment short: RA. So as long array_shift is dragging the rooms out of the array, the loop should count further and it have to check allRARooms if there are still some rooms left for me.
So is that ok to check for isset in a for condition?
for($i = 1; count($ra) <= $quantity && isset($this->allRARooms); $i++)
Yes you can set for loop terminating condition to whatever expression you like.
You can even skip it ! for example:
for ($i=0;;$i++) {
if ($i>10) break;
echo "$i\n";
}
Or maybe you want an everlasting loop with for? here it is :
for (;;) echo ++$x . "\n";
In essence you can skip whatever part in for loop you need
Condition optimization
Your condition count($ra) <= $quantity && isset($this->allRARooms) can be factored a bit.
In 99% cases it's enough of count($ra) <= $quantity && $this->allRARooms, because '',null,[] - all evaluates to false.
Further you should put allRARooms var check at first place, like:
$this->allRARooms && count($ra) <= $quantity. In that way you will employ a short-circuit evaluation trick for boosting condition check speed, because if var allRARooms is not set - count($ra) will not be evaluated - thus saving CPU ticks
Yes it is.
A for loop can be described as such : for (initialisation; alive condition; last loop statement)
it can be translated using a while loop that way :
initialisation
while (alive condition)
{
// some code
last loop statement
}
You put what you want as long as it respects the differents statements
for($i = 1; count($ra) <= $quantity && isset($this->allRARooms); $i++) { }
is equivalent to
$i = 1;
while (count($ra) <= $quantity && isset($this->allRARooms))
{
// some code
$i++;
}
You can add many initialisation and last instruction statements and the alive condition can be independant of them.
$aConditionIndependantOfInit = true;
for ($i = 0, $j = 42; $aConditionIndependantOfInit; $i++, $j--)
{
echo "foo\n";
if ($i >= $j)
$aConditionIndependantOfInit = false;
}
This output 21 foo
I am currently teaching myself web development/ programming and to learn php i have built a simple program. The program takes user input and based on a series of math algorithms and calculates 7 random lottery numbers. The code is working fine but i want to improve it. The code is very repetitive and i want to simplify it by creating my own functions. I have created the first function that takes the users input, simply does some maths and then returns some values.
For Example...
<?php
function some_maths($int1 $int2 $int3){
$x = $int1 + $int2;
$y = $int2 * $int3;
$z = $y * $x;
return $x
....}
So this is pretty straight forward, but what i want to do now is take the values of X, Y, Z and create a function that checks to make sure they're not matching, or that they're not less than 1 or greater than 59. I used a while loop in my original code that goes like this:
while($x == $y || $x == $z || $x <1 || $x >59){
if( x> 59 || x < 1){
if (x<1){
do{ $x+=$int}while($x <1);
}elseif ($x > 59){
do{ $x-=$int}while($x >59);
}else $x++;
}
This seems to work fine but i don't want to have to repeat the same code over and over. I am sure there has to be a better way? Could i put the values into an array and maybe do it that way? What would be the best solution for this?
Your question is kind of vague but if I had to write a function to check if three numbers weren't equal and were < 59 and >1 this is how I would do it
function validateNumbers($x , $y , $z)
{
if(equal($x,$y)) return false;
if(equal($x,$z)) return false;
if(equal($y,$z)) return false;
if($x>59||$x<1) return false;
if($y>59||$y<1) return false;
if($z>59||$z<1) return false;
return true;
}
function equal($x , $y)
{
if($x == $y)return true;
else return fasle;
}
So far I only see two (pretty straightforward) things:
Your function prototype in the first example is missing commas between the parameters. Instead of function some_maths($int1 $int2 $int3) it should read function some_maths($int1, $int2, $int3).
In your second example a closing } is missing. But if I am interpreting your stuff correctly, the outer if-clause is redundant. Thus, the snippet can be simplified to:
Second example:
while($x == $y || $x == $z || $x <1 || $x >59){
if (x<1){
do{ $x+=$int}while($x <1);
}
elseif ($x > 59){
do{ $x-=$int}while($x >59);
}
else $x++;
}
There may be more room for improvement (e.g. slim down the condition of the outer while loop) - but for that we would need more context (what happens before your loop, what is $int, ...).
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.
Suppose I have a variable integer and wish to do different things if the value is greater then one value and less then another value. My objective for this switch, is basically to send different results based on the value of $chance, which I will have many cases in the end as this is for a game.
switch ($chance)
{
case ($chance < 15):
echo"strike<br>";
case ($chance < 15 && $chance > 50):
echo"Ball<br>";
break;
case ($chance < 50 && $chance > 100):
echo"Single<br>";
break;
case ($chance <= 150 && $chance >= 100):
echo"double<br>";
break;
case ($chance <= 175 && $chance >= 151):
echo"triple<br>";
break;
case ($chance > 200 && $chance > 175):
echo"Ground Rule Double<br>";
break;
case ($chance < 200):
echo"Home Run<br>";
break;
}
Now, I've been told that I can use conditionals in switch statements, and I've also been told that I should not use them. I really don't know who to believe.
What I do know, is that currently, this switch statement does not work as intended. It doesn't generate syntax errors, but I will get random echos back. This happens when sometimes the chance may be 100 and I will get a home run echo. I'm not sure.
I know I could do the same with a series of if but it would amount to a huge difference in length of code if I can achieve the same results.
I imagine I can do something like
case 1:
echo this
case 2:
echo that
etc etc
Until I hit 2 or 300 but I would like to avoid that if possible.
This is not how you use the switch statement. This is an example of a correct way:
switch ($a) {
case 1:
echo 1;
break;
case 2:
echo 2;
break;
default:
echo 0;
}
For what you want to accomplish you need to use the old if-else statements.
if ($chance < 15)
echo"strike<br>";
else if ($chance >= 15 && $chance < 50)
echo"Ball<br>";
else if ($chance >= 50 && $chance < 100)
echo"Single<br>";
else if ($chance <= 150 && $chance >= 100)
echo"double<br>";
else if ($chance <= 175 && $chance >= 151)
echo"triple<br>";
else if ($chance < 200 && $chance > 175)
echo"Ground Rule Double<br>";
else if ($chance <= 200)
echo"Home Run<br>";
Switch statement syntax:
http://php.net/manual/en/control-structures.switch.php
<?php
switch ($i) {
case 0:
echo "i equals 0";
break;
case 1:
echo "i equals 1";
break;
case 2:
echo "i equals 2";
break;
default:
echo "i is not equal to 0, 1 or 2";
}
?>
To do what you are wanting to do, you should use an if-else. The value used for the case expression must be an integer, floating-point decimal, or string.
You need just set true in you switch. Use switch (true) instead of switch ($chance).
now your code will be:
switch (true)
{
case ($chance < 15):
echo"strike<br>";
case ($chance < 15 && $chance > 50):
echo"Ball<br>";
break;
case ($chance < 50 && $chance > 100):
echo"Single<br>";
break;
case ($chance <= 150 && $chance >= 100):
echo"double<br>";
break;
case ($chance <= 175 && $chance >= 151):
echo"triple<br>";
break;
case ($chance > 200 && $chance > 175):
echo"Ground Rule Double<br>";
break;
case ($chance < 200):
echo"Home Run<br>";
break;
}
Despite some mathematical/comparison issues in your code, it seems that you intend to set numeric ranges that correspond to specific outcomes. It also seems inappropriate to reach multiple outcomes in a single script execution.
Given these truths, you should use an if-elseif-else block. It will be more appropriate and less verbose than a switch block.
The ONLY advantage to using a switch block is when you need to make 1 evaluation and take different actions based on that evaluation. Because you are making multiple evaluations, there is no advantage in using a switch -- in fact, the computational complexity will be the same and the syntax will either be of equal or greater length versus an if block. I personally have such a distaste for switch blocks that I endeavor to use any other viable technique instead. Switch blocks only make very rare appearances in my professional projects.
By progressing in an ASC or DESC fashion, you will only need one expression in each condition. Using consistent operators in each condition will make your script easier to maintain/extend.
Finally, in PHP, elseif is one word not two.
Code:
if ($chance < 0) {
$result = 'Balk'; // ;)
} elseif ($chance < 15) {
$result = 'Strike';
} elseif ($chance < 50) {
$result = 'Ball';
} elseif ($chance < 100) {
$result = 'Single';
} elseif ($chance < 150) {
$result = 'Double';
} elseif ($chance < 175) {
$result = 'Triple';
} elseif ($chance < 200) {
$result = 'Ground Rule Double';
} else {
$result = 'Home Run';
}
echo "$result<br>";
This is what i have currently
if ($j == 1 || $j == 2 || $j == 3)
Is there a simpler way of writing this. Something like...
pseudocode
if ($j == 1-3)
Here's one way using in_array()
if (in_array($j, array(1,2,3)))
{
//do something
}
Or how about using range() to make the array
if (in_array($j, range(1,3)))
{
//do something
}
However, building an array just to check a narrow, contiguous range like that is pretty inefficient. So how about simply:
if ($j >= 1 && $j <= 3)
{
//do something
}
If other values of $j will trigger different action, a switch might be more appropriate...
switch($j)
{
case 1:
case 2:
case 3:
//do something
break;
}
If it's a range, you can simply do:
if ($j >= 1 && $j <= 5) ...
Paul's good one, but if you have a large number then you may want to use range:
if (in_array($j, range(0, 100)))
{
}