Exclamation mark in front of variable - clarification needed - php

I've been working with PHP for quite a while now, but this was always a mystery to me, the correct use of the exclamation mark (negative sign) in front of variables.
What does !$var indicate? Is var false, empty, not set etc.?
Here are some examples that I need to learn...
Example 1:
$string = 'hello';
$hello = (!empty($string)) ? $string : '';
if (!$hello)
{
die('Variable hello is empty');
}
Is this example valid? Would the if statement really work if $string was empty?
Example 2:
$int = 5;
$count = (!empty($int)) ? $int : 0;
// Note the positive check here
if ($count)
{
die('Variable count was not empty');
}
Would this example be valid?
I never use any of the above examples, I limit these if ($var) to variables that have boolean values only. I just need to know if these examples are valid so I can broaden the use of the if ($var) statements. They look really clean.
Thanks.

if(! $a) is the same as if($a == false). Also, one should take into account that type conversion takes place when using == operator.
For more details, have a look into "Loose comparisons with ==" section here. From there it follows, that for strings "0" and "" are equal to FALSE ( "0"==false is TRUE and ""==false is TRUE, too).
Regarding posted examples:
Example 1
It will work, but you should note, that both "0" and "" are 'empty' strings.
Example 2
It will work

It's a boolean tester. Empty or false.

It's the not boolean operator, see the PHP manual for further detail.

Related

Is there a compelling reason to use PHP's operator === in comparison operations, over ==?

Say I have this code:
$str = '5';
$int = 5;
For comparison, is there any reason to use something like this (with conversion):
if ($int === intval($str)) //...
or do I just use native PHP facilities?
if ($int == $str) //...
To me, == looks simpler, perhaps at the expense of having PHP do the extra work for me.
Using '==' tends to lead to subtle bugs - eg if two strings look like numbers, PHP does not compare them as strings, which can give unexpected results - the most common/scary example is:
<?php
$actual_password = '240610708';
$provided_password = 'QNKCDZO';
// These would presumably be stored in your database
$stored_password_md5 = md5($actual_password); //0e462097431906509019562988736854;
$stored_password_hash = password_hash($actual_password, PASSWORD_DEFAULT);
$computed_password_md5 = md5($provided_password); //0e830400451993494058024219903391
var_dump($stored_password_md5 == $computed_password_md5); // bool(true) - BAD! NO!
var_dump($stored_password_md5 === $computed_password_md5); // bool(false) - Better, but still no. Vulnerable to timing attacks
var_dump(hash_equals($stored_password_md5, $computed_password_md5)); // bool(false) getting somewhere
var_dump(password_verify($provided_password, $stored_password_hash)); // bool(false) best
While in your specific example, this problem doesn't occur, the possible problems lead to a lot of people recommending to /always/ use ===, so you don't have to remember when == is safe and when it isn't.
Depends on what you are trying to do. Some functions might return false or 0 or a positive integer, like strpos(). 0 means the string was found at position 0 so == false would not work as === false.
In your scenario it is fine to use == as this is common when getting values from a DB or $_POST and $_GET, they will always be strings.
Thanks to the comment from Fred Emmott: Be careful, the following return true:
var_dump('0xa' == '10'); // 0xa hex 10 in decimal
var_dump('10pigs' == 10); // pigs truncated
See String conversion to numbers
The == operator just checks to see if the left and right values are equal. But, the === operator (note the extra “=”) actually checks to see if the left and right values are equal, and also checks to see if they are of the same variable type (like whether they are both booleans, ints, etc.).

how ordering makes a difference within an expression for an if statement

I have an array ...
$a= array(1,2,3,4);
if (expr)
{ echo "if";
}
else
{ echo 'else';
}
When expr is ( $a = '' || $a == 'false') , output is "if" ,
but when expr is ( $a == 'false' || $a = '' ) , output is "else"
Can anyone explain why & how ordering makes a difference ??
Edit : I understand that I am assigning '' to $a. That is not the problem. The real question is : What does the expression $a = '' return? And why does reversing the order of the 2 situations switch us from the IF section to the ELSE section?
AGAIN : I UNDERSTAND I AM ASSIGNING NOT COMPARING. PLEASE ANSWER THE QUESTION AS IS.
First, never use = as a comparison operator. It is an assignment operator.
The difference is that false (as a boolean) is not the same as 'false' as a string.
Certain expressions are type juggled by PHP to evaluate somewhat differently to how you would expect.
false==""
// TRUE.
false=="false"
// FALSE.
Additionally, when you try to compare numbers to strings, PHP will try to juggle the data so that a comparison will be performed. There is a lot to it (much more than I will post here) but you would do well to investigate type juggling and various operators. The docs are a great start for this. You should also have a read of the comparison operators which go into a lot of detail about how various comparisons will work (depending on whether you use == or === for example).
With $a = '' you are setting $a to an empty string. This is the same as:
$a = '';
if($a){
echo 'if';
}
The || operator checks if the first condition is true and if it is, it continues with the code in the brackets. In PHP, if $a is set to anything, it will return true. In the second case $a does not equal the string 'false' (you are not comparing it to a boolean false even!), so it executes the code in the else part.
And Fluffeh is not entirely correct. You can use the assignment operator in an if condition very effectively, you just have to be smart about it.
$a = '' is an assignment: you have, in error, used = in place of ==. Assignment is an expression which has the value of the thing your assigning.
A single equals sign = is the assignment opporator, so $a = '' is assigning an empty string to $a not checking if it is equal to.
In your 1st example you set the value of $a to an empty string, then check if it is false. An empty tring evalutes to false in php, so the conditional is true.
In your second example, you check if $a equals false 1st (when the value of $a is an array), so the conditional is false

