字符串函数
在线手册:中文  英文

strstr

(PHP 4, PHP 5)

strstr查找字符串的首次出现

说明

string strstr ( string $haystack , mixed $needle [, bool $before_needle = false ] )

返回 haystack 字符串从 needle 第一次出现的位置开始到 haystack 结尾的字符串。

Note:

该函数区分大小写。如果想要不区分大小写,请使用 stristr()

Note:

如果你仅仅想确定 needle 是否存在于 haystack 中,请使用速度更快、耗费内存更少的 strpos() 函数。

参数

haystack

输入字符串。

needle

如果 needle 不是一个字符串,那么它将被转化为整型并且作为字符的序号来使用。

before_needle

若为 TRUEstrstr() 将返回 needlehaystack 中的位置之前的部分。

返回值

返回字符串的一部分或者 FALSE(如果未发现 needle)。

更新日志

版本 说明
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
?>

参见


字符串函数
在线手册:中文  英文

用户评论:

xslidian at lidian dot info (2013-02-21 07:37:48)

For those in need of the last occurrence of a string:

<?php
function strrstr($h$n$before false) {
    
$rpos strrpos($h$n);
    if(
$rpos === false) return false;
    if(
$before == false) return substr($h$rpos);
    else return 
substr($h0$rpos);
}
?>

peter at olds dot co (2012-02-20 10:16:48)

I was in need of getting the first and last part of a string pre 5.3 so I wrote this:

<?php
$fir 
$first explode" "$cmd[1] );
unset( 
$fir[0] );
$end ltrimimplode" "$fir ) );
?>

I needed it split with a " " but can obviously change for your needs. But with this format your output for the string:

"PHP is the best programming language out there"

Will give you the following results:

<?php
$first
[0// PHP
$end // is the best programming language out there
?>

Works really well :)

xydon1 at yahoo dot com (2011-08-31 15:03:41)

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");
?>

gruessle at gmail dot com (2011-04-20 13:39:51)

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($haystack0,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 (2009-01-20 00:28:04)

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 (2007-11-25 16:42:05)

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 (2007-11-25 08:02:35)

For the needle_before (first occurance) parameter when using PHP 5.x or less, try:

<?php
$haystack 
'php-homepage-20071125.png';
$needle '-';
$result substr($haystack0strpos($haystack$needle)); // $result = php
?>

prafe at prafesplace dot com (2007-11-21 21:14:39)

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'@'falsefalsefalse);
echo 
$domain// prints example.com

$user strstrbi($email'@'truefalsefalse);
echo 
$user// prints user
?>

root at mantoru dot de (2007-11-10 03:22:43)

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 (2007-02-24 12:48:33)

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.

(2005-06-06 09:13:53)

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&ouml;r att klippa av en str&auml;ng som inneh&aring;ller skandinaviska (eller Franska, f&ouml;r den delen) tecken, kan man g&ouml;ra s&aring;h&auml;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($oldstr0$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&ouml;r att klippa av en str&auml;ng som inneh&ar

With the decode-encode snippet:
F&ouml;r att klippa av en str&auml;ng som inneh&aring;ller skandin

First post in this db ;) 
Best regards, Mikael R?nn, FIN

leo dot nard at free dot fr (2005-05-24 02:12:18)

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($string0strlen($string)-$nb);
        }
        
$a=substr($a,1,strlen($a)-1);
    }
    return 
$string;
}
?>

Romuald Brunet (2004-01-21 12:25:33)

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 fasterBut then if the haystack starts with needle the condition whould not be met.

php at silisoftware dot com (2003-02-14 15:37:02)

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"
?>

易百教程