if(!($whatever && what()) do_stuff...
Can this be replaced with something more intuitive like:
if(not($whatever && what()) do_stuff...
?
function not($OriginalCheck)
{
return !$OriginalCheck;
}
function is($OriginalCheck)
{
return !!$OriginalCheck;
}
should do exactly that :)
There are several ways to write checks:
if(!($whatever && what()) do_stuff...
if(!$whatever || !what()) do_stuff...
if(($whatever && what()) === false) do_stuff...
if((!$whatever || !what()) === true) do_stuff...
if($whatever === false || what() === false) === true) do_stuff...
all these ways are intuitive and known through out the programming world.
No it can't. See http://www.php.net/manual/en/language.operators.logical.php for the language reference about logical operators, and navigate to find other aliases.
Note however that the precedence of && and || is not the same as and and or.
One option is to make the boolean expression more explicit:
if(($whatever && what()) == false) // do_stuff...
Or alternatively, by implementing a custom not():
function not($expr) {
return $expr == false;
}
if(not($whatever && what())) // do_stuff...
Actually, I don't like the ! operator as well. Although it was understood by every developers but it took me a bit of time every time I read the code. So I prefer do not use the ! operator. But it depends on also.
For php built-in function, I created almost the helper functions for not operator.
https://github.com/vuvanly/not-operators-helpers
There is no alternative !, but it could be written less intuitive:
if ($whatever - 1) {
}
Should the question cause be that ! is too easy to overlook, but not more visible; then another alternative notation would be:
if (!!! $whatever) {
If this still looks to simple, just use:
if (~$whatever & 1) {
Binary operations always look professional ;)
Related
I have php if statement that should display certain HTML code if two conditions are true or another two are true or third part of conditions are true.
I have several arrays - $Options_arr, $MoreOptions_arr, $Special_arr .
To explain in the easiest possible way I want to do this:
if(!empty($Options_arr[0]) && $Options_arr[0]!="") or
(!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") or
(!empty($Special_arr[0]) && $Special_arr[0]!="")
{?> some HTML here
All help will be appreciated thank you.
empty() already checks for empty string "" so it's shorter:
if(!empty($Options_arr[0]) || !empty($MoreOptions_arr[0]) || !empty($Special_arr[0])) {
//some HTML here
}
BragG, you can use elseif
Like:
if((!empty($Options_arr[0]) && $Options_arr[0]!="") ||
(!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") ||
(!empty($Special_arr[0]) && $Special_arr[0]!=""))
{
// some html or any code
}
I hope that is what you were looking for..
Feel free to ask any question.
You are just missing some brackets. Also || is more frequently used than OR
if((!empty($Options_arr[0]) && $Options_arr[0]!="") || (!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") || (!empty($Special_arr[0]) && $Special_arr[0]!="")){
echo '<p>hello</p>';
}
You're basically already there...
if (
(!empty($Options_arr[0]) && $Options_arr[0]!="")
|| (!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="")
|| (!empty($Special_arr[0]) && $Special_arr[0]!="")
){
...do something
Basically you write an if statement that resolves if any of the sub-statements are true by joining the sub-statements together with ORs
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)) { ... }
I am using this snippet below, how can i add a second equal statement with an "and" so something like ($onevariable === $othervariable) and ($2variable ===$2othervariable)
if ( $onevariable === $othervariable ) {
require("file.php");
}
You do this with &&
if ( $onevariable === $othervariable && $2variable === $2othervariable) {
You can read more about logical operators here.
You can Directly use the && operator like this
if ( $onevariable === $othervariable && $2variable ===$2othervariable )
{
require("file.php");
}
further You can visit here
This is fairly straight-forward, it's just how you already wrote in your question:
if ( ($onevariable === $othervariable) and ($2variable === $2othervariable) ) {
require("file.php");
}
See as well Logical Operators (PHP).
Note: $2variable is not a valid variable name, as well isn't $2othervariable because they start with a number. But I think you get the idea from the example code.
You can use a simple && operator:
if ( $onevariable === $othervariable && $2variable === $2othervariable ) {
require("file.php");
}
Just use the logical and operator &&. You can also use and if you prefer, but && is more in use. The only difference between the two is operator precedence.
if ($onevariable === $othervariable && $2variable === $2othervariable) {
require("file.php");
}
I have seen advice that says the ternary operator must not be nested.
I have tested the code below and it works okay. My question is, I haven't seen the ternary operator used like this before. So, is this as reliable as it were used in an if or could something like this come and bite me later(not in terms or readability, but by failing).
$rule1 = true;
$rule2 = false;
$rule3 = true;
$res = (($rule1 == true) && ($rule2 == false) && ($rule3 == true)) ? true : false;
if($res) {
echo "good";
} else {
echo "fail";
}
Thanks!
If the results you are returning from the ternary operator are only "true" and "false", then you don't even need the operator. You can just have:
$res = (($rule1 === true) && ($rule2 === false) && ($rule3 === true))
But, to answer your question, yes multiple conditions work perfectly well.
It's totally legal, it works and is "as reliable as if", but it looks ugly.
If you put each ternary statement inside parenthesis, nesting would be fine too:
$res = ( $rule1 ? true : ( $rule2 ? true : false ) )
The only thing that is advised against in the manual is nesting without parenthesis like this:
$res = ( $rule1 ? true : $rule2 ? true : false )
Is there a reason you want to have your conditions saved into a variable? this is the simplified version of above.
if($rule1 && !$rule2 && $rule3)
{
echo "good";
}
else
{
echo "bad";
}
You do not need the ternary if you are going to return true or false. Quoting the manual:
The expression (expr1) ? (expr2) : (expr3) evaluates to expr2 if expr1 evaluates to TRUE, and expr3 if expr1 evaluates to FALSE.
This means
$res = (($rule1 == true) && ($rule2 == false) && ($rule3 == true));
will assign true or false already. Also, if dont care about $rule being booleans, you dont need the comparison with ==. You also dont need the braces, e.g.
$res = $rule1 && !$rule2 && $rule3;
is the same as your initial ternary.
A good practise when you have multiple expressions like that is to hide the actual comparison behind a meaningful method or function name, e.g.
function conditionsMet($rule1, $rule2, $rule3) {
return $rule1 && !$rule2 && $rule3;
}
and then you can do
if (conditionsMet($rule1, $rule2, $rule3)) {
// do something
}
Of course, conditionsMet isnt that meaningful. A better example would be something like isSummerTime or isEligibleForDiscount and so on. Just express what the rules express in the method name.
You might also be interested in Simplifying Conditional Expressions from the book Refactoring - Improving the design of existing code.
You can also do
$res = ($rule1 && !$rule2 && $rule3);
It's legal and doesn't have to be "ugly". I use the "hook" operator often, in table form it's quite clean, e.g.:
bool haveANeed()
{
// Condition result
// ---------- ------
return needToEat() ? true
: needToSleep() ? true
: needToStudy() ? true
: needToShop() ? true
: needToThink() ? true
: false; // no needs!
}
This function would, IMHO, be less clear and certainly longer if written with if-else logic.
I have system, that using keywords for some data
There are normal keywords and meta keywords - To:all, Tomember: and Togroup:
and I have following condition to check meta keywords:
if ((strpos($kwd, 'To:all') === 0) ||
(strpos($kwd, 'Tomember:') === 0) ||
(strpos($kwd, 'Togroup:') === 0))
{
/* ... */
}
I think this way of identifying meta keywords is incorrect.
One more incorrect way is like this:
if ((strpos($kwd, 'To:all') !== FALSE) ||
(strpos($kwd, 'Tomember:') !== FALSE) ||
(strpos($kwd, 'Togroup:') !== FALSE))
{
/* ... */
}
And in my opinion the correct way is:
if ((substr($kwd,0,6) == 'To:all') ||
(substr($kwd,0,9) == 'Tomember:') ||
(substr($kwd,0,8) == 'Togroup:'))
{
/* ... */
}
Any thoughts?
Of the solutions you propose, the second is wrong because it will return true even if the meta-keywords do not appear in the beginning of $kwd. The other two work correctly.
An even better way would be:
function str_starts_with($haystack, $needle) {
return substr($haystack, 0, strlen($needle)) == $needle;
}
if (str_starts_with($kwd, 'To:all') ||
str_starts_with($kwd, 'Tomember:') ||
str_starts_with($kwd, 'Togroup:'))
{
// ...
}
strpos($kwd, 'To:all') === 0
will check if the $kwd string begins with To:all -- it'll check if the position of To:all in $kwd is 0.
strpos($kwd, 'To:all') !== FALSE
will check if the $kwd string contains To:all -- no matter at which position.
substr($kwd,0,6) == 'To:all'
whill check if the first 6 characters of $kwd are To:all -- which is equivalent to the first solution.
If you want to test the begins with case, you'll use the first or third solution.
Personnaly, I'd go with the strpos-based : I find it easier to read/understand ; but it's mainly a matter of personnal preferences.
If you want to test the contains case, you'll need to use the second solution.