Check in array if only one specific entry is present - php

I am trying to check if there is only one value in an array and if that specific value is "Home" then do something. Is the method below the best way to accomplish this or can I do it in one step?
Like:
$mymenu; // array
if(count($mymenu) < 2 && in_array('Home', $mymenu)){
// Do something
}

The only other changes I'd make would be:
if(count($mymenu) === 1 && $mymenu[0] === 'Home')
Changing the count check from < 2 to === 1 reads better to me; it makes more sense when reading the code back, since it conveys what you actually mean.
As for in_array, since you know there should only be one item in your array, it's probably faster to just use $mymenu[0] instead of doing a needle/haystack lookup.
Other than that, there isn't a more concise way to do what you want.

Try this ternary Operator ...
echo count($mymenu) === 1 && $mymenu[0] === 'Home' ? 'Do something' : null;

Related

Is there PHP shorthand for testing variable value for multiple conditions without using in_array?

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";
}

PHP If a variable equals this or this

I have this if statement in my PHP:
if($_SESSION['usrName']!='test1'){
header('location:login.php');
}
But i want it to be something like this:
if($_SESSION['usrName']!='test1' or 'user'){
header('location:login.php');
}
But i cant figure out how to do it in PHP code. I have tried this:
if($_SESSION['usrName']!='test1','user'){
header('location:login.php');
}
And this:
if(($_SESSION['usrName']!='test1')||($_SESSION['usrName']!='user')){
header('location:login.php');
}
Can anybody help please?
You have to replace the || with &&. Because you only want to redirect when both conditions are true.
if(($_SESSION['usrName']!='test1') && ($_SESSION['usrName']!='user')){
header('location:login.php');
}
if (!in_array($_SESSION['usrName'], array('test1', 'user')) {
header('location:login.php');
}
This checks if variable $_SESSION['usrName'] is not in list of strings to simplify additional allowed user.
As others have said, you need to be careful with your boolean logic - (NOT X) || (NOT Y) is equivalent to NOT (X AND Y), whereas what you want is NOT (X OR Y) which is equivalent to (NOT X) AND (NOT Y).
For this particular situation, there are also a couple of other options, although none as neat as the invalid syntaxes you tried.
First, there is in_array(), which is easy to read, but not very efficient if you use it a lot with long lists (for a simple case like this, it's not worth worrying about performance, though):
$allowed_users = array('test1', 'user');
if ( ! in_array($_SESSION['usrName'], $allowed_users ) { ... }
Or, you can build a hash with the usernames as keys; this is more efficient as the list grows, because PHP can check for a key without looping through the whole list:
$allowed_users = array('test1' => true, 'user' => true);
if ( ! array_key_exists($_SESSION['usrName'], $allowed_users) ) { ... }
// Or, if you don't mind PHP raising a few notices about accessing undefined keys
if ( ! $allowed_user[ $_SESSION['usrName'] ] ) { ... }
Finally, you can use a switch statement, with the labels falling through, and a default case acting as the "else":
switch ( $_SESSION['usrName'] )
{
case 'test1':
case 'user':
// These users are allowed :)
break;
default:
header('location:login.php');
}
Which, if any, of these you choose to use will depend on how you expect the code to grow in future, but they're useful tricks to know.
Your last attempt is almost correct.
However...
if (var != something || var != something-else)
...will always be true, because one of those conditions will always match. Even if it's equal to one side, it won't be equal to the other.
When you're testing two negatives like that, you need to use AND (&&) instead of OR (||).
if (($_SESSION['usrName']!='test1') && ($_SESSION['usrName']!='user'))
This will match if it's not equal to one, and also not equal to the other.
Currently, you're checking if either one of conditions are true. The last condition will evaluate to true if either one of the conditions are correct. I assume you're trying to check if both the the conditions are true. In that case, you'll need && instead of ||.
Try:
if( ($_SESSION['usrName'] != 'test1') && ($_SESSION['usrName'] != 'user') ) {
header('location:login.php');
}
You need to do something like:
if($_SESSION['usrName'] != 'test1' and $_SESSION['usrName'] != 'user'){
header('location:login.php');
}
The first attempt of yours is equivalent to:
if(($_SESSION['usrName']!='test1') or 'user'){
header('location:login.php');
}
Second seems like invalid syntax
Third is almost right, you just need to replace || with and or &&, as anything will be unequal to either 'user' or 'test1'

PHP operators if statement 'and' and 'or'

I have an if statement that I want to control with having one field needing input and they have to pick one of the other 2 choices.
if(test1 && test || test3){
//Something here
}
Should I do it like this:
if(test1 && (test2 || test3)){
//do stuff
}
How would I go about doing this. I can't wrap my head around the logic...
if ($requiredField && ($optional1 || $optional2)) {
/* Do something */
}
For the /* Do something */ bit of code to be executed, the if statement has to evaluate to TRUE.
This means, that $requiredField must be TRUE, and so must be ($optional1 || $optional2).
For $requiredField to be TRUE, it just needs to be filled in - and for the second part: ($optional1 || $optional2) either optional1 or optional2 would do it.
Edit:
After rereading the question, it seems that I might have misunderstood you. If the user must enter one specific piece of information, and must choose only one (not both) out of two options - then the following should be used.
if ($requiredField && ($optional1 ^ $optional2)) {
/* Do something */
}
This means that $optional1 or $optional2 must be filled out - but not both of them.
From the sound of it, you want the latter:
if ($test1 && ($test2 || $test3)){
//do stuff
}
Think of it as two conditions needing to be met. This gives you those two conditions. The second condition just happens to be another condition. The first option you posted, however, is quite the opposite as it can allow execution if just $test3 is true
test1 && (test2 || test3) is very easy to understand from the first place - Choose test1 && (test2 || test3) means one the last two. Very clear.
test1 && test || test3 - doesn't seem to be correct:
test1 = false
test2 = false
test3 = true
false && false || true = true
doesn't actually fit your criteria.
... they have to pick one of the other 2 choices
I'm just throwing a guess out here. If you really want to ensure that one, but only one of the two other options are selected, then you need xor:
if ($required AND ($and_either XOR $or_other)) {
You can have 'nested' if statements withing a single if statement, with additional parenthesis.
if(test1 && (test2 || test3)){
//do stuff
}
Your logic is right but your sintax isnt, you should compare the values of the variables as show, or simply ignore them as saying you are trying to compare them as they are TRUE.
$test1=true;
$test2=true;
$test3=false;
if($test1==true && ($test2==true || $test3==true){ echo "YES";}
This will output YES.

Short hand to do something like: if($variable == 1 || $variable == "whatever" || $variable == '492') .

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)) { ... }

Is this the way to do this simple IF OR OR statement?

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;
}

Categories