What is a true way to write like:
if ($variable == '(value1/value2/value3)' ) { }
It should work similar to:
if ($variable == 'value1' || $variable == 'value2' || $variable == 'value3') { }
Just want to make this code shorter (now I use switch).
Thanks.
Try in_array():
if (in_array($variable, array('value1', 'value2', 'value3'))) {}
If you do happen to have a group of values separated by, in your example, a /, just explode() it and you'll have an array to plug into in_array():
if (in_array($variable, explode('/', 'value1/value2/value3'))) {}
It might seem like you could just use strpos() instead since it's a long string of values, but that's not how one would work with a delimited string of multiple values (use explode() instead, as above):
if (strpos('value1/value2/value3', $variable) !== false) {}
Also shorter:
if (preg_match('#^(?:value1|value2|value3)$#', $variable) {
Not that it's necessarily the best way to do it. The long way, using just if and || statements, is going to be simple to read even though it's lengthy, and will be the most efficient to run.
switch ($variable)
{
case "value1":
case "value2":
case "value3":
...
break;
default: // else
...
}
Related
Basically what I'm wondering if there is a way to shorten something like this:
if ($variable == "one" || $variable == "two" || $variable == "three")
in such a way that the variable can be tested against or compared with multiple values without repeating the variable and operator every time.
For example, something along the lines of this might help:
if ($variable == "one" or "two" or "three")
or anything that results in less typing.
in_array() is what I use
if (in_array($variable, array('one','two','three'))) {
Without the need of constructing an array:
if (strstr('onetwothree', $variable))
//or case-insensitive => stristr
Of course, technically, this will return true if variable is twothr, so adding "delimiters" might be handy:
if (stristr('one/two/three', $variable))//or comma's or somehting else
$variable = 'one';
// ofc you could put the whole list in the in_array()
$list = ['one','two','three'];
if(in_array($variable,$list)){
echo "yep";
} else {
echo "nope";
}
With switch case
switch($variable){
case 'one': case 'two': case 'three':
//do something amazing here
break;
default:
//throw new Exception("You are not worth it");
break;
}
Using preg_grep could be shorter and more flexible than using in_array:
if (preg_grep("/(one|two|three)/i", array($variable))) {
// ...
}
Because the optional i pattern modifier (insensitive) can match both upper and lower case letters.
Basically what I'm wondering if there is a way to shorten something like this:
if ($variable == "one" || $variable == "two" || $variable == "three")
in such a way that the variable can be tested against or compared with multiple values without repeating the variable and operator every time.
For example, something along the lines of this might help:
if ($variable == "one" or "two" or "three")
or anything that results in less typing.
in_array() is what I use
if (in_array($variable, array('one','two','three'))) {
Without the need of constructing an array:
if (strstr('onetwothree', $variable))
//or case-insensitive => stristr
Of course, technically, this will return true if variable is twothr, so adding "delimiters" might be handy:
if (stristr('one/two/three', $variable))//or comma's or somehting else
$variable = 'one';
// ofc you could put the whole list in the in_array()
$list = ['one','two','three'];
if(in_array($variable,$list)){
echo "yep";
} else {
echo "nope";
}
With switch case
switch($variable){
case 'one': case 'two': case 'three':
//do something amazing here
break;
default:
//throw new Exception("You are not worth it");
break;
}
Using preg_grep could be shorter and more flexible than using in_array:
if (preg_grep("/(one|two|three)/i", array($variable))) {
// ...
}
Because the optional i pattern modifier (insensitive) can match both upper and lower case letters.
can I do something like
if($x != (y&&z&&r&&w))
Or do I have to write it like this
if($x!=y && $x!=z && $x!=r && x!=w)
Just wondering because I have lots of variables to compare and just wanted a more elegant solution.
You might have a more elegant solution anyway. Here's what I'm trying to do.
foreach($_POST as $key => $value){
if($key != 'category_id'){
$cp[$key] = $value;
}
}
And I have about 6 more variables to compare in my $_POST statement and I would like to make the code pretty. It's basically a huge form that needs to format into a specific array ($cp[]) with specific keys to use my MySQL insert statement.
Any fancy ideas?
Your first portion of code :
if($x != (y&&z&&r&&w))
will evaluate the constants y, z, r and w (strings 'y', 'z', 'r' and 'w', if those constants don't exist) ; doing a AND between each one of those.
And, then, the result of this AND will be compared to $x -- which will be considered as a boolean.
So, no, it's not quite doing what you hoped for ; you must use your second portion of code :
if($x!=y && $x!=z && $x!=r && x!=w)
Note that here, too, it'll search for constants called y, z, r and w (or strings, if those constants still don't exist) -- you should probably put some $ in front of those, if you expect them to be treated as variables.
If you want to test if a variable has one of several values, a possible solution is to put those values into an array, and, then, use the in_array() function :
if (in_array($x, array(10, 20, 30) )) {
// $x is one of those values : 10, 20, 30
}
Some think it's easier to understand this way than writing several comparisons -- I sometimes use this myself, and kind of like it.
You'll have to write the long form or use in_array and an array containing your values.
You you can not do it like this:
if($x != (y&&z&&r&&w))
They have to be separated out in to 4 comparisons.
Alternatively, what you can do is stick the values in an array and have only 1 comparison:
$skip_keys = array('a', 'b', 'c', 'd');
foreach ($_POST AS $key => $value) {
if ( ! in_array($key, $skip_keys)) {
// Continue
}
}
You can't say
if ($x != (1&&2&&3))
like that
I also was wondering in my early years whether we can do
if (1 < $x < 5)
and the answer is no too. But you can use in_array() to test if something in an array for you to check several values at once:
http://php.net/manual/en/function.in-array.php
My recommendation, if you're doing this comparions multiple times, is to write a function that validates your requirements for it. So you'll pass in your '$x' and can compare that to everything you need, and will get a boolean result. The function can be structured nicely with ifs and elseifs and you'll keep your code cleaner.
So, example...
<?php
// random, bad logic, but you get the idea
function validateThisThing($x) {
$toReturn = false;
if ($x == 'this') {
$toReturn = true;
} elseif ($x == 'that') {
$toReturn = true;
}
return $toReturn;
}
Then you can just use that function as needed and keep your checks cleaner and more structured as your function name will bring context into what's being checked.
Simple but this has always bothered me. Which is the best way to condition statement?
$foo = '1';
if($foo === '1' || $foo === '2' || $foo === '3')
{
// foo matches
}
or
if($foo === '1' || '2' || '3')
{
// foo matches
}
Which step works and is better. is there a better solution?
The second version will always evaluate to true.
If you want to compact the comparison against multiple alternatives then use:
if (in_array($foo, array('1', '2', '3') )) {
If you want to closely match the exact comparison === then you would however need:
if (is_string($foo) && in_array($foo, array(...))) {
$foo = 1;
if(in_array($foo, array(1, 2, 3))){
//foo matches
}
This is an alternative:
if($foo>0 && $foo<4){
}
Second if statement won't work. PHP doesn't work like that. Any number other than 0 (including negatives) evaluates to true when alone in an if statement. This is why you can do something like if(count($array)) without specifying that count($array) must be greater than 0.
Would be the same as if you had said:
if($foo === 1)
{}
elseif(2) //This will always trigger if $foo !== 1.
{}
elseif(3) //This will never trigger because of the last one
{}
Each condition is it's own self contained condition. Instead of reading it as just "or" or "and" read it as "or if" and "and if". So if $foo is 1 or if 2 or if 3 instead of if $foo is 1 or 2 or 3
If it's just numeric, then amosrivera's solution is the best. If it's for other types of data, then webarto/mario have a good solution.
Okay, I believe that I can simplify this line of code except I can't find anything online. Can anyone help me?
if(empty($action) || $action == "a" || $action == "b" || $action == "c") {
}
Thanks!
You can use in_array() to search an array of possible values for $action:
if (empty($action) || in_array($action, array('a', 'b', 'c'))) {
}
I keep the empty() condition separate because empty() tests true for a number of things besides the empty string ''.
If all you care is to test for the empty string, you can include it in in_array(), and get rid of that empty():
if (in_array($action, array('', 'a', 'b', 'c'))) {
}
Performantly, I think explicitly including empty() is a teeny weeny little bit better, due to short-circuiting.
$options = array("a", "b", "c");
if (empty($action) || in_array($action, $options) ) {
}
I suggest you don't simplify this code because you may gain some kind of readability but you would also increase computation time. And that's a thing I would prefer to improve more than readability (code is executed a lot more often than read in plain text).
Why is that?
An expression like yours consisting only of or conjunctions will end right the moment the first 'true' value is found. So in best case PHP will just evaluate empty($action) with true and leave the if-header without evaluating all the other parts. In worst case it will check every part till the end. So in average - without further knowlege about the data you will check - you are running and computing half of the if-header.
But if you use something like in_array($action, array('a', 'b', 'c')) than you will construct the whole array with all elements and search in it. So your PHP interpreter has to create all the elements and the array just to match one of the first ones. Which is anyway more computation than your current line.
So think twice about readabilty vs. code complexity.
if (empty($action) || preg_match('/^[abc]$/', $action)) { ... }
Edit: empty($action) is needed to allow false, array(), 0, and null to pass which you may not want.