Finding common characters in strings

I am tring this method to find the common characters in two strings namely, $a and $r, but the first character isn't getting printed . Moreover the $already collects the common characters and prevents them from being printed for multiple times( I need each character to be printed once only) but it isn't doing so. Please tell me what errors I am making.
<?php
$a="BNJUBCI CBDIDIBO";
$r="SBKJOJLBOU";
$already="";
for($i=0;$i<strlen($r);$i++)
{
if (stripos($a,$r[$i])!=FALSE)
{
if (stripos($already,$r[$i])==FALSE)
{
$already=$already.$r[$i];
echo "already=".$already."<br>";
echo $r[$i]."<br>";
}
}
}
?>
Use !==FALSE instead of !=FALSE. The problem is that stripos returns 0 if the needle is at the start of the haystack, and 0 is falsy. By using !== you are forcing it to ensure the result is actually false, and not just 0.
This is actually listed in the docs. An "RTM" might be appropriate here.
Warning
This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
The simplest way to find the intersection of the two strings in PHP is to turn them into arrays and use the built-in functions for that purpose.
The following will show all the unique and common characters between the two strings.
<?php
$a="BNJUBCI CBDIDIBO";
$r="SBKJOJLBOU";
$a_arr = str_split($a);
$r_arr = str_split($r);
$common = implode(array_unique(array_intersect($a_arr, $r_arr)));
echo "'$common'";
?>
I would think a much simpler solution to this would be to make the strings into arrays and compare those no?
Something like:
<?php
$a="BNJUBCI CBDIDIBO";
$r="SBKJOJLBOU";
$shared = implode( '' , array_intersect( str_split($a) , str_split($r) ) );
?>
That should return you a string of all the characters in $a that are present in $r

PHP if condition with strings

I am trying to write would be a simple if condition.
function genderMatch($consumerid1, $consumerid2)
{
$gender1=getGender($consumerid1);
$gender2=getGender($consumerid2);
echo $gender1;
echo $gender2;
if($gender1=$gender2)
echo 1;
return 1;
else
echo 0;
return 0;
}
The output of the getGender function is either a M or F. However, no matter what I do gender1 and gender2 are returned as the same. For example I get this output: MF1
I am currently at a loss, any suggestions?
if ($gender1 = $gender2)
assigns the value of $gender2 to $gender1 and proceeds if the result (i.e. the value of $gender2) evaluates to true (every non-empty string does). You want
if ($gender1 == $gender2)
By the way, the whole function could be written shorter, like this:
function genderMatch($cid1, $cid2) {
return getGender($cid1) == getGender($cid2);
}
You have to put two == for comparison. With only one, as you have right now, you are assigning the value to the first variable.
if($gender1=$gender2)
would become
if($gender1==$gender2)
this:
if($gender1=$gender2)
should be
if($gender1==$gender2)
notice the extra ='s sign. I think you might also need curly brackets for multiple lines of an if/else statement.
Your using the assignment operator = instead of comparsion operators == (equal) or === (identical).
Have a look at PHP operators.
You have some structural problems with your code as well as an assignment instead of a comparison.
Your code should look like this:
function genderMatch($consumerid1, $consumerid2){
$gender1=getGender($consumerid1);
$gender2=getGender($consumerid2);
echo $gender1;
echo $gender2;
if($gender1==$gender2){
echo 1;
return 1;
}else{
echo 0;
return 0;
}
}
Notice the double '=' signs in the if statement. This is a comparison. A single '=' is an assignment. Also, if you want to execute more than 1 line of code with an if/else, you need brackets.
You are using a single = which sets the variable, ie. the value of $gender1 is set to be the value of $gender2.
Use the === operator instead: if($gender1 === $gender2). It is usually a good idea to do strict comparisons rather than loose comparisons.
Read more about operators here: php.net
Another alternative is to use strcmp($gender1, $gender2) == 0. Using a comparer method/function is more common in languages where the string-datatype isn´t treated as a primary data-type, eg. C, Java, C#.

