I'm trying to do some validation in PHP, and one of them is checking whether there is a specific word in the inputted string or not.
The problem is, my code seem to not working when I put the specified word first.
here's the code:
$word = "aa bb cc dd";
if(strpos($word, 'aa') == false)
{
echo "wrong input";
}
but if I change the $word to either bb aa cc dd or bb cc dd aa, it works. I wonder how to fix this though.
strpos will return false if your string isn't there. Otherwise, it returns the position of your string.
In this case, 'aa' is at the start of the string, which means that it's at position 0; and 0 evaluates to false.
You need to do a boolean compare on the result:
if(strpos($word, 'aa') === false)
That's because strpos returns the position of the word, in this case 0. 0 is falsey. == does not check for identical matches, === does. So use a triple equals.
It's even in the docs.
strpos is returning 0, as 'aa' is the 0th character. As 0 == false but does NOT === false (it is not boolean), you need to use === instead of ==.
You should use the strict comparison operator, this will match against the same type, so using === will check if it's a Boolean:
if(strpos($word, 'aa') === false)
{
echo "wrong input";
}
Using == is a loose comparison, anything can be stated true (apart from true, 1, string), e.g.
"false" == false // true
"false" === false // false
The reason why it's false because it's comparing a string against a Boolean which returns false.
Because the position of aa is 0, which equals to false.
You have to use:
if(strpos($word, 'aa') === false)
Add a space before search string and find more than 0 position
if(strpos(" ".$word, 'aa') > 0)
{
echo "Found it!";
}
Related
I am having problems with strpos evaluating properly.
$status = "L";
$x = strpos($status,'L');
echo var_export($x,true);
echo "<br/>";
if (strpos($status,'L') === true) {echo "L is there!.";}
else {echo "No L Found!";}
This outputs:
0
No L Found!
With how I understand strpos and the "===" vs the "==" this should be finding the L.
What do I not understand?
strpos doesn't return true, it returns false if the string isn't found or the index if it is found.
From the official docs:
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.
You do need to perform a strict comparison. You just need to do the opposite one.
if (strpos($status, 'L') !== false) {
echo "L is there!.";
} else {
echo "No L Found!";
}
When evaluated with === true, strpos($status,'L') would have to return a literal boolean true, not just a value that evaluates to true, and as you can see in the documentation, strpos will never return that.
If you used == true instead, it would work sometimes, only when L was not the first character in the string. When it is the first character, strpos($status,'L') will return 0, which does not evaluate to true, but any other position in the string would return a positive integer, which does.
Since false is the value the function returns if the search string is not found, the only reliable way to do this is to do strict comparison against false.
PHP is thinking that null is 0 when the character in $position doesn't exist.
$statusentery = $_POST[status];
$position = strpos($statusentery,"<");
if ($position == 0){
echo "Sorry, for security purposes we do not
allow characters such as <";
exit;
}
For example, if $statusentery was equal to "Howdy there", it would return "Sorry, for security purposes we do not allow characters such as <". (unexpected)
If $statusentery was equal to "Howdy there <" it would return blank (expected).
How to make it work so that when I enter "Howdy there", it didn't do the if loop, but when I enter "< howdy there>", it did the if loop?
Because 0 can means "false" in PHP, $postition will be false when it doesn't exist. So you'll need to use the following:
if ($position === 0){
Using the triple equal sign in PHP verifies that the compared values have the same data type. A lot more information can be found here: http://php.net/manual/en/language.operators.comparison.php
From: http://php.net/manual/es/function.strpos.php
WARNING
As strpos may return either FALSE (substring absent) or 0 (substring
at start of string), strict versus loose equivalency operators must be
used very carefully.
To know that a substring is absent, you must use:
=== FALSE
To know that a substring is present (in any position including 0), you
can use either of:
!== FALSE (recommended)
-1 (note: or greater than any negative number)
To know that a substring is at the start of the string, you must use:
=== 0
To know that a substring is in any position other than the start, you
can use any of:
0 (recommended) != 0 (note: but not !== 0 which also equates to FALSE) != FALSE (disrecommended as highly confusing)
Also note that you cannot compare a value of "" to the returned value
of strpos. With a loose equivalence operator (== or !=) it will return
results which don't distinguish between the substring's presence
versus position. With a strict equivalence operator (=== or !==) it
will always return false.
So the code must be:
$statusentery = $_POST[status];
$position = strpos($statusentery,"<");
if ($position === 0){
echo "Sorry, for security purposes we do not allow characters such as <";
exit;
}
This is a tricky function. As stated in the strpos manual:
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.
I use this comparison, which works well without even a notice level warning:
if ($position > -1)
Returns boolean false when the string is not found, which is evaluable as a number, thus comparing whether the value is greater than -1 actually works well. In case any match is found, even at position 0 the above comparison will be passed.
In the following code, if I set $what to 'red', it doesn't find it, whereas it finds green and blue. Why and how to make it find red as well?
$where = 'red,green,blue';
$what = 'blue';
if (strpos($where, $what) == true) {
echo 'found';
}
strpos returns the index of the found string. In this case the index is 0 and your check for == true will fail. Try:
strpos($where, $what) !== false
The documentation provides more information.
strpos will return false if your string isn't there. Otherwise, it returns the position of your string.
In this case, 'red' is at the start of the string, which means that it's at position 0; and 0 evaluates to false.
You need to do a boolean compare on the result:
if(strpos($word, 'red') === false)
if (strrpos($_POST['security_data'], $OrderReference) === false ||
md5($_POST['security_data'] . $sekey) != $_POST['security_hash'])
{
return;
}
I don't understand why is strrpos in there and === "3 equals"
and what is the dot "." doing in $_POST['security_data'] . $sekey
Thank You
strrpos returns the position of the substring.
echo strrpos("Hello", "e"); // outputs `1`
. is concatenation.
echo "Hello "."There"; // outputs: 'Hello There'
=== checks type as well as equality.
var_dump(1 == true); // true
var_dump(1 === true); // false
Here's a translation to C#:
string hash = MD5.Create().ComputeHash(Request.Form["security_data"] + sekey);
if (!Request.Form["security_data"].Contains(OrderReference)
|| hash != Request.Form["security_hash"])
{
return;
}
strrpos returns false if the string isn't found (don't know which string in which, but the docs will tell you)
=== compares type as well instead of just value. This is done so php doesn't to any casting, for example 0 == false (0 represents false in php as well) but 0 !== false as 0 isn't the same type as false.
the . is the concat operator in php.
strrpos is "return position of substring within a string, starting from the right (end) side". === is the PHP strict comparison, which compares type AND value. The strpos functions CAN return a legitimate 0 as a position, which is the very start of the string. But 0 evalutes to boolean FALSE in PHP, so the === check ensures that you're looing at a real false (strrpos found nothing) and not just "strrpos found string at position zero".
The dot (.) connects between 2 strings, and the 3 equals checks if the returned value is in the same type as what it compared to
If the contents of the variable $OrderReference are not found in the POST variable security_data, or the MD5 hash of the POST variable security_data, concatenated with (that's the . operator in PHP) the variable $sekey isn't equal to security_hash, return from the function.
=== is used to ensure that the return from strrpos() is the boolean FALSE rather than the possible valid return value of 0. === is for strict type comparison.
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