I have an if statement with a few or's in it.
i.e.
if($count == 1 || $count == 3 || $count == 7) {
// do stuff
}
I'm just curious - is this the best way to do this? With this simple example above, is there a faster way to do this, and if so, what is it?
Your code works fine. Alternately, you can use in_array(), which is a bit cleaner and scales better:
if (in_array($count, array(1,3,7))) { ... }
The code you've written is fine. As Paul Schreiber says, there are various other options that are a little neater.
One thing you may want to think about (and I know this is just an example) is why the values you're checking are important. Do they all have some property in common that you're checking? If so, then stating the property symbolically may make the code easier for someone to understand. For example:
if (is_odd($x) && $x < 10) {
//...
}
rather than
if ($x == 1 || $x == 3 || $x == 5 || $x == 7 || $x == 9 ) {
//...
}
This is quite a contrived example, but hopefully you see what I'm getting at.
As a more concrete example, instead of doing something like:
if ($user->age > 65
|| $user->years_of_custom > 3
|| $num_items > 5 ) {
// Give this user a discount ....
}
you might want to do:
if (eligible_for_discount($user, $num_items) ) {
// Give this user a discount
}
Even if you only use the function in this one place, this could increase the readability of the code. Obviously you have to use your judgment though, because you're increasing readability at the expense of having more lines of code to maintain, and that isn't always the right choice. If the conditions have little to do with each other, binding them up into a separate function might make no sense and make your code harder to follow, not easier. Focus on what your code actually means, and how a human being should understand it.
You can assign all possible value in an array and check using array_search function
$array=array(1,3,7);
if (array_search($count,$array) !== FALSE)
{
//do stuff
}
Wouldn't the switch statement be better?
switch ($count) {
case 1:
case 3:
case 7:
echo "do stuff";
break;
}
Related
I find myself doing this a lot, and I assume there is a short hand way to make this faster. Yet in my research about shorthand and ternary operations, I can't quite seem to wrap my head around how to do it.
// below variable only be impactful if it's SET, not Null, and === important value.
$verbose_instructively_named_variable = $other_variable. "_modifier";
if(isset($verbose_instructively_named_variable) && $verbose_instructively_named_variable !== null && $verbose_instructively_named_variable === "key_text_modifier"):
// Now do important thing here;
endif;
I am a beginning programmer obviously, but find myself attracted to longer variable names so when I revisit things later it flows linearly for me. So I find myself wanting to do the below all the time, and am frustrated I can't.
if(isset($verbose_instructively_named_variable) && !==null && === "key_text_modifier"):
// Now do important stuff;
endif;
I know this is a PHP question, but I find myself wanting this form of chained logic in javascript also. Am I missing a basic step of some kind?
Is there an altogether different way to test ONE variable for multiple conditions quickly and efficiently?
I have tried combinations of things found in similar questions. Like the in_array solution provided in this answer: In PHP, is there a short way to compare a variable to multiple values?
As well as things like the below standard shortcut/shorthand.
$result = $initial ?: 'default';
But what I want often is something more like this.
$result = ($initial !==null && !=="bad" && !in_array($initial,$record_set_from_mysql_query) ? $initial : 'default');
And keep in mind the main reason I don't like and don't want to do this:
$result = ($initial !==null && $initial !=="bad" $initial !=="even_worse" ? $initial : 'default');
Is because "$initial" maybe named something like $always_make_this_value_green_when_blue_present or something otherwise cumbersome to type repeatedly and it makes the code hard to read later with multi-line parameters in the functions etc.
Presently my best work around for this is to do this.
$a = $long_verbose_instructively_named_variable;
$result = $a !== null && $a !== "bad" && $a !== "even_worse" ? $a : 'default';
But this means in a function with a half dozen little small if/else checks I end up with a, aa, aaa, a_4, a_5 variables all over the place and it just gets cumbersome.
I will still recommend you use in_array at this point. When the array is not big enough, the speed of in_array is still good enough. Because your code will be more easier to read.
As Markus Zeller commented, you can also use a match() method at this condition, you can read from here.
PHP also support array key with characters, it's mean you can use isset() method for your problem, you can read on here.
A tips, you may read PSR-1.
There's a tradeoff between legible code that may be more verbose, and clever code that is shorter but harder to understand. That being said, this is a bit of a kludge but seems to achieve your goal of only referencing $long_verbose_instructively_named_variable once:
switch ($result = ($long_verbose_instructively_named_variable ?? 'default')) {
case 'bad':
case 'even_worse':
$result = 'default';
}
The results for various test cases:
For [unset] got 'default'
For false got false
For NULL got 'default'
For 'bad' got 'default'
For 'even_worse' got 'default'
For 'foo' got 'foo'
How I generated these test cases:
$test_cases = [ FALSE, NULL, 'bad', 'even_worse', 'foo' ];
for ( $i=-1; $i < sizeof($test_cases); $i++ ) {
if ( -1 == $i ) {
unset($long_verbose_instructively_named_variable);
} else {
$long_verbose_instructively_named_variable = $test_cases[$i];
}
echo "For " . ( (-1 == $i ) ? '[unset]' : var_export($long_verbose_instructively_named_variable, TRUE) );
switch ($result = ($long_verbose_instructively_named_variable ?? 'default')) {
case 'bad':
case 'even_worse':
$result = 'default';
}
echo " got " . var_export($result, TRUE) . "\n";
}
I find my self doing this type of IF statement allot. For example:
if($variable == 1 || $variable == "whatever" || $variable == '492') { ... }
Except for allot of the time, I am comparing the $variable to maybe 4-5 things, sometimes more. Is there a short hand way to write this? You can see that repeating $variable == would get redundant.
I would love for this to work, but it doesn't:
if($variable == (1 || "whatever" || 492) { ... }
You can use this shorthand, but keep in mind that it is less efficient that explicitly listing them all with or clauses:
if(in_array($variable, array(1, 'whatever', '492'))){ ... }
Also if you want to use === instead of == the equivalent is:
if(in_array($variable, array(1, 'whatever', '492'), TRUE)){ ... }
if(in_array($variable, array(1, "whatever", 492)))
in_array(...). http://php.net/manual/en/function.in-array.php
Although this doesn't directly answer the question, I think it's worth adding this method as part of a solution to the above problem:
If you find that something has multiple values, you may find that something like the following is appropriate:
if (true === is_condition_one ( $variable )) {
// Execute any condition_one logic here
}
function is_condition_one ( $variable = null ) {
$arrKnownConditions = array (
// This can be an array from the database
// An array from a file
// An array from any other source
// or an array of hardcoded values
);
return in_array ( $variable, $arrKnownConditions );
}
I agree with Godwin and toon81 and PaulPRO, but feel that if you are doing this a lot, you may actually benefit from a refactor as part of your solution. The refactor above may help you organise this project and others better by defining the purpose of the comparison and letting your code be more readable and abstracting away those hardcoded values to a function. This will probably also help you re-use that check in other parts of your code with greater confidence.
Another viable alternative is to use a regex.
if (preg_match('^1|whatever|492$', $variable)) { ... }
This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
php multiple if conditions
What is better ? Multiple if statements, or one if with multiple conditions
So I was working on a segment of code in which I ended up using two different styles of if statements. That got me wondering - which one is more efficient in PHP? Are there times when one might be better than the other, despite general differences (if present)? Is there a certain level of complexity where the benefits become clear (if close) or close (if originally clear)? Also, are there other benefits of one method over the other, other than aesthetic or subjective differences?
if ($value == 'someval') {
if($otherval == 'someval') {
// do stuff
} else if ($otherval == 'otherval') {
// do same stuff
}
}
vs
if (($value == 'someval') && ($otherval == 'someval' || $thirdval == 'someval') {
// do stuff
}
Note - I don't care what works for C# or Java or whatever other language, unless someone can show that they handle the construct exactly the same.
So long as you're executing the same code in each block (as you've indicated by your comments) then they'll both do the trick (and no, there's really not much of a performance difference).
However, typically it's not the case that you'd execute the same code both ways, so logically the first block is actually different from the second in that case. Here's an example:
if($value == 'someval') {
if($otherval == 'someval') {
doSomething();
}
else if ($otherval == 'otherval') {
doSomethingElse();
}
}
versus:
if(($value == 'someval') && ($otherval == 'someval' || $otherval == 'otherval')) {
//we now still need to evaluate $otherval in order to determine which func to execute...
//this adds bloat...
if($otherval == 'someval') {
doSomething();
}
else if ($otherval == 'otherval') {
doSomethingElse();
}
}
So as you can see in the case above the second block is actually less efficient than the first.
There is no real difference, you should use whichever is more readable.
Nested or not nested if-blocks?
Is this a proper way to say: if something is the case, do nothing?
if ( ($hostNameInfo == $hostNameInput) && ($hostAddressInfo == $hostAddressInput) )
{
return;
}
Update:
I'm not inside a function. :(
So the return is just nonsense.
Here is more code:
//if the input fields are equal to database values, no need to update and waste resources,hence, do nothing:
if ( ($hostNameInfo == $hostNameInput) && ($hostAddressInfo == $hostAddressInput) )
{
//do nothing
}
//If, however, (they are NOT equal and) input fields are not empty:
elseif (!empty($hostNameInput) && (!empty($hostAddressInput)))
{
//do something.
}
Thanks in advance,
MEM
For do nothing you simply can type:
function relax() {
;
}
if (($hostNameInfo == $hostNameInput) && ($hostAddressInfo == $hostAddressInput)) {
relax();
}
Maybe you should do the opposite, do something if your condition is not verified
if($hostNameInfo != $hostNameInput || $hostAddressInfo != $hostAddressInput) {
// do something
}
I assume you're inside a function in which case it does what you expect, although multiple return statements within a function can lead to confusion and a lack of readability. (Apparently I was wrong.)
Instead, I prefer to let all conditional blocks (my description for the code between in the if's {...} block) contain the relevant code, i.e., write the conditional check in such a way that the total condition evaluates to true when additional processing (sub-flow) is needed:
if ($hostNameInfo != $hostNameInput || $hostAddressInfo != $hostAddressInput) {
// do stuff, else skip
}
Furthermore, you can extract the conditional statement in order to improve both readability and simplicity of control flow:
$hostInfoEqualsInput = ($hostNameInfo == $hostNameInput && $hostAddressInfo == $hostAddressInput);
if (!$hostInfoEqualsInput) {
...
}
UPDATE (based on updated question). Consider this instead:
$fieldsAreFilled = (!empty($hostNameInput) && !empty($hostAddressInput));
$hostInfoEqualsInput = ($hostNameInfo == $hostNameInput && $hostAddressInfo == $hostAddressInput);
if ($fieldsAreFilled && !$hostInfoEqualsInput) {
...
}
ERGO
Minimize branch rate and avoid empty blocks by writing conditions you want to be met, not all the exceptions you want to ignore (subjective).
You're talking about best practices here..
One of best practice things is that routine shall have single exit point, though it is widely discussed and is up to developer/style.
UPDATE:
New answer, since the question was changed:
Don't see any reason to add additional checks if the code should run only under some circustances. To make the code more readable, you should stuck to whatever you accept as easy-maintainable, like this (or something similar):
// Do something only if required
if (($hostNameInfo != $hostNameInput) || ($hostAddressInfo != $hostAddressInput)) &&
!empty($hostNameInput) && !empty($hostAddressInput))
{
echo 'place some code here';
}
A native do_nothing() function would be very nice and readable sometimes.
To avoid stressing alerts from syntax checkers & linters, that go crazy when you have an empty if block, I use:
echo(null);
The other possibility is to throw a new exception, which you can later catch in your application.
UPDATE: not inside the function this is probably a bad idea.
Is there any good alternative for the plain if statements in PHP? I know about switch, but I'll guess that there's some more refined alternative out there that comes handy when working with really big if statements.
Thanks a lot,
If you can't read your algorithm on one screen fold, there's a 99.9% chance you need to refactor your code toward more readability.
Change
if ($isHappening) {
// ... millions of lines of code
} else {
// .. another million lines of code
}
into
if ($isHappening) {
happen();
} else {
didntHappen();
}
function happen() {
// millions of lines of code
}
function didntHappen() {
// another million lines of code
}
There really is no magic hammer out there. Your best bet to making them manageable is to break nested ifs into their own functions to make them more readable.
Also, don't forget about array_filter. That can save you from having to write a for loop to filter out items.
Also, you can eliminate nesting by using guard statements. You basically invert your if and do a return instead (another reason to break conditions into functions).
If you want to improve readability only, then you can always split up the expressions inside the if statement:
$exp1 = is_array($var) && isset($var['key']);
$exp2 = is_object($var) && isset($var->key);
$exp3 = substr($string, 0, 4) == 'foo';
$exp4 = ($exp1 || $exp2) && $exp3;
if ($exp4) {}
instead of
if (((is_array($var) && isset($var['key'])) || (is_object($var) && isset($var->key))) && substr($string, 0, 4) == 'foo') {}
Obviously, these are simplified examples, but you get the idea...
Welcome to the world of Object Orientation :)
class Case1 {
function do() { echo "case 1"; }
}
class Case2 {
function do() { echo "case 2"; }
}
$object = new Case1();
$object->do();
And then, there is dispatching using an array:
$choices = array( "case1" => new Case1(), "case2" => new Case2(), ... );
$choices[ $_GET["case"] ]->do();
Well if is if, there is not much else out there. Of course switch is an alternative but depending on the conditions it might not be applicable.
If you are doing OOP, the state design pattern might be what you need.
Otherwise you have to give more information...
If by "big" you mean large, highly nested "ifs", this is a clear sign of code smell, and you should be looking at OOP and design patterns.