Searching Strings in PHP

Learn how to search through strings of text in PHP. Looks at strstr() for simple searching; strpos() and strrpos() for locating text; and substr_count() for counting matches.

When writing PHP scripts, you often need to search a string for a particular chunk of text. For example, you might be writing a search engine to search through pages of content, or you might want to know if a URL or email address contains a certain domain name.

PHP gives you many useful functions for searching strings. In this article you look at:

  • strstr() for finding out whether some text is in a string
  • strpos() and strrpos() for finding the position of some text in a string
  • substr_count() for finding out how many times some text appears in a string

Simple text searching with strstr()

PHP's strstr() function simply takes a string to search, and a chunk of text to search for. If the text was found, it returns the portion of the string from the first character of the match up to the end of the string:

$myString = 'Hello, there!';
echo strstr( $myString, 'llo' );  // Displays "llo, there!"

If the text wasn't found then strstr() returns false. You can use this fact to determine if the text chunk was in the string or not:

$myString = 'Hello, there!';

if ( strstr( $myString, 'Goodbye' ) ) {
  echo "Text found";
} else {
  echo "Text not found";

The above code displays:

Text not found

strstr() is case sensitive — for example, "hello" won't match "Hello". If you don't care about matching case, use the case-insensitive version, stristr(), instead.

Finding the position of a match: strpos() and strrpos()

strpos() takes the same 2 arguments as strstr(). However, rather than returning a portion of the string, it returns the index of the first character of the matched text in the string:

$myString = 'Hello, there!';
echo strpos( $myString, 'llo' );  // Displays "2"

In the above code, strpos() finds the text 'llo' in the target string starting at the 3rd character, so it returns 2. (Remember that character index positions in strings start from 0, not 1.)

Be careful when using strpos() to check for the existence of a match. The following code incorrectly displays "Not found", because strpos() returns 0, which is equivalent to false in PHP:

$myString = 'Hello, there!';
if ( strpos( $myString, 'Hello' ) ) {
  echo "Found";
} else {
  echo "Not found";

To fix this, make sure you test explicitly for false by using the === or !== operator. The following code correctly displays "Found":

$myString = 'Hello, there!';
if ( strpos( $myString, 'Hello' ) !== false ) {
  echo "Found";
} else {
  echo "Not found";

You can pass a third argument to strpos() to specify the index position from which to begin the search:

$myString = 'Hello, there!';
echo strpos( $myString, 'e' ) . '<br />';     // Displays "1"
echo strpos( $myString, 'e', 2 ) . '<br />';  // Displays "9"

The strrpos() function is very similar to strpos(). The only difference is that it finds the last match in the string instead of the first:

$myString = 'Hello, there!';
echo strpos( $myString, 'e' ) . "<br />";   // Displays "1"
echo strrpos( $myString, 'e' ) . "<br />";  // Displays "11"

As with strstr(), the strpos() and strrpos() functions are case sensitive. Their case-insensitive equivalents are stripos() and strripos() respectively.

Counting matches with substr_count()

You can use PHP's substr_count() function to find the number of times a chunk of text appears in the target string:

$myString = 'Short stories';
echo substr_count( $myString, 'or' );  // Displays "2"

As with strpos() and strrpos(), you can pass an optional third argument: the index position to begin the search. For example:

$myString = 'Short stories';
echo substr_count( $myString, 'or', 6 );  // Displays "1"

You can also pass an optional fourth argument: the number of characters after the offset position in which to search for the text. For example:

echo substr_count( $myString, 'or', 0, 10 ) . '<br />';  // Displays "2"
echo substr_count( $myString, 'or', 0, 5 ) . '<br />';   // Displays "1"

In this article you've looked at how to search strings in PHP. You've explored the strstr() function for finding out whether a chunk of text exists in a string; strpos() and strrpos() for locating text in a string; and substr_count() for finding out the number of matches in a string. Happy coding!

Learn PHP With Ease!

Written by Matt Doyle — ELATED's resident Web programming expert — Beginning PHP 5.3 is a complete introduction to PHP, covering everything in these tutorials and lots more besides. Find out how to:

  • Set up PHP on your computer
  • Use strings, arrays, functions and objects
  • Create interactive Web forms
  • Handle cookies and sessions
  • Work with files on the server
  • Build database-driven sites with MySQL
  • Send emails from your scripts
  • Create images on the fly with PHP
  • Work with regular expressions
  • Write robust, secure PHP applications

...and lots more!

“What a pleasure it's been spending hours and hours studying PHP with this magical book.” — Lulio, Florida
“The book is not only great for learning, but I find myself using it constantly as a reference as well!” — David A. Stoltz

Buy Beginning PHP 5.3 now from Amazon.comBeginning PHP 5.3 or PHP 5.3.

Follow Elated

Related articles

Responses to this article

5 responses (oldest first):

10-Nov-10 12:21
This is my case: Mysql Column called TAG Containing this information:

row1 Note: bla bla bla1 - Tag: bla bla bla1
row2 Note: bla bla bla2 - Tag: bla bla bla2
row3 Note: bla bla bla3 - Tag: bla bla bla3
row4 Tag: bla bla bla4
row5 Note: bla bla bla4

So I want to do a query with php that displays the all rows, but from column TAG display the info containing only the string corresponding to "Note: bla bla blaX"
so in the row 4 shouldn't show anything but at the others rows should show the corresponding Note.

I hope it is not too difficult.

Thanks for your help.
10-Nov-10 20:25
Hi achandia,

You need to use a regular expression for this, eg:

$row = "row1 Note: bla bla bla1 - Tag: bla bla bla1";
$result = preg_match( "/Note: (.*?)(-|$)/", $row, $matches );
echo $matches[1];

You'll probably want to trim any whitespace from the end of the match too.

It's a pretty nasty data format - you'd be better off having your notes and tags in separate columns in the DB, if possible.
11-Nov-10 01:28
Thanks for your answer, the problem is I can not use a different colum, that's why I'm looking for a solution like this, actually to make it easier may be I can use tags, I mean something like thiis:

Row Stuff Info
row1 First Stuff <N>bla bla bla1</N><T>bla bla bla1</T>
row2 Second Stuff <N>bla bla bla2</N><T>bla bla bla2</T>
row3 Third Stuff <N>bla bla bla3</N><T>bla bla bla3</T>
row4 Fourth Stuff <T>bla bla bla1</T>
row5 Fifth Stuff <N>bla bla bla1</N>

And make the regular expression accordingly
I will try your solution and I let you know how it goes.
Thanks again.

[Edited by achandia on 11-Nov-10 02:29]
11-Nov-10 03:12
Thanks a lot Matt, following your code I could solve the problem, this is the code I finally used:

$rowtag = $row['Tag'];
$resulttag = preg_match( "/<N>(.*)<\/N>/", $rowtag, $matches );
echo $matches[1]. "</td></tr></table>";
13-Nov-10 13:27
Yes, that is a better data format. You want to use delimiters that will never be seen in the data.

Glad you solved it


Post a response

Want to add a comment, or ask a question about this article? Post a response.

To post responses you need to be a member. Not a member yet? Signing up is free, easy and only takes a minute. Sign up now.

Top of Page