Second check in or-statement not executed - php

In my php application i do the following check:
if(($images = $main->get_images($data['id'])) || ($videos = $main->get_videos($data['id']))){
(...)
if($videos){
(...)
}
if($images){
(...)
}
}
This operation sends back an error saying $videos is undefined. My guess is that if the first statement is true, the second wont be checked. Is there any neat way of preforming the second check, even is the first one is true, because in this case if images is true, videos will be evaluated as false

There isn't a way. You'll need to re-write it into something like this...
$images = $main->get_images($data['id']);
$videos = $main->get_videos($data['id']);
if($images || $videos){
(...)
if($videos){
(...)
}
if($images){
(...)
}
}
And just FYI... order of operations means you don't need to enclose the conditions in () brackets. Almost everything gets computed BEFORE the OR operator (including the && operator).
Good luck!
Joey

You can use empty() to see if a variable does not exist or is null e.g.
if(!empty($videos)) {
(...)
}

Related

PHP If (!isset(...) || !isset(...))

I'm trying to check if the first $_COOKIE['one'] exists OR the second $_COOKIE['two'] exists and if none exists to redirect the user.
Only one of those two cookies are going to exist when this script is running.
if (!isset($_COOKIE['one']) || !isset($_COOKIE['two'])) {
header('Location: ./');
} else {
...
}
I tried many things but every time I get into this if altough one of those cookies always exist.
This is a simple case of inverted logic. As Mark pointed out, you need to be using the boolean && (AND) operator. You are trying to see if both don't exist, then send the header. Currently, if either exists, you send the header anyway.
Just change if (!isset($_COOKIE['one']) || !isset($_COOKIE['two'])) {
to
if (!isset($_COOKIE['one']) && !isset($_COOKIE['two'])) {
Or (||) returns true if either the left or right of the statement is true. And (&&) returns true only if both parts of the statement are true. The Not(!) operator reverses true->false and false-> true.
isset tells you if the cookie exists. If the cookie exists, it returns true. You are correct in using not on this, as you want it to tell you if the cookie doesn't exist (opposite). However, you only want to send the header if BOTH cookies don't exist. Or will send it if one doesn't exist.
You wrote an opposite logic to what you really want.
You said that
You're trying to check if
That's an if conditional.
the first $_COOKIE['one'] exists
For that you use isset, which you did and it's right.
OR the second $_COOKIE['two'] exists
So you'd use the OR operator ( || )
and if none exists to redirect the user.
That's an else, and then use header to redirect.
Converting your words to literal code, you'd have this:
if (isset($_COOKIE['one']) || isset($_COOKIE['two'])) {
//... Do your thing
} else {
header('Location: ./');
}
Your code also works with the fix provided by Mark in the comments, but might confuse you in the future...
You can also do this to avoid nesting:
if (!(isset($_COOKIE['one']) || isset($_COOKIE['two']))) {
{
header('Location: ./'); exit;
}
//... Do your thing
If only one of the cookies will ever be set then then your if condition will always be true so the redirect will happen.
Change || for &&,
if (!isset($_COOKIE['one']) && !isset($_COOKIE['two'])) {
header('Location: ./');
} else {
//
}
More elegantly, isset() can handle muliple arguments and negating its return value will give you exactly what you want.
Code: (Demo)
var_export(!isset($cookie1, $cookie2)); // Are either missing? Yes, both are missing.
echo "\n";
$cookie1 = 'declared';
var_export(!isset($cookie1, $cookie2)); // Are either missing? Yes, one is missing.
echo "\n";
$cookie2 = 'declared';
var_export(!isset($cookie1, $cookie2)); // Are either missing? No, neither are missing.
Output:
true
true
false

Function executing order in an if statement php

I want to make a function for a "secure" php page that will check the token(the one passed by post and the one from the session). But I don't want to write two if statements like this:
function CheckToken(){
if(isset($_POST['token']) && isset($_SESSION['token']))
if($_POST['token']==$_SESSION['token']) return true;
return false;
}
Can I do something like this(?):
function CheckToken(){
if(isset($_POST['token']) && isset($_SESSION['token']) && $_POST['token']==$_SESSION['token']) return true;
return false;
}
Here's all about the order in which those functions are executed (when using the and operator).So if you're using the AND operand then if the first conditions is false don't evaluate the second. I remember that vb.net had a solution to this problem(evaluating only the first function-if it is false don't evaluate the second one). So, is it safe to put everything on a single line(like I did in the second example)?
PHP does the same thing as the usual if statement evaluation in other major languages, that is, check from left to right.
So if you have
if (cond1 && cond2 && cond3)
Scenario 1:
If cond1 is true, it will then execute cond2, and then cond3.
Sample: https://3v4l.org/Ap9SQ
Scenario 2:
If let's say cond2 is false, then cond3 will be ignored.
Sample: https://3v4l.org/u9P4O
Same goes to OR
if (cond1 || cond2 || cond3)
If cond1 is true, cond2 and cond3 will be skipped.
Sample: https://3v4l.org/ZAZcD
So since your function is just returning true or false, you can even simplify it to something like this:
function CheckToken() {
return isset($_POST['token']) &&
isset($_SESSION['token']) &&
$_POST['token'] == $_SESSION['token'];
}
Split lines for readability. Also checkout isset manual as you can pass in multiple variables for empty checking.
Yes, there really is no difference to changing the order like that. It is perfectly safe, because all it's doing is changing the look of the script while the execution is the EXACT same.
It would be best to do the second option.

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'

What is the best way to know is $_GET['example']=="somevalue"?

if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
OR
if((!empty($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
OR just
if($_GET['example']=='somevalue'){ ... }
I am asking that why I have seen many example where people check first if $_GET['example'] is set and then if $_GET['example']=='somevalue' ( first and second example above ).
I don't understand why not just use the last solution ( if $_GET['example']=='somevalue' then $_GET['example'] is obviously set ).
This question refers to any other variable ( $_POST, $_SERVER, ecc ).
if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
Is the right one, you want to know that the "variable" exists (or is set) in order to use it. Empty just checks wether it has data of any kind or not.
For example:
<?php
$foo= 0;
if (empty($foo)) { // True because $foo is empty
echo '$foo is either 0, empty, or not set at all';
}
if (isset($foo)) { // True because $foo is set
echo '$foo is set even though it is empty';
}
if (isset($var)) { // FALSE because $var was not declared before
...
}
?>
The differences between isset and empty are subtle but important. They are most relevant when used alone. If you are checking that a variable exists and is a truethy value (e.g. any string that is not all spaces or 0s) you can use either interchangeably.
When to use isset
Use isset when it's important to know if the variable has been defined and is not null:
if (isset($maybeExistsMaybeNull)) {
// variable defined and is not NULL
}
When to use !empty
Use !empty when it's important to know if the variable has be defined and is truthy
if (!empty($mightBeEmpty)) {
// variable defined, and isn't "", " ", 0, "0" etc.
}
!empty is a great shorthand for exists and is something.
When to use array_key_exists
Use array_key_exists when it's important to know if the key exists and the value is of no importance:
if (array_key_exists('something', $array)) {
// $array['something'] exists, could be literally anything including null
}
When not to use isset
If your code looks like this:
if (isset($something) && $something) {
// code is shorter with !empty
}
When not to use !empty
If your code looks like this:
if (!empty($something) && $something === "") {
// you meant isset. this is unreachable.
}
Then you're writing code that can't be executed
Code that throws errors is error prone
Avoid writing code that issues notices/warnings that you are ignoring. For example in the question:
if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }
The first use of example is an undeclared constant. Or is it undeclared - what if you've got define('example', "foo"); somewhere else in the code.
if($_GET['example']=='somevalue'){ ... }
If the url doesn't contain ?example=.. that's going to issue a notice too.
Writing code without displaying errors means you can very easily miss mistakes like the first.
In context: isset and !empty are equivalent
For the example given, these two language constructs act exactly the same.
There is no case where one will act differently than the other, neither will issue a notice if the variable is undefined, and no measurable difference in performance between the two.
As others have said for checking things like $_GET and $_POST you would ideally want to use:
if ( isset($_GET['example']) && $_GET['example'] =='somevalue' ) {
// process data
}
So you always want to firstly make sure that the variable has been set (and not set to null) or in other words exists. Then proceed to check if the variable contains the data that you were expecting. If you try to make reference to a variable which doesn't exist (by not checking isset()) php will give you a notice saying 'undefined variable...etc etc'.
If you wanted to find out if a variable is set but are not concerned too much by what then you could use:
if ( !empty($_GET['example']) ) {
// process data
}
But I would be careful about using empty() on strings in this regard as empty can behave strangely with string data like '0' or ' '.
So I would always do the first one, to a) make sure the variable exists and b) is what you were expecting it to be.
This is something that you'll probably do a lot of and it helps to put together a class/functions which handles this checking for you so you dont have to do it everytime.
function checkValue($key, $value) {
if(array_key_exists($key, $_REQUEST)){
if ($_REQUEST[$key] == $value) {
return true;
} else {
return false;
}
} else {
return false;
}
}
I just use Request as a default instead of switching out (though it is preferable to switch in some cases between POST and GET for security (imo)).
Now you can just call this function anywhere
if (checkValue('Item', 'Tom') === true){} etc
the best is
if((isset($_GET[example]))&&('somevalue'==$_GET['example'])){ ... }
The difference between
'somevalue'==$_GET['example']
AND
$_GET['example']=='somevalue'
If you mistype the == and type = instead, the first notaion will raise an error to notify you.
if((isset($_GET[example]))&&($_GET['example']=='somevalue')){ ... }

testing for var that might be array/empty array/false

I have a function that will perform a SELECT query from some db and return either:
false (in case of error)
an empty array array(0) { }
an associative array
In order to test the return value of this function, is it good practice to do :
$someVar = $this->someFunction();
if ($someVar) {
// ok, this is an associative array of result
} else {
// $someVar = false OR $someVar is an empty array
}
Or do I have to do something like this instead :
$someVar = $this->someFunction();
if (is_array($someVar) && count($someVar) > 0) {
// ok, this is an associative array of result
} else {
// $someVar = false OR $someVar is an empty array
}
The first test seems to do what I want, but maybe I'm missing something that might go wrong after.
So, is it good practice test arrays like I did in my first example?
Neither.
Returning false to indicate error is fine at a very low level, but there should a layer between your low-level queries and your application code which inspects the return value and throws an exception on false. The top-level controller which invokes your code should be handling those exceptions (which aren't caught earlier) and displaying a user-friendly error page in production, or dumping debugging information in development, while logging the error.
There is absolutely no way you should be doing a three-way if/elseif/else branch in your application to inspect the return values of every single database query. This is an incredibly dated way of checking for errors.
Throw exceptions, and you can use your first form (if ($someVar)) or, better yet:
foreach ($this->someFunction() as $key => $row) {
}
http://php.net/manual/en/types.comparisons.php
An empty array evaluates to false. An array with values evaluates to true (even if all values would individually evaluate to false).
You can also check if (empty($array)) but it is redundant to do so unless you are concerned about the array variable not being set.
Finally, if the array is empty, $array == false is true, but $array === false is not.
According to the documentation on type comparisons, your first method is completely acceptable. An empty array will always evaluate to FALSE.
Documentation: http://php.net/manual/en/types.comparisons.php
That said, you may choose to handle no results and errors differently, e.g. logging the error message to a server log. In this case, you may want multiple if() conditions.
Neither. Test for all three cases:
if (false === $result) {
die('There is an error!');
} elseif (empty($result)) {
die('No results found');
}
foreach ($result as $foo) { ... }
If you really want to test for just two, then remember that foreach will work in an empty array. So, this will work:
if (false === $result) {
die('There was an error!');
}
foreach ($result as $foo) { ... }
Or:
if (false === $result) {
echo 'There was an error!';
} else {
foreach ($result as $foo) { ... }
}
These last examples will simply give an empty page when the $result is an empty array. The first example will say that there are no results.

Categories