This should be pretty straightforward, but I can't seem to find an explanation anywhere on how to do it.
I have a string in PHP. That string might contain within it somewhere the substring ":ERROR:". I need to find if it has that string. strpos() has worked perfectly up to this point, until today when ":ERROR:" was the first item in the string, so strpos() returned 0, so the program kept running thinking it had no error.
I don't need to replace the string, or do any manipulation to it, I just need a simple true/false answer to "does :ERROR: exist in the string?"
strpos returns false when the string is not found, so check for false instead of making an implicit condition.
if(strpos($string, ':ERROR:') !== false) {
// Do something...
}
As Anurag said in the comments, with functions like these it's always best to do a strict comparison (=== instead of just leaving out the operator or using ==) because that's a common source of bugs, especially in PHP, where many functions can return values of different types.
The PHP Manual on strpos():
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.
if (strpos($myString, ":ERROR:") !== FALSE) {
// Error!
}
You can also avoid the strpos() problems of not checking with a strict type operator by using the lesser known strstr()
if(strpos($string, ':ERROR:') !== false){
//found ':ERROR:' in string
}
"[strpos()] [r]eturns the position as an integer. If needle is not found, strpos() will return boolean FALSE."
http://php.net/manual/en/function.strpos.php
If the position is 0, then merely using == or != will evaluate 0 and false as equivalent. So use === or !== to avoid type coercion.
Related
I am working on the following snippet. What is the point of using !== 0 inside the first if condition while even the second condition is returning same result without using !== 0?
I was following some online tutorial and noticed that most developer are using the !== 0 but I accidentally noticed that I am also getting same result back , at least in this specific example without using !== 0
<?php
$name1 = "Geeks";
$name2 = "geeks";
if (strcmp($name1, $name2) !== 0) {
echo 'Strings are not equal';
}
else {
echo 'Strings are equal';
}
if (strcmp($name1, $name2)) {
echo 'Strings are not equal';
}
else {
echo 'Strings are equal';
}
?>
The "===" and "!==" comparison operators assert two things:
The values are equal, and
The values are of the same type
The short answer to your question "what is the point of using !== with the strcmp function" is simply "it's good practice". That's really the only reason regarding strcmp specifically, and != would give you the exact same result when it comes to that function.
The long answer is as follows:
PHP is traditionally a loosely typed language. That is, datatypes were not all that important and PHP implicitly cast types for you automatically. It still does this by default (although lots of stuff has been added to improve the situation over recent years). For example, if you add the string "1" to the integer 1, PHP will cast the string to an integer automatically and return the integer value 2. Strongly typed languages would return an error if you tried to do that. Another example is that PHP will cast 0 to boolean false and any other non-zero value to boolean true.
It's that second example that causes problems with some of PHP's built-in functions. For example, the strpos() function. If you check the documentation page for strpos you'll see a big "Warning" in the "Return Values" section stating "This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE". For that reason it advises you to use the "===" operator to make sure you are getting the exact value and type that you expect. So "=== 0" means the string was found at the beginning of the input, and "=== false" means the string was not found. If you just used "== false" you won't be distinguishing between the string being found at the beginning of the input and the string not being found at all (because 0 will be implicitly cast to boolean false for the "if" statement).
So, developers got into the habit of testing for equality and type by using "===" and "!==". It's a good habit.
Since strcmp always return an integer, and you are always comparing it to an integer, there is no implicit casting and so comparing types as well as equality is not neccessary.
I was looking into trying to revise some old code in an application that I work on. Currently the app parses out portions of a response string received from an API to determine if a request is good or if it failed. The response from the API sends back a string that contains the characters "DP" if the request was processed successfully. Right now there's a line of code in the app that is as follows:
if(stripos($result, "DP") !== false)
This is working fine now, but I can foresee an issue coming from this. stripos can return a "falsey" value even when the needle is in fact found within the haystack. Since the haystack string is zero-indexed with stripos the function will return 0 if the characters "DP" are found at the very beginning of the haystack string, which will incorrectly be read as false. This code is working now, but if for any reason the developers who maintain the API we work with decide to reformat their response, we will have problems. I was thinking of changing this to the following:
if(stristr($result, "DP") !== false)
From what I can tell this should be OK because according to php.net stristr only returns false if the needle is not found in haystack. I'm curious though if anybody has seen any problems similar to the one described above occurring with the stristr function.
0 doesn't equal false if you use === (or !==).
See this fiddle for proof: http://phpfiddle.org/main/code/nih-esg
More info on the PHP site here: http://www.php.net/manual/en/language.operators.comparison.php
Since your using !== it is a non issue, since the tripple operators checks both value and type
false != 0 : false
false !== 0 : true
<?php
$result="DP";
if (stripos($result, "DP") !== false)
{
echo stripos($result, "DP");
}
?>
Returns 0 from within brackets.
I see a lot of people using a variety of different methods to check whether of a variable is empty, there really seems to be no consensus. I've heard that if($foo) is exactly the same as if(!empty($foo)) or if($foo != ""). Is this true?
I realize it's a really simple question, but I'd really like to know. Are there any differences? Which method should I use?
Difference between bare test and comparison to empty string
if($foo != "") is equivalent to if($foo) most of the time, but not always.
To see where the differences are, consider the comparison operator behavior along with the conversion to string rules for the first case, and the conversion to boolean rules for the second case.
What I found out is that:
if $foo === array(), the if($foo != "") test will succeed (arrays are "greater than" strings), but the if($foo) test will fail (empty arrays convert to boolean false)
if $foo === "0" (a string), the if($foo != "") test will again succeed (obviously), but the if($foo) test will fail (the string "0" converts to boolean false)
if $foo is a SimpleXML object created from an empty tag, the if($foo != "") test will again succeed (objects are "greater than" strings), but the if($foo) test will fail (such objects convert to boolean false)
See the differences in action.
The better way to test
The preferred method to test is if(!empty($foo)), which is not exactly equal to the above in that:
It does not suffer from the inconsistencies of if($foo != "") (which IMHO is simply horrible).
It will not generate an E_NOTICE if $foo is not present in the current scope, which is its main advantage over if($foo).
There's a caveat here though: if $foo === '0' (a string of length 1) then empty($foo) will return true, which usually is (but may not always be) what you want. This is also the case with if($foo) though.
Sometimes you need to test with the identical operator
Finally, an exception to the above must be made when there is a specific type of value you want to test for. As an example, strpos might return 0 and also might return false. Both of these values will fail the if(strpos(...)) test, but they have totally different meanings. In these cases, a test with the identical operator is in order: if(strpos() === false).
No it's not always true. When you do if($foo) PHP casts the variable to Boolean. An empty string, a Zero integer or an empty array will then be false. Sometimes this can be an issue.
You should always try to use the most specific comparison as possible, if you're expecting a string which could be empty use if($foo==='') (note the three equal signs). If you're expecting either (boolean) false or a resource (from a DB query for instance) use if($foo===false){...} else {...}
You may read the documentation about casting to boolean to find the answer to this question. There's a list in there with which values are converted to true and false, respectively.
Note that empty also checks if the variable is set, which regular comparison does not. An unset variable will trigger an error of type E_NOTICE during comparison, but not when using empty. You can work around this using the isset call before your comparison, like this:
if(isset($foo) && $foo != '')
if() "converts" the statement given to a bool, so taking a look at the documentation for boolean seems to be what you're looking for. in general:
empty strings (""), empty arrays (array()), zero (0) and boolean false (false) are treated as false
everything else ("foo", 1, array('foo'), true, ...) is treated as true
EDIT :
for more information, you could also check the type comparison tables.
empty($foo) should return true in all of these cases: 0,"", NULL.
For a more complete list check this page: http://php.net/manual/en/function.empty.php
No, it's not equal. When variable is not defined, expression without empty will generate notice about non-defined variable.
I'm using strpos to find the position of a string in another string. I first check if the string is found at all in there. Here's my line:
if (strpos($grafik['data'],$ss1)<>false && strpos($grafik['data'],$ss2)<>false && strpos($grafik['data'],$ss1) < strpos($grafik['data'],$ss2))
I check if both strings are contained and then I want the first one to be placed before the second one. In the php manual it says that strpos returns false when string is not found. However if my string starts at the zero position (strpos returns 0 since its the beginning), it seems like this statement
strpos($grafik['data'],$ss1)<>false
is false. Somehow 0==false ? How do I make the statement true when strpos returns 0 ?
From http://www.php.net/manual/en/function.strpos.php:
Warning
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.
You have to use the === operator instead of ==.
In your case, instead of using <>, use !==:
strpos($grafik['data'], $ss1) !== false
This will return TRUE if $ss1 is found in $grafik['data']
You need to check with ===. This will make sure you have exact false and not 0.
This function behaves unpredictably, so to be sure it'll have deterministic behavior use either
if(strpos($text,$string)===false)
or test it using a variable
$pos=strpos($text,$string);
if($pos===false)
How can you search a partial string when typing (not to use MySQL) like the LIKE function in MySQL but using PHP when searching a string, e.g.
<?php
$string = "Stackoverflow";
$find = "overfl";
if($find == $string)
{
return true;
}
else
{
return false
}
?>
But that will obviously work won't, but is there a function where you can search partially of a string? That would be great :)
EDIT:
What if it was in an array?
if i use the strpos, it does the echo, If I use it, it goes like truetruetruetruetrue.
I tend to use strpos
$needle='appy';
$haystack='I\'m feeling flappy, and you?';
if(strpos($haystack,$needle)!==false){
//then it was found
}
If you want it to ignore case, use stripos.
Note that a subtlety about this is that if the needle is at the very start of the haystack, in position 0, integer 0 is returned. This means you must compare to false, using strict comparison, or it can produce a false negative.
As noted in the manual, linked above
Warning
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.
As far as using arrays, strpos is meant to take two strings. Using an array will produce Warning: strpos() expects parameter 1 to be string, array given or 1Warning: strpos(): needle is not a string or an integer`.
Okay, let's say you have an array of strings for which to search.
You can
$needles=array('hose','fribb','pancake');
$haystack='Where are those pancakes??';
foreach($needles as $ndl){
if(strpos($haystack,$ndl)!==false){ echo "'$ndl': found<br>\n"; }
else{ echo "'$ndl' : not found<br>\n"; }
}
Another way of searching for multiple strings in one string, without using an array... This only tells you whether at least one match was found.
$haystack='Where are those pancakes??';
$match=preg_match('#(hose|fribb|pancake)#',$haystack);
//$match is now int(1)
Or, use preg_match_all to see how many matches there are, total.
$all_matches=preg_match_all('#(hose|fribb|pancake)#',$haystack,$results);
//all_matches is int(2). Note you also have $results, which stores which needles matched.
In that, the search term is a regular expression. () groups the terms together, and | means 'or'. # denotes the beginning and end of the pattern. Regexes can get pretty complicated quickly, but of course, they work! They are often avoided for performance reasons, but if you're testing multiple strings, this might be more efficient than they array looping method described above. I'm sure there are also other ways to do this.
strstr() / stristr() (the latter being case-insensitive)
if(strstr($string,$find)!==false){
//true
}
strpos() can do that.
if(strpos($string, $find) !== false)
. . .
Note that it may return 0, so do use the type-equals operator.