isset() multiple parameters difference - php

What is the difference between
if (!isset($_SESSION['lang']) && !isset($_GET['lang'])) return 'ru';
and
if (!isset($_SESSION['lang'], $_GET['lang'])) return 'ru';
Why does the first one work correctly, but the second always return 'ru'?
As I understand the two conditions are equivalent, but why do they work differently under the same conditions?
Without session and get parameter the first version returns nothing (as I need it), but the second version always returns true, not matter if any of the parameters are set or not.

First condition means both of them have to be set
if (! isset($_SESSION['lang']) && ! isset($_GET['lang']))
Second condition:
isset($_SESSION['lang'], $_GET['lang'] means: both are set.
!(isset($_SESSION['lang'], $_GET['lang']) means: at least one is unset
So if the $_SESSION['lang'] is set and $_GET['lang'] is not set, the second condition will display ru

If multiple parameters are supplied then isset() will return TRUE only
if all of the parameters are set. Evaluation goes from left to right
and stops as soon as an unset variable is encountered.
This means that isset(A,B) is the same as isset(A) && isset(B).
Therefore your second version
!isset(A,B)
is equivalent to
!(isset(A) && isset(B))
which is equivalent to
!isset(A) || !isset(B) // DeMorgan
which is NOT equivalent to your first version
!isset(A) && !isset(B)

You are using incorrect condition.
You can use any of these 3 conditions.
if ((!isset($i)) || (!isset($j))) echo 'ru1';
if (!(isset($i) && isset($j))) echo 'ru3';
if (!isset($i,$j)) echo 'ru2';

Related

PHP && operators

Just curious why this would trigger a warning.
Note: query string param "test" is not included in the URL
//Notice: Undefined index: test
if($_GET['test'] === 'somestring' && !empty($_GET['test'])) {
}
//Valid - No Warning. Why is this Valid? Param 'test' was never given
if(!empty($_GET['test']) && $_GET['test'] === 'somestring') {
}
Is this because PHP evaluates from LEFT to RIGHT? And not the whole condition?
if(!empty($_GET['test']) && $_GET['test'] === 'somestring') {
Because you're using &&, if any condition is false, further conditions are not checked. Conditions are checked in the order they're written. Since here, first condition !empty($_GET['test']) is false, the next one does not evaluate hence no warning.
In the first example:
//Notice: Undefined index: test
if($_GET['test'] === 'somestring' && !empty($_GET['test'])) {
}
you are trying to access the value of the variable first, before checking if it exists, which is what the second example is basically doing. After checking that it does not exist, it exits the conditional without testing the second part.
Simply put, it comes down to operator precedence.
The documentation shows that && is evaluated left-to-right, which means the left part of the clause is evaluated first. In your case, that clause results in a warning. If you reversed your clause order, the empty() check would return false, then the logic would short circuit and stop evaluating.

How does empty() work with a boolean expression?

A guy learning PHP sent me some code that has me scratching my head. He's getting $_POST input, putting it in variables, and then:
if( !empty($id && $name && $email) ) {
//do something
}
My first inclination was that passing multiple variables as an argument would throw an error, but it evaluates successfully. Am I incorrect that empty() should NOT take a boolean expression? Or - if I'm right - why does it work?
You can pass an expression to empty rather than a variable (since PHP 5.5), but with an expression like that you lose half of the benefit of using empty. empty checks that variables are set as well as evaluating their "truthiness". When you give it an expression like that, the individual variables within the expression are not checked to exist by empty. The expression is just evaluated as a boolean.
So if you used separate empty checks, you would get the check that the variables exist as well as the check that they are != false
if(!empty($id) && !empty($name) && !empty($email))
But when you use
if (!empty($id && $name && $email))
You will still get into the if block if all the variables are set and have non-false values, but you'll get undefined variable notices if any of them are not set. It's basically the same thing as not using empty at all, like this:
if ($id && $name && $email)
But if your guy is setting these variables from $_POST, they will be set, (if they weren't in $_POST he'd get undefined index warnings at that point) and the empty here is pointless anyway.

Will an If Statement Stop Checking if the first OR condition is met in PHP?

I want to try and make my code as efficient as possible and from what ive read
if($process == true)
Will process faster than something that calls a function. I.e
if(count($total) == 100)
So if i had an OR inside my if and the first condition was a simple boolean check and it turned out to be true would the second part of the condition still be checked anyway?
For example
$process = true;
if($process == true || count($total) == 100)
Would the count function still be called even though process is true and that is enough the make the condition pass.
PHP has indeed a mechanic named short-circuit:
http://php.net/manual/en/language.operators.logical.php#example-140
If the first operand of a logical OR is true, then the second part isn't evaluated, and the function isn't called.
Since comparing a variable to a boolean is faster than calling a function in PHP, this mechanic can help you to optimize, but never forget that premature optimisation is the root of all evil.
It will work same as exactly logical operator works. For example foo() will never get called.
if (false && foo()) {
}
if (true || foo()) {
}
In case of OR once it found a true statement it wont check further conditions,
In case of AND once it found a false statement it wont check further conditions.
its known as lazy evaluation.
illustration:
<?php
$var=0;
if($var++ || $var++){//Since 0 means false in Php both conditions will be checked
//Do nothing
}
echo $var;//output :2
if we change condition to if(++$var || $var++) the first condition will return true hence next condition will not be checked thus it will print output as 1;
If any statement inside a or is true other statements will not be checked and the if will be evaluated to true.
If you are checking a and statement all statements needs to evaluate to true and if any of them is false the stamen check will stop because the if is already false.
Just another important detail is that a function inside a if does not slow down the if check, what will slow down is what the function is doing and if it needs a lot of processing of course will be slower than just check a boolean but do not get afraid of use functions because they are very important in any system.
(I remember this from C# but I'm quite sure it's the same in php)
This depends if you use the single | or double || I think if you used the single ones it would still go do the other one ( usefull for when theres a function like loggin behind it ) if you use double and the first one is true it'll skip the second condition.
(This could be the other way around, so best bet is to try it using Javascript eg. create 2 function each returning true after alerting something, and thest these with either 1 line or 2)

Whats the difference in these two php conditions?

i am trying to check whther $_GET['id'] is set and is numeric else killing the code execution.,
following both codes are working for me , but would like to know whats the difference in between them ?
php condition 1
<?php
if(!isset($_GET['id']) || (isset($_GET['id']) && !is_numeric($_GET['id']))) {
die();
}
php condition 2
<?php
if(!isset($_GET['id']) || !is_numeric($_GET['id'])) {
die();
}
The difference is that the first one has an unnecessary extra check if $_GET['id'] is set. PHP uses what is called short-circuit boolean evaluation, which means that if the left side of an || is true, the right side doesn't need to be evaluated. So, even in the second example, !is_numeric($_GET['id']) will never get evaluated unless isset($_GET['id']) is true.
Logically these statements are equivalent.
You're basically doing
A || (!A && B)
if A is true, then the rest won't be executed.
If A is false, !A will be true anyway. So the !A is redundant.
Functionally they are the same, but in practice, you don't need the extra condition.
You can see the logical explanation here:
In the first one
It makes three checks which are unnecessary.
In the second it won't catch one of the conditions required
|| means OR - either one of the conditions should evaluate to true
&& means AND - both conditions must be true
To work properly you need this
if (!isset($_GET['id']) && !is_numeric[$_GET['id']])
die();
The first statement does the same thing but it check if $_GET['id'] is set two times which isn't needed.

PHP isset for submit form with or operator

Is it possible to add the "OR" operator to php isset submit form code when there are two submit buttons with different names?
Eg:
if (!isset($_POST['submitRequest'] || $_POST['submit']))
The above code prompts and an error. Please advice.
try:
if(isset($_POST['submitRequest']) || isset($_POST['submit'])){
//do something
}
No, it isn't possible. You need each variable in its own isset functioYou cannot combine them.
That's not how to use the or operator. You have to put it between two isset calls.
if ( ! isset($_POST['submitRequest']) || isset($_POST['submit']) ) { }
You always have to take a good look at the syntax. Remember that the or operator is used to make an entire condition evaluate to true if the left condition or the right condition is true. As such, you always need to use the or operator with two conditions.
Also, if you want to do this with the and operator, you can just use one isset call.
if ( isset($_POST['username'], $_POST['password']) ) { }
You need to call the isset function on respective variables individually. You have an option of using either of the two syntax, depending on the convention you follow.
if(isset($_POST['submitRequest']) || isset($_POST['submit'])){
//do something
}
if(isset($_POST['submitRequest']) OR isset($_POST['submit'])){
//do something
}
You can use isset() on multiple variables:
if(isset($_POST['submitRequest']) || isset($_POST['submit'])) {
// One of them was pushed
}
Be careful when passing multiple arguments to isset(). As the manual documents:
If multiple parameters are supplied then isset() will return TRUE only if all of the parameters are set. Evaluation goes from left to right and stops as soon as an unset variable is encountered.
So isset($_POST['submitRequest'], $_POST['submit']) would be the equivalent of isset($_POST['submitRequest']) && isset($_POST['submit']). However, that second sentence can be useful if you want to check !isset($_POST['submitRequest']) || !isset($_POST['submit']). Since when passed multiple arguments, isset() will return false for the first unset one, you can use !isset($_POST['submitRequest'], $_POST['submit']).
to elaborate a bit:
isset(), empty() and a few other are not functions, but language constructs. As such, they don't work in all the ways one might expect according to them looking like functions.
The important part here is: they only check variables, they can't and don't evaluate the results of expressions.
The use of || makes $_POST['submitRequest'] || $_POST['submit'] an expression. The result is only calculated temporarily, not stored in defined variable which can be set or empty.
I know I had misunderstood the original post.
if(isset($_POST['submitRequest'])||isset($_POST['submit'])){
// you can do something here
}
Original (incorrect)
You can use this:
if(!isset($_POST['submitRequest'], $_POST['submit'])){
die("Fail");
}
If multiple parameters are supplied, the function will check all of them. This will return TRUE only if all of the parameters are set.
Reference: http://php.net/manual/en/function.isset.php

Categories