String comparison; finding 'like' characters - php

I am doing a quick duplicate check on a form. When comparing two strings, I was trying something like this:
if (stripos($_SESSION['website'], $f['website']))
I am getting this error:
Fatal error: Call to undefined function: stripos() in...
I do not want it to be an exact match, basically if the $_SESSION['website'] is www.google.com, I'd want stripos to return true if $f['website] is www.goog.com
Am I doing something wrong, or is there a better way to do this?
edit: I was doing some testing, and noticed if my $_SESSION['website'] variable contains www and .com. As does my $f['website] variable. shouldn't strpos return that as true?

stripos(), as per the manual only exists in the core of PHP 5 or later. If stripos doesn't exist, that would suggest you're using PHP 4, which is wildly outdated. I suggest you upgrade. If for some insane reason you really can't, you can always force the two strings to lowercase before calling strpos, which would have the same effect:
<?php
// PHP 5.
$pos = stripos( 'www.google.com', 'google.com' );
// PHP 4.
$pos = strpos( strtolower( 'www.google.com' ), strtolower( 'google.com' ) );
That said, there's something more to your code: you're checking if( stripos( $foo, $bar ) ) which would return 0 if the string $foo starts with the string $bar. You should check with if( stripos( $foo, $bar ) !== false ) instead.
On another note: I don't think stripos will help you. You mentioned www.google.com and www.goog.com, which are two totally different things. The latter is not a substring of the former, and stripos checks for the starting position of a substring, it doesn't do "loose comparison".
If you want "like" and you have the terms in an array, you might want to check out the similar_text() function which will give you an indication of how similar two different strings are. As an example:
<?php
$similarity = 0;
similar_text( 'www.goog.com', 'www.google.com', $similarity );
var_dump( $similarity );
The above code would set $similarity to float(92.307692307692), which is the similarity of the two strings in percentages. You can decide the threshold for the similarity yourself, naturally.

its a strpos('Your String Or Websitename','The Term Search');
if its find the match it returns true otherwise it returns false
$a=strpos($_SESSION['website'], $f['website'])
if($a==TRUE)
{
//do stuff
}
else
{
//other stuff
}

Related

startsWith Case sensitive

Can't find a solution to this which seems simple enough. I have user input field and want to check the user has prefixed the code asked for with an S (example code S123456 so I want to check to make sure they didn't just put 123456).
// Function to check string starting with s
if (isset($_REQUEST['submitted'])) { $string=$_POST['required_code'];function startsWith ($string, $startString){$len = strlen($startString);return (substr($string, 0, $len) === $startString);
}
// Do the check
if(startsWith($string, "s"))echo "Code starts with a s";else echo "Code does not start with a s";}
The problem is if the user inputs an upper case S this is seen as not being a lower case s.
So I can get round this using
$string = strtolower($string);
So if the user inputs an uppercase S it gets converted to lower case before the check. But is this the best way? Is there not someway to say S OR s?
Any suggestions?
What you could do instead of creating your own function, is using stripos. Stripos tries to find the first occurrence of a case-insensitive substring.
So as check you could have:
if(stripos($string, "s") === 0)
You need 3 equal signs, since stripos will return false (0) if it can't find the substring.
Take your pick; there are many ways to see if a string starts with 'S'. Some of them case-sensitive, some not. The options below should all work, although I wouldn't consider any of them better than your current solution. stripos() is probably the 'cleanest' check though. If you need multibyte support, there's also the mb_stripos() variant.
(Although; keep in mind that stripos() can also return false. If you're going with that option, always use the stricter "identical" operator ===, instead of == to prevent type juggling.)
if (stripos($string, 's') === 0) {
// String starts with S or s
} else {
// It does not
}
if (str_starts_with($string, 's') || str_starts_with($string, 'S')) // ...
if (in_array(substr($string, 0, 1), ['S', 's'], true)) // ...
if (preg_match('/^s/i', $string)) // ...
// Many other regexp patterns also work
Thanks all, it was
if (str_starts_with($string, 's') || str_starts_with($string, 'S')) // ...
I was looking for I had tried
if (str_starts_with($string, 's' || 'S')) // ...

Check to see if EXACT value is in a string - PHP

I have read numerous posts about how to see if a value is in a string. Apparently my request is different since the multiple bits of code haven't worked 100%.
I am searching a string and need to make sure the EXACT value is in there - with a perfect match.
$list="Light Rain,Heavy Rain";
$find="Rain";
That should NOT match for what I need to do. I need it to match exactly.
All the code I have tested says it IS a match - and I understand why. But, what can I do to make it not match since Rain is different than Light Rain or Heavy Rain? I hope I am making sense.
I have already tried strpos and preg_match, but again, those equal a match - but for my purposes, not an equal match.
Thanks for something that probably will end up being a DUH moment.
If you need exact matches and the $list is always comma delimited. Why not check for them this way?
$list = explode(',', "Light Rain,Heavy Rain");
var_dump(in_array('Rain', $list)); // false
var_dump(in_array('Heavy Rain', $list)); // true
and if you must have a regular expression.
in your regex, make sure you're checking for the start of the string or a comma (^|,) at the start, and then your string, then another comma or the end of the string (,|$). The ?: makes them non-capturing groups so they dont show up in $matches.
$list = "Light Rain,Heavy Rain";
$test = 'Rain';
preg_match("/(?:^|,)($test)(?:,|$)/", $list, $matches);
var_dump(!empty($matches)); // false
$test = 'Heavy Rain';
preg_match("/(?:^|,)($test)(?:,|$)/", $list, $matches);
var_dump(!empty($matches)); // true
Try this:
$list="Light Rain,Heavy Rain";
$find="Light";
if(strpos($list,$find) !== false)
{
echo 'true';
}
else
{
echo 'false';
}
Credits to: https://stackoverflow.com/a/4366748/4660348

regex to filter php array by conditional existence of value

I have have a php array
$arr[0] = "something/somethingelse/anotherval";
$arr[1] = "something/!somevar/anotherval";
$arr[3] = "something/!notcorrect/anotherval";
$arr[4] = "something/somethingelse/_MyVal";
$arr[5] = "something/_MyVal/anotherval";
$arr[6] = "something/_AnotherNotCorrect/anotherval";
I'm using array_filter to filter the array by certain criteria...
$f = array_filter(array_keys($arr), function ($k){
return ( strpos($k, 'something/') !== false ); });
This returns all my vals where the term something/ is matched... I'd like to be able to say IF we encounter a ![something here] or a _[something here] then we need to make sure that the [something here] matches either $afterExcl or $afterUnderscore. If we didn't encounter a ! or _ then just check the strpos($k, 'something/') !== false check...
(notice that the ! and _ portions may or may not be at the end of val string)
I'm assuming this is regex, but I've always struggled to build them.
CLARIFICATION
Thanks. Clarification though, the ! or _ sequence may not be the next directory after something/, it may three or four more steps in. AND, I'll be providing a $afterExcl or $afterUnderscore value which will designate approved values. Basically the client is using ! and _ to denote "regions" ie.
something/images/!Canada
something/videos/tutorials/!Canada or
something/images/!USA or
something/images/!Mexico OR last
something/images/All
then I'd specify
$afterExcl=Canada
My filter would return
something/images/!Canada
something/videos/tutorials/!Canada
something/images/All
You can use something like this:
$f = array_filter(array_keys($arr), function ($k){
return preg_match('~something/(?![_!])~', $k); });
The negative lookahead (?!...) checks if the slash isn't followed by a ! or a _.
Note that preg_match returns 1 if found or 0 if not. If you want to return true or false you can do it with the ternary operator:
return preg_match('~something/(?![_!])~', $k) ? true : false;
an other way:
If you use strpos, I assume that the string you describe as 'something/' is a fixed string $str, in other words you know the length of this strings. Since strpos returns the position $pos in the string of the occurence, you can easily check if at the position $pos + strlen($str) there is either an exclamation mark or an underscore. (you could, for example, extract this next character and check if it is in the array array('!', '_'))

PHP match string, is fnmatch right for the job

I'm trying to figure out how I can compare values from an array against a particular string.
Basically my values look like chrisx001, chrisx002, chrisx003, chrisx004, bob001
I was looking at fnmatch() but I'm not sure this is the right choice, as what I want to do is keep chrisx--- but ignore bob--- so I need to wildcard the last bit, is there a means of doing this where I can be like
if($value == "chrisx%"){/*do something*/}
and if thats possible is it possible to double check the % value as int or similar in other cases?
Regex can tell you if a string starts with chrisx:
if (preg_match('/^chrisx/', $subject)) {
// Starts with chrisx
}
You can also capture the bit after chrisx:
preg_match('/^chrisx(.*)/', $subject, $matches);
echo $matches[1];
You could filter your array to return a second array of only those entries beginning whith 'chris' and then process that filtered array:
$testData = array ( 'chrisx001', 'chrisx002', 'chrisx003', 'chrisx004', 'bob001');
$testNeedle = 'chris';
$filtered = array_filter( $testData,
function($arrayEntry) use ($testNeedle) {
return (strpos($arrayEntry,$testNeedle) === 0);
}
);
var_dump($filtered);

Sorting through a delimited string with PHP

I am trying to create a script that checks if a certain value is in a comma delimited string, and if the value is present, it should return true else it should return false.
Basically, I am trying to check if a user has voted for a specific person before, and if so, they cannot vote again, if they have not, vote and then add their uid to the database.
I am using explode to get all the values into an array, but I am unsure about the checking function, I have a few ideas but this is quite an important script so I wanted to see if there is a better way of going about it.
$test = "john,jack,tom";
$exploded = explode(",",$test);
$hostID = "john";
foreach($exploded as $one){
if($one == $hostID){
$return = TRUE;
}else{
$return = FALSE;
};
};
Thanx in advance!
You could use in_array.
Some people prefer to use lowercase true and false.
The semicolon after } is not needed
$return = TRUE does not actually stop the function. Maybe you do return $return.
Some people like to put spaces after comma's and keywords (e.g. foreach, if, else)
Some people prefer single quotes over double quotes
Code:
function find_name($name, $list)
{
$exploded = explode(',', $list);
return in_array($name, $exploded);
}
var_dump(find_name('john', 'john,jack,tom'));
?>
As Sjoerd says, in his very good advice.
function find_name( $needle , $haystack ) {
if( strpos( $haystack , $needle )===false )
return false;
return in_array( $needle , explode( ',' , $haystack ) );
}
Test cases:
// find_name( 'john' , 'peter,mark,john' );
true
// find_name( 'peter' , 'mark,john' );
false
EDITED: As per advice from Gordon.
You could also use
strpos — Find position of first occurrence of a string
instead:
return strpos('john,jack,tom', 'barney'); // returns FALSE
Note that the function returns the position if the string was found, so searching for john will return zero, which would be FALSE if you compare it for equality (==). In other words use the identity comparator (===).
As Lucanos correctly points out, there is chance to get false positives when using strpos if the searched name is part of a longer name, e.g. searching for jean only would also find jean-luc. You could add a comma at the end of the haystack string and search for jean, though, but then again, it feels hackish. So it's likely better to use in_array.

Categories