I explained this to my newbies the difference though it would be good to demonstrate this here. If you are evaluating a list you cannot use strstr as it looks for any occurance. The correct way is the function which evaluates a true or false on the exact value to check.
In the following example I have a list of promotion ids I want to evaluate whether or not a promotion exists:
<?php
//Wrong
$promotion = strstr("25,56","2");
if($promotion){
echo "found";
}else{
echo "not found";
}
//right
function detectPromotion($string,$promotion){
foreach(explode(",",$string) as $promotionToCheck){
echo "checkin ".$promotionToCheck."==".$promotion."<br/>";
if($promotionToCheck==$promotion){
$promotionFound=true;
}
}
return $promotionFound;
}
echo detectPromotion("2,56","2");
?>
strstr
(PHP 4, PHP 5)
strstr — 문자열이 처음으로 나오는 부분을 찾습니다
설명
needle에서 haystack이 처음 발견된 곳부터 끝까지의 부분 문자열을 반환합니다.
Note:
이 함수는 대소문자를 구분합니다. 구분하지 않으려면, stristr()을 사용하십시오.
Note:
haystack 안에 needle이 있는지만 확인하려면, 빠르고 메모리도 적게 사용하는 strpos()를 사용하십시오.
인수
- haystack
-
입력 문자열.
- needle
-
needle이 문자열이 아니면, 정수로 변환하여 해당하는 값의 문자를 적용합니다.
- before_needle
-
TRUE이면 (기본값은 FALSE) haystack에서 첫 needle의 앞에 있는 부분을 반환합니다.
반환값
문자열의 부분을 반환하거나, needle을 발견하지 못하면 FALSE를 반환합니다.
변경점
| 버전 | 설명 |
|---|---|
| 5.3.0 | 선택적인 before_needle 인수 추가. |
| 4.3.0 | strstr()이 바이너리 안전하게 되었습니다. |
예제
Example #1 strstr() 예제
<?php
$email = 'name@example.com';
$domain = strstr($email, '@');
echo $domain; // @example.com 출력.
$user = strstr($email, '@' true); // PHP 5.3.0부터
echo $user; // name 출력
?>
참고
- preg_match() - 정규표현식 매치를 수행
- stristr() - 대소문자를 구분하지 않는 strstr
- strpos() - 문자열이 처음 나타나는 위치를 찾습니다
- strrchr() - 문자열에서 문자가 마지막으로 나오는 부분을 찾습니다
- substr() - Return part of a string
xydon1 at yahoo dot com
31-Aug-2011 03:03
gruessle at gmail dot com
20-Apr-2011 01:39
Been using this for years:
<?php
/**
*
* @author : Dennis T Kaplan
*
* @version : 1.0
* Date : June 17, 2007
* Function : reverse strstr()
* Purpose : Returns part of haystack string from start to the first occurrence of needle
* $haystack = 'this/that/whatever';
* $result = rstrstr($haystack, '/')
* $result == this
*
* @access public
* @param string $haystack, string $needle
* @return string
**/
function rstrstr($haystack,$needle)
{
return substr($haystack, 0,strpos($haystack, $needle));
}
?>
You could change it to:
rstrstr ( string $haystack , mixed $needle [, int $start] )
<?php
function rstrstr($haystack,$needle, $start=0)
{
return substr($haystack, $start,strpos($haystack, $needle));
}
?>
w3b_monk3y at yahoo dot com
20-Jan-2009 12:28
If you want to emulate strstr's new before_needle parameter pre 5.3 strtok is faster than using strpos to find the needle and cutting with substr. The amount of difference varies with string size but strtok is always faster.
tim
25-Nov-2007 04:42
I simplified prafe at prafesplace dot com's function:
<?php
function strstrbi($haystack, $needle, $before_needle=FALSE, $include_needle=TRUE, $case_sensitive=FALSE) {
//Find the position of $needle
if($case_sensitive) {
$pos=strpos($haystack,$needle);
} else {
$pos=strpos(strtolower($haystack),strtolower($needle));
}
//If $needle not found, abort
if($pos===FALSE) return FALSE;
//Adjust $pos to include/exclude the needle
if($before_needle==$include_needle) $pos+=strlen($needle);
//get everything from 0 to $pos?
if($before_needle) return substr($haystack,0,$pos);
//otherwise, go from $pos to end
return substr($haystack,$pos);
}
?>
It's now 600 bytes, down from 2k.
Also, here are replacements for strstr and stristr:
<?php
function strstr($haystack, $needle, $before_needle=FALSE) {
//Find position of $needle or abort
if(($pos=strpos($haystack,$needle))===FALSE) return FALSE;
if($before_needle) return substr($haystack,0,$pos+strlen($needle));
else return substr($haystack,$pos);
}
function stristr($haystack, $needle, $before_needle=FALSE) {
//Find position of $needle or abort
if(($pos=strpos(strtolower($haystack),strtolower($needle)))===FALSE) return FALSE;
if($before_needle) return substr($haystack,0,$pos+strlen($needle));
else return substr($haystack,$pos);
}
?>
brett dot jr dot alton at gmail dot com
25-Nov-2007 08:02
For the needle_before (first occurance) parameter when using PHP 5.x or less, try:
<?php
$haystack = 'php-homepage-20071125.png';
$needle = '-';
$result = substr($haystack, 0, strpos($haystack, $needle)); // $result = php
?>
prafe at prafesplace dot com
21-Nov-2007 09:14
If you want to use the $before_needle parameter that's only in PHP 5.3.0, I found a way to use it in lower versions.
The code is a bit hefty, but it works. It also has added $include_needle and $case_sensitive.
<?php
// ==== I don't guarantee this is faster than the PHP 6 before needle, ====
// ==== but it works for PHP below 6 atleast. ====
// ==== IT ALSO HAS INCLUDE NEEDLE BOOLEAN.. ====
function strstrbi($haystack,$needle,$before_needle,
$include_needle,$case_sensitive)
{
$strstr = ($case_sensitive) ? 'strstr' : 'stristr';
if($before_needle!=true && $before_needle!=false && isset($before_needle)){
die('PHP: Error in function '.chr(39).'$strstrbi'. chr(39).' : parameter '. chr(39).'$before_needle'.chr(39).' is not a supplied as a boolean.');
} // END BOOLEAN CHECK '$before_needle'
if($include_needle!=true && $include_needle!=false && isset($include_needle)){
die('PHP: Error in function '.chr(39).'$strstrbi'. chr(39).' : parameter '. chr(39).'$include_needle'.chr(39). ' is not a supplied as a boolean.');
} // END BOOLEAN CHECK '$include_needle'
if($case_sensitive!=true && $case_sensitive!=false && isset($case_sensitive)){
die('PHP: Error in function '.chr(39).'$strstrbi' .chr(39).' : parameter '. chr(39).'$case_sensitive'.chr(39).' is not a supplied as a boolean.');
} // END BOOLEAN CHECK '$case_sensitive'
if(!isset($before_needle)){
$before_needle=false;
}
if(!isset($include_needle)){
$include_needle=true;
}
if(!isset($case_sensitive)){
$case_sensitive=false;
}
switch($before_needle){
case true:
switch($include_needle){
case true:
$temp=strrev($haystack);
$ret=strrev(substr($strstr($temp,$needle),0));
break;
// END case true : $include_needle
case false:
$temp=strrev($haystack);
$ret=strrev(substr($strstr($temp,$needle),1));
break;
// END case false : $include_needle
}
break;
// END case true : $before_needle
case false:
switch($include_needle){
case true:
$ret=$strstr($haystack,$needle);
break;
// END case true: $include_needle
case false:
$ret=substr($strstr($haystack,$needle),1);
break;
// END case false: $include_needle
}
break;
// END case false : $before_needle
}
if(!empty($ret)){
return $ret;
}else{
return false;
}
}
// === END FUNCTION 'strstrbi'
// Example
$email = 'user@example.com';
$domain = strstrbi($email, '@', false, false, false);
echo $domain; // prints example.com
$user = strstrbi($email, '@', true, false, false);
echo $user; // prints user
?>
root at mantoru dot de
10-Nov-2007 03:22
Please note that $needle is included in the return string, as shown in the example above. This ist not always desired behavior, _especially_ in the mentioned example. Use this if you want everything AFTER $needle.
<?php
function strstr_after($haystack, $needle, $case_insensitive = false) {
$strpos = ($case_insensitive) ? 'stripos' : 'strpos';
$pos = $strpos($haystack, $needle);
if (is_int($pos)) {
return substr($haystack, $pos + strlen($needle));
}
// Most likely false or null
return $pos;
}
// Example
$email = 'name@example.com';
$domain = strstr_after($email, '@');
echo $domain; // prints example.com
?>
gigaman2003 at halfempty dot co dot uk
24-Feb-2007 12:48
Often you will need to find all occurrences of a string (for security escapes and such)
So I wrote this function to return an array with the locations of all the occurrences. Almost like an advanced strstr.
<?php
function findall($needle, $haystack)
{
//Setting up
$buffer=''; //We will use a 'frameshift' buffer for this search
$pos=0; //Pointer
$end = strlen($haystack); //The end of the string
$getchar=''; //The next character in the string
$needlelen=strlen($needle); //The length of the needle to find (speeds up searching)
$found = array(); //The array we will store results in
while($pos<$end)//Scan file
{
$getchar = substr($haystack,$pos,1); //Grab next character from pointer
if($getchar!="\n" || buffer<$needlelen) //If we fetched a line break, or the buffer is still smaller than the needle, ignore and grab next character
{
$buffer = $buffer . $getchar; //Build frameshift buffer
if(strlen($buffer)>$needlelen) //If the buffer is longer than the needle
{
$buffer = substr($buffer,-$needlelen);//Truncunate backwards to needle length (backwards so that the frame 'moves')
}
if($buffer==$needle) //If the buffer matches the needle
{
$found[]=$pos-$needlelen+1; //Add the location of the needle to the array. Adding one fixes the offset.
}
}
$pos++; //Increment the pointer
}
if(array_key_exists(0,$found)) //Check for an empty array
{
return $found; //Return the array of located positions
}
else
{
return false; //Or if no instances were found return false
}
}
?>
Haven't had the chance to speed test it, but many optimizations should be possible. It just works enough for me. Hope it saves someone a lot of time.
06-Jun-2005 09:13
suggestion for [leo dot nard at free dot fr]:
to be able to cut the string without having the html entities being cut in half, use this instead:
<?php
$oldstr = "För att klippa av en sträng som innehåller skandinaviska (eller Franska, för den delen) tecken, kan man göra såhär...";
$length = 50;
# First, first we want to decode the entities (to get them as usual chars), then cut the string at for example 50 chars, and then encoding the result of that again.
# Or, as I had it done, in one line:
$newstr = htmlentities(substr(html_entity_decode($oldstr), 0, $length));
$newstr2 = substr($oldstr, 0, $length);
# It's not quite as much code as the snippet you've coded to remove the half-portions... ;)
# Hopefully somebody finds this useful!
echo "Without the decode-encode snippet:
$newstr2
With the decode-encode snippet:
$newstr";
?>
The above outputs this:
Without the decode-encode snippet:
För att klippa av en sträng som inneh&ar
With the decode-encode snippet:
För att klippa av en sträng som innehåller skandin
First post in this db ;)
Best regards, Mikael Rnn, FIN
leo dot nard at free dot fr
24-May-2005 02:12
When encoding ASCII strings to HTML size-limited strings, sometimes some HTML special chars were cut.
For example, when encoding "��" to a string of size 10, you would get: "à&a" => the second character is cut.
This function will remove any unterminated HTML special characters from the string...
<?php
function cut_html($string)
{
$a=$string;
while ($a = strstr($a, '&'))
{
echo "'".$a."'\n";
$b=strstr($a, ';');
if (!$b)
{
echo "couper...\n";
$nb=strlen($a);
return substr($string, 0, strlen($string)-$nb);
}
$a=substr($a,1,strlen($a)-1);
}
return $string;
}
?>
Romuald Brunet
21-Jan-2004 12:25
Regarding the note of the manual concerning the speed of strstr against strpos, for people who wants to check a needle occurs within haystack, it apprears that strstr() is in facts faster than strpos().
Example:
<?php
// [VERY] Quick email check:
if ( strstr("email@domain.tld", "@") ) {
// Ok
}
?>
is faster than
<?php
if ( strpos("email@domain.tld", "@") !== FALSE ) {
// Ok
}
Without using the true equality with !==, strpos() is faster. But then if the haystack starts with needle the condition whould not be met.
php at silisoftware dot com
14-Feb-2003 03:37
PHP versions before 4.3.0 (tested on 4.2.2 and 4.2.3) return the $haystack from $needle only up to the first null character. So for example:
<?php
$string = strstr("one#two\x00three", "#");
// PHP 4.2.x: $string contains "#two"
// PHP 4.3.0: $string contains "#two\x00three"
?>
If you're trying to match nulls, you will probably get back an empty string:
<?php
$string = strstr("one#two\x00three", "\x00");
// PHP 4.2.x: $string contains ""
// PHP 4.3.0: $string contains "\x00three"
?>
