This question already has answers here:
php array_search returning 0 for the first element?
(4 answers)
How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ?
(13 answers)
Closed 5 years ago.
Why does example A fail, but example B work?
A) FAIL:
$request_IP = '8.8.8.8';
$list_Array = explode(',', "8.8.8.8,9.9.9.9,2.2.2.2");
$result = array_search($request_IP, $list_Array);
if($result) {
// Expecting - to get it success there
}
else {
echo "FAIL";
exit;
}
B) WORKS:
$request_IP = '8.8.8.8';
$list_Array = explode(',', "0,8.8.8.8,9.9.9.9,2.2.2.2");
$result = array_search($request_IP, $list_Array);
if($result) {
// In this case it works??
}
else {
echo "FAIL";
exit;
}
From the documentation for array_search:
Returns the key for needle if it is found in the array, FALSE otherwise.
So you should change your code to:
$result = array_search($request_IP, $list_Array);
if ($result === false) {
// Not found
echo "FAIL";
exit;
} else {
// $result is the key of the element in the array
echo $result . "\n";
}
Example A matches properly, it returns index 0.
0 is a falsy variable. 0 == false.
Look at https://secure.php.net/manual/en/types.comparisons.php what kind of values match to which result when doing loose comparisan(two ==) in the boolean column
You can better flip the if statements, to test for the false first.
We don't need an "else" here because either the code will abort in the if statement, or it will continue.
Saves an indentation level.
if($result === false) {
echo "FAIL";
exit;
}
// success
Three === means an exact match on value AND type
That's because in section A,
array_search($request_IP, $list_Array) will return zero.
so next condition line would compile as following:
if ($result) // if (0)
this condition will always return false.
To fix this issue. you have to use following line
if ($result === FALSE)
Because in your first example array_search will return 0 - because the first occurence of 8.8.8.8 is the first item. PHP is designed "weakly", so an assertion of "0" and boolean false will be true (false == 0) and an assertion of 1 and true will also be true (true == 1). This can be very tricky - as for example strpos returns 0 if a pattern is in the beginning of a string, in that case you would need to write your condition like (strpos($string, $search) !== false) - simply checking the return type "weakly" would result in a logic error (!strpos($string, $search).
You will have to adopt the condition.
I would recommend to use in_array
if (in_array($request_IP, $list_Array) === true)
will do
You should also have a look at this question:
What are the benefits (and drawbacks) of a weakly typed language?
Weak types is not bad design, its concept, if you use PHP or any other weakly typed language for business logic, you will need to be extra careful, using strict comparison only (=== instead of ==, !== instead of != and explicit comparison instead of negation) is a good start.
Related
This question already has answers here:
Is there a difference between !== and != in PHP?
(7 answers)
difference between != and !== [duplicate]
(4 answers)
The 3 different equals
(5 answers)
Closed 3 years ago.
I have two statements like this:
$ready = true;
if($ready === true) {
echo "it's ready!";
}
And this:
$ready = true;
if($ready !== false) {
echo "it's ready!";
}
I know those mean the same thing as === true and !== false is the same thing. I see people use the negation type (is not false or is not {something}). like this: https://stackoverflow.com/a/4366748/4357238
But what are the pros and cons of using one or the other? Are there any performance benefits? Any coding benefits? I would think it is confusing to use the negation type rather than the straight forward === true. Any input would be appreciated! thank you
These do not mean the same thing, and you can see this demonstrated below:
$ready = undefined;
if($ready === true) {
console.log("it's ready 1");
}
if($ready !== false) {
console.log("it's ready 2");
}
When in doubt, stick with ===. You're comparing to exactly what it should be. "This should exactly be equal to true" vs "This should be equal to anything but exactly false" are 2 separate statements, the second including a lot of values that would be true (As demonstrated above, undefined is not exactly false, so this would be true).
Most PHP functions return false as failure, such as strpos, from the manual it says:
Returns the position of where the needle exists relative to the
beginning of the haystack string (independent of offset). Also note
that string positions start at 0, and not 1.
Returns FALSE if the needle was not found.
So it returns an integer or false, then it is wrong to use strpos() === true
strpos() !== false is the right way to check the result.
It is not about performance and they are not the same. It helps us in reducing unnecessary if else statements.
Consider this: there is a variable foobarbaz whose value can be anything among foo/ bar/ baz/ foobar/ barbaz. You need to execute a statement if the value is not foo. So instead of writing like this:
if(foobarbaz === "bar" || foobarbaz === "baz" || foobarbaz === "foobar" || foobarbaz === "barbaz") {
//some statement
}
else if(foobarbaz === "foo") {
//do nothing
}
You can write something like this:
if(foobarbaz !== "foo") {
//some statement
}
You can see we were able to eliminate the unnecessary else statement.
In php == compare only the values are equal. For and example
$ready = 'true';
if($ready == true) {
echo "true";
}
else{
echo "false";
}
It print true.But if it is compare with === it not only check the values but also it check the datatype. So it compares with === it print the false.
Talking about !== it's work as the same. So it's not a problem to output if you use
if($ready === true)
or
if($ready !== false)
Can't compare these two because both are same.
I am trying to filter a specific column in an array in php using the code below:
(strpos( 'meeting',$event['categories'] ) == false )
It is not working actually. An example of what [categories] hold is:
$event['categories'] = 'meeting;skype'
Thanks in advance!
You need to flip the arguments to strpos():
if (strpos($event['categories'], 'meeting') === false) {
echo $event['categories'] . ' does not contain "meeting"';
}
Also, use strict comparison (=== vs ==), as meeting could be at the start of the string, and then strpos() would return 0, which would evaluate to false (which would be wrong in that case).
For reference, see:
http://php.net/manual/en/function.strpos.php
For an example, see:
https://3v4l.org/Ab4ud
I think you should use === not == and also flip the arguments
(strpos($event['categories'] , 'meeting') === false )
strpos could return 0 or false and when you use == then zero is like false
see compression operators
see strpos() docs
<?php
$event = ['categories' => 'meeting;skype'];
$needle = 'meeting';
$haystack = $event['categories'];
if( ($pos = strpos( $haystack, $needle )) === false){
echo "\n$needle not found in $haystack";
}
else
{
echo "\n$needle exists at position $pos in $haystack";
}
See demo
The two things to watch out for are the order of the parameters for strpos() as well as doing a strict comparison using the identity operator ("===") so that when the 'needle' appears at position zero of the 'haystack' it's not mistakenly deemed a false result which occurs if you use the equality operator ("=="), given that in PHP zero == false.
I had the following in my code:
$mixed = array();
$mixed[0] = "It's a zero!";
$mixed['word'] = "It's a word!";
foreach ($mixed as $key => $value) {
if ($key == 'word') {
echo $value.'<br />';
}
}
The above would for some reason print both "It's a zero!" and "It's a word!". I was expecting it to print only "It's a word!". Why is that?? I feel like I am missing something important. When I was using === in the if statement, it worked as expected, in other words it printed only "It's a word!". I know there's a difference between the equal and identical operators, but the first example is not equal is it?
== does the type-conversion for you before comparison.
When you did an == with an integer 0, it converted 'word' into the appropriate integer value.
intval() returns 0 when supplied a pure-string, so 0 matched. The other was matched in string-context, and that matched as well.
=== does no such implicit conversion, so it returned true only in one case, when the strings were actually identical.
PHP variables have type.
== checkes equality after conversion to the same type, === also checks the type. Use var_dump to see what the real types are.
See #Cthulhu 's answer above which is much clear.
Apart from that, here is a different example.
strpos() function returns the position of the needle from haystack.
<?php
$pos_a = strpos('apple', 'a'); // a is in the first position.
$pos_b = strpos('apple', 'b'); // there is no b.
if ($pos_a){
echo 'we got a!'."\n";
}
if ($pos_b){
echo 'we got b!'."\n";
}
strpos return FALSE if the needle is not found. But you will see that php does not run any echo statement.
If you var_dumo()'d these 2 values, you will see that $pos_a and $pos_b contain 0 and FALSE.
if statement just failed because 0 and FALSE both are considered FALSE unless you use ===
Now try this:
<?php
$pos_a = strpos('apple', 'a'); // a is in the first position.
$pos_b = strpos('apple', 'b'); // there is no b.
if ($pos_a !== FALSE){
echo 'we got a!'."\n";
}
if ($pos_b !== FALSE){
echo 'we got b!'."\n";
}
Now you will see the desired result as it echos "we got a!".
$a == $b Equal TRUE if $a is equal to $b after type juggling.
$a === $b Identical TRUE if $a is equal to $b, and they are of the same type.
it looks that
if you check 0 against a string with == then PHP returns true:
php -r 'var_dump(0 == "statuses");'
-> returns TRUE
but not if your string has a number at the beginning:
php -r 'var_dump(0 == "2statuses");'
-> returns FALSE
from the specs I get it that it attempts a conversion - in this case the string to number.
so better use ===
http://php.net/manual/en/language.operators.comparison.php
Aren't these equivalent?
==SCRIPT A==
if (file_exists($file) == false) {
return false;
}
==SCRIPT B==
if(!file_exists($file)) {
return false;
}
Plain answer: Y E S
They evaluate to the same thing.
That first one might be even better suited like this:
if (file_exists($file) === false) { // === checks type and value
return false;
}
OR:
return file_exists($file);
yes, file_exists returns a boolean, so it's either true or false.
so you could return file_exists($file) as well...
If you are making boolean comparisons, then you would rather do this:
if (file_exists($file) === false) {
return false;
}
using the === operator, to ensure that what you are receiving is a variable of type boolean and of value equivalent to false.
Yes.
But if you would use:
if (file_exists($file) === false) {
return false;
}
then it would not be the same as:
if(!file_exists($file)) {
return false;
}
because in the first case it would check whether the value returned by function matches strictly to false, and in the second case the value returned by function would be evaluated to boolean value.
EDIT:
That is general rule.
But in case of file_exists() function, which returns boolean value, evaluating to boolean is not necessary, thus you can use strict condition and this will have the same result (but only in case you know the value will be either true or false.
If you're asking "what's the difference between the === and == operator" then:
'===' is a strict comparison that checks the types of both sides.
'==' is an 'equivalent to' comparison operator that will cast either side to the appropriate type if deemed necessary.
To expand, '==' can be used to check for 'falsey' values and '===' can be used to check for exact matches.
if (1 == TRUE) echo 'test';
>> "test"
if (1 === TRUE) echo 'test';
>>
If you're asking if there's any functional / practical difference between your two code blocks then no, there isn't and you should be returning as such: return file_exists($file);
Worth a read:
http://php.net/manual/en/language.operators.comparison.php
I have a string in $str variable.
How can I verify if it starts with some word?
Example:
$str = "http://somesite.com/somefolder/somefile.php";
When I wrote the following script returns yes
if(strpos($str, "http://") == '0') echo "yes";
BUT it returns yes even when I wrote
if(strpos($str, "other word here") == '0') echo "yes";
I think strpos returns zero if it can't find substring too (or a value that evaluates to zero).
So, what can I do if I want to verify if word is in the start of string? Maybe I must use === in this case?
You need to do:
if (strpos($str, "http://") === 0) echo "yes"
The === operator is a strict comparison that doesn't coerce types. If you use == then false, an empty string, null, 0, an empty array and a few other things will be equivalent.
See Type Juggling.
You should check with the identity operator (===), see the documentation.
Your test becomes:
if (strpos($str, 'http://') === 0) echo 'yes';
As #Samuel Gfeller pointed out: As of PHP8 you can use the str_starts_with() method. You can use it like this:
if (str_starts_with($str, 'http://')) echo 'yes';
PHP does have 2 functions to verify if a string starts with a given substring:
strncmp (case sensitive);
strncasecmp (case insensitive);
So if you want to test only http (and not https), you can use:
if (strncasecmp($str,'http://',7) == 0) echo "we have a winner"
check with
if(strpos($str, "http://") === 0) echo "yes";
as == will turn positive for both false & 0 check the documentation
Another option is:
if (preg_match("|^(https?:)?\/\/|i", $str)) {
echo "the url starts with http or https upper or lower case or just //.";
}
As shown here: http://net.tutsplus.com/tutorials/other/8-regular-expressions-you-should-know/
strncmp($str, $word, strlen($word))===0
Is a bit more performant than strpos
Starting with PHP 8 (2020-11-24), you can use str_starts_with:
if (str_starts_with($str, 'http://')) {
echo 'yes';
}
PHP 8 has now a dedicated function str_starts_with for this.
if (str_starts_with($str, 'http://')) {
echo 'yes';
}
if(substr($str, 0, 7)=="http://") {
echo("Statrs with http://");
}
There's a big red warning in the documentation about this:
This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE, such as 0 or "". Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
strpos may return 0 or false. 0 is equal to false (0 == false). It is not identical to false however, which you can test with 0 === false. So the correct test is if (strpos(...) === 0).
Be sure to read up on the difference, it's important: http://php.net/manual/en/language.operators.comparison.php