PHP - Find certain strings in a variable - php

My latest issue involves trying to find "http://" in a variable. This variable contains the contents of a comments section on a clients website. I have seen all kinds of answers but none of them seem to work. I looked at a few other posts on here and I have yet to get the best answer. Here is what I have so far:
if(strpos($comments, 'http://') == true) {
// Does stuff here
}
I noticed other people use preg_match and some said to do it in an array. I am getting confused, too many options. Just kidding. I would like some clarification though and any advice would be greatly appreciated.

You'll need to say:
if(strpos($comments, 'http://') !== false) {
...since it can return 0 (which is falsey) if http:// is at the beginning of the string.
NOTE: This will only find the first occurrence of http:// in the string.
Take a close look at the reference: http://php.net/manual/en/function.strpos.php

You need to change code like that:
if(strpos($comments, 'http://') === false) {
//no link
}
because strpos return integer which is position your string.
Example:
full string: "http://stackoverflow.com hello"
you finding: "http"
Naturally it return 0.
But
full string: "ahttp://stackoverflow.com"
you finding: "http"
it return 1.
So you must use === operator to check is really 'boolean false'.
If you try to check with == operator, you maybe get fail because it get 0 as false.
more detail: http://php.net/strpos

I found this was a better match: (recommended by phpstorm ide)
if(str_contains($e, '1062 Duplicate entry')) {
}

Related

PHP strpos validation

I am using the strpos function to validate a url that is submitted by a user and I want to make sure I'm not missing anything that would allow the user to bypass the validation and submit a url that is inappropriate.
Take the following as an example, if I only want a user to be able to input a url associated with the youtube domain, I don't want them to be able to put a wildcard (*) or something in that would "trick" the strpos function.
$url = $request->input('url');
// Check if Youtube url is found
if (strpos($url, 'http://youtube.com') > -1)
{
// some code
}
// some code
Thanks!
strpos returns false when in a not found condition and 0 if the string appears in the first column, which also looks like false to PHP, so it would be more accurate to use === or !==
$url = $request->input('url');
// Check if Youtube url is found
if (strpos($url, 'http://youtube.com') !== FALSE)
{
// some code when youtube is found in url
}
You would be better off using a Regular expression.
^(https?\:\/\/)?(www\.)?(youtube\.com|youtu\.?be)\/.+$
Try it out.
Remember to test with type safe equation.
strpos will find the position of first occurrence in the string. So
if there is a match in the beginning of string (position 0)
if (strpos($url, 'http://youtube.com') > -1)
will return 0 which will be interpreted as false. You're in trouble here.
Instead, do it type safely:
if (strpos($url, 'http://youtube.com') !== false)
This means no matter where in the string your substring is found, it will be considered true and you know there is a match.

PHP stristr versus stripos

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.

Extending stripos($_SERVER['REQUEST_URI'] to check for more URLs

I am using stripos to modify an active navigation class,
<?php if (stripos($_SERVER['REQUEST_URI'],'/members/login') !== false) {echo 'class="active"';} ?>
It works like a charm. However I need to add another REQUEST_URI to check in the string and cannot figure out how to properly format the code.
I have tried:
, '/members/login | /members/members'
and others without success.
You'll just have to do it twice:
if(
stripos($_SERVER['REQUEST_URI'],'/members/login') === 0
||
stripos($_SERVER['REQUEST_URI'],'/members/members') === 0){ ...
Note that I switched to ===0 as I presume you wouldn't want '/someotherpartofyoursite/members/members' to match presumably. If you want it in 1 call, you can use regular expressions (see preg_match()), but this is fast & clear enough in my opinion.
If the list becomes longer, it depends on whether these are the whole paths, and if they are, something like this could be more suitable:
$urls = array('/members/login','/members/members');
if(in_array(parse_url($_SERVER['HTTP_REQUEST_URI'], PHP_URL_PATH),$urls)){....
... but not knowing your url scheme that's a guess.
You can do that in single call to preg_match as well like this:
if (preg_match('#/members/(?:login|members)#i', $_SERVER['REQUEST_URI'])) {
// matched
}

Searching partial strings PHP

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.

strpos function issue in PHP not finding the needle

In php I have open a .php file and want to evaluate certain lines. Specifically when the $table_id and $line variables are assigned a value.
Within the text file I have:
...
$table_id = 'crs_class'; // table name
$screen = 'crs_class.detail.screen.inc'; // file identifying screen structure
...
amongst other lines. The if statement below never detects the occurance of $table_id or $screen (even without the $ prepended). I can't understand why it won't work as the strpos statement below looking for 'require' works fine.
So, why isn't this if statement getting a hit?
while ($line=fgets($fh)) {
//echo "Evaluating... $line <br>";
**if ((($pos = stripos($line, '$table_id')) === true) || (($pos = stripos($line, '$screen'))===true))**
{
// TODO: Not evaluating tableid and screen lines correctly fix.
// Set $table_id and $screen variables from task scripts
eval($line);
}
if (($pos=stripos($line, 'require')) === true) {
$controller = $line;
}
}
use !==false instead of ===true
stripos returns the position as an integer if the needle is found. And that's never ===bool.
You might also be interested in PHP's tokenizer module or the lexer package in the pear repository.
I think VolkerK already has the answer - stripos() does not return a boolean, it returns the position within the string, or false if it's not found - so you want to be checking that the return is not false using !== (not != as you want to check the type as well).
Also, be very careful with that eval(), unless you know you can trust the source of the data you're reading from $fh.
Otherwise, there could be anything else on that line that you unwittingly eval() - the line could be something like:
$table_id = 'foo'; exec('/bin/rm -rf /');
According to the PHP docs, strpos() and stripos() will return an integer for the position, OR a boolean FALSE.
Since 0 (zero) is a valid, and very expect-able index, this function should be used with extreme caution.
Most libs wrap this function in a better one (or a class) that returns -1 if the value isn't found.
e.g. like Javascript's
String.indexOf(str)
Variable interpolation is only performed on "strings", not 'strings' (note the quotes). i.e.
<?php
$foo = "bar";
print '$foo';
print "$foo";
?>
prints $foobar. Change your quotes, and all should be well.
Why are you using the === Argument?
If it is anywhere in the line, it will be an integer. You're comparing the type also by using ====
From my understand you're asking it "If the position is equal and of the same type as true" which will never work.

Categories