PHP best way to check whether a string is empty or not

I've seen a lot of php code that does the following to check whether a string is valid by doing:
$str is a string variable.
if (!isset($str) || $str !== '') {
// do something
}
I prefer to just do
if (strlen($str) > 0) {
// something
}
Is there any thing that can go wrong with the second method? Are there any casting issues I should be aware of?
Since PHP will treat a string containing a zero ('0') as empty, it makes the empty() function an unsuitable solution.
Instead, test that the variable is explicitly not equal to an empty string:
$stringvar !== ''
As the OP and Gras Double and others have shown, the variable should also be checked for initialization to avoid a warning or error (depending on settings):
isset($stringvar)
This results in the more acceptable:
if (isset($stringvar) && $stringvar !== '') {
}
PHP has a lot of bad conventions. I originally answered this (over 9 years ago) using the empty() function, as seen below. I've long since abandoned PHP, but since this answer attracts downvotes and comments every few years, I've updated it. Should the OP wish to change the accepted answer, please do so.
Original Answer:
if(empty($stringvar))
{
// do something
}
You could also add trim() to eliminate whitespace if that is to be considered.
Edit:
Note that for a string like '0', this will return true, while strlen() will not.
You need isset() in case $str is possibly undefined:
if (isset($str) && $str !== '') {
// variable set, not empty string
}
Using !empty() would have an important caveat: the string '0' evaluates to false.
Also, sometimes one wants to check, in addition, that $str is not something falsy, like false or null[1]. The previous code doesn't handle this. It's one of the rare situations where loose comparison may be useful:
if (isset($str) && $str != '') {
// variable set, not empty string, not falsy
}
The above method is interesting as it remains concise and doesn't filter out '0'. But make sure to document your code if you use it.
Otherwise you can use this equivalent but more verbose version:
if (isset($str) && (string) $str !== '') {
// variable set, not empty string, not falsy
}
Of course, if you are sure $str is defined, you can omit the isset($str) from the above codes.
Finally, considering that '' == false, '0' == false, but '' != '0', you may have guessed it: PHP comparisons aren't transitive (fun graphs included).
[1] Note that isset() already filters out null.
This will safely check for a string containing only whitespace:
// Determines if the supplied string is an empty string.
// Empty is defined as null or containing only whitespace.
// '0' is NOT an empty string!
function isEmptyString($str) {
return !(isset($str) && (strlen(trim($str)) > 0));
}
What about this:
if( !isset($str[0]) )
echo "str is NULL or an empty string";
I found it on PHP manual in a comment by Antone Roundy
I posted it here, because I did some tests and it seems to work well, but I'm wondering if there is some side effect I'm not considering. Any suggestions in comments here would be appreciated.
According to PHP empty() doc (http://ca1.php.net/empty):
Prior to PHP 5.5, empty() only supports variables; anything else will result in a parse error. In other words, the following will not work: empty(trim($name)). Instead, use trim($name) == false.
This simple old question is still tricky.
strlen($var) works perfectly ONLY if you're absolutely sure the $var is a string.
isset($var) and empty($var) result are based on type of the variable, and could be tricky at some cases (like empty string ""). View the table in this page for more details.
UPDATE
There are actually 2 cases for this question:
Case 1: You're sure that your variable is always going to be a "string":
In this case, just test the length:
if(strlen($str) > 0) {
// do something..
}
Case 2: Your variable may and may not be a "string":
In this case, it depends on what you want to do. For me (most of the time), if it's not a string then I validate it as "false". You can do it this way:
if(is_string($var) && $var !== '') {// true only if it's a string AND is not empty
// do something ...
}
And to make it shorter and in 1 condition instead of 2 (specially useful if you're testing more than 1 string in same if condition), I made it into function:
function isNonEmptyString($var) {
return is_string($var) && $var !== '';
}
// Somewhere else..
// Reducing conditions to half
if(isNonEmptyString($var1) && isNonEmptyString($var2) && isNonEmptyString($var3)) {
// do something
}
If your variable $str is not defined then your strlen() method will throw an exception. That is the whole purpose of using isset() first.
trimming the string will also help if there are string with white spaces.
if (isset($str) && trim($str) !== '') {
// code
}
I think not, because strlen (string lenght) returns the lenght (integer) of your $str variable.
So if the variable is empty i would return 0. Is 0 greater then 0. Don't think so.
But i think the first method might be a little more safer. Because it checks if the variable is init, and if its not empty.

Categories