Signature
strpbrk(string $string, string $characters): string|falsePurpose
strpbrk() searches a string for the first character that appears in a set of characters you supply. When it finds one, it returns the part of the string that starts at that character and runs to the end. If no character from the set occurs, it returns false.
Think of it as a "find the nearest delimiter" tool. You hand it several possible delimiters, such as a comma, a semicolon and a space, and it tells you where the first of them appears. Unlike strpos(), it does not return a position. It returns the tail of the string, which is similar to what strstr() does for a single substring.
Signature
Parameters and defaults
$string: the subject string to search. There is no default.$characters: a string treated as a set of individual characters, not as a substring.'mi'means "eithermori". Matching is case sensitive, so'S'does not matchs. There is no default.
The order of characters inside $characters does not matter. The function reports whichever matching character occurs earliest in $string, regardless of where it sits in the set.
Return value and failure cases
On success you get a non-empty string beginning with the first matching character. If nothing matches, or if $string is empty, you get false. In PHP 8.4, passing an empty $characters string throws a ValueError, so a set that comes from user input or configuration should be validated first.
The function works on bytes, not on Unicode characters. With UTF-8 text, a multibyte character in $characters is treated as several separate bytes, and any of those bytes can match. ASCII delimiters work reliably in UTF-8 text, because their bytes never appear inside multibyte sequences. For true multibyte character sets, use preg_match() with the u modifier instead.
Example 1: basic matching
The first call matches i at the third character, because i comes before any m in the text. The second call is case sensitive. The third finds nothing and returns false.
$text = 'This is a Simple text.';
echo json_encode([
strpbrk($text, 'mi'),
strpbrk($text, 'S'),
strpbrk($text, 'qz'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;["is is a Simple text.","Simple text.",false]
Example 2: splitting at the first delimiter
A common use is cutting a string at whichever delimiter comes first. Since strpbrk() returns the tail, the head is everything before that tail. Subtracting the tail's length with substr() recovers it. The first character of the tail tells you which delimiter was hit.
$input = 'name:Ada;role=admin';
$rest = strpbrk($input, ';,');
$head = $rest === false ? $input : substr($input, 0, -strlen($rest));
$delimiter = $rest === false ? null : $rest[0];
echo json_encode(['head' => $head, 'delimiter' => $delimiter, 'rest' => $rest], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"head":"name:Ada","delimiter":";","rest":";role=admin"}
Note that the colon in name:Ada is not in the set, so it is ignored. Only ; and , count.
Example 3: edge cases
This example shows an empty subject, an empty character set and a match that is a falsy string.
$emptySubject = strpbrk('', 'abc');
try {
strpbrk('abc', '');
$emptySet = 'no error';
} catch (ValueError $e) {
$emptySet = get_class($e);
}
$zero = strpbrk('abc0', '0');
echo json_encode([
'empty_subject' => $emptySubject,
'empty_set' => $emptySet,
'zero' => $zero,
'truthy' => (bool) $zero,
'found' => $zero !== false,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"empty_subject":false,"empty_set":"ValueError","zero":"0","truthy":false,"found":true}
Edge cases to remember
- Empty subject: searching
''returnsfalse, because there is nothing to match. - Empty set:
$charactersmust not be empty. Catch theValueErroror check the value beforehand. - Match at position zero: if the first character already matches, the whole string is returned unchanged.
- Repeated characters in the set: duplicates are harmless.
'aaa'behaves like'a'. - Special characters: there is no pattern syntax. A dot, a bracket or a hyphen in
$charactersis just that literal byte, so you do not escape anything and ranges likea-zare not supported. - Binary data: null bytes are ordinary bytes and can be searched for.
Common mistakes
- Treating the set as a substring.
strpbrk($s, 'ab')does not look for the textab. It looks foraorb. For a literal substring usestrstr()orstrpos(). - Testing the result with a loose check. A match can be the string
"0", which is falsy, as Example 3 shows. Always compare with=== falseor!== false. - Expecting a position. If you need an index, use
strcspn()to count the characters before the first match, or computestrlen($string) - strlen($result). - Ignoring case. The search is case sensitive. To ignore case, include both forms in the set, such as
'aA'. - Using it with multibyte characters. Because it is byte based, an accented letter or emoji in the set can produce a surprising partial match. Use
preg_match()with/ufor that. - Passing a dynamic, possibly empty set. An empty string for
$charactersthrows, so guard it.
Related functions
strpos()finds the position of a substring.strstr()returns the tail starting at a substring.strcspn()returns the length of the initial segment that contains none of the given characters.strspn()returns the length of the initial segment made only of the given characters.preg_match()handles complex or Unicode-aware patterns.
Recap
strpbrk($string, $characters) returns the tail of $string beginning at the first character that is found in the set $characters, or false when there is none. It is case sensitive and byte based. The set must be non-empty, and the result should always be checked with a strict comparison.
Tested examples
$text = 'This is a Simple text.';
echo json_encode([
strpbrk($text, 'mi'),
strpbrk($text, 'S'),
strpbrk($text, 'qz'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;["is is a Simple text.","Simple text.",false]
$input = 'name:Ada;role=admin';
$rest = strpbrk($input, ';,');
$head = $rest === false ? $input : substr($input, 0, -strlen($rest));
$delimiter = $rest === false ? null : $rest[0];
echo json_encode(['head' => $head, 'delimiter' => $delimiter, 'rest' => $rest], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"head":"name:Ada","delimiter":";","rest":";role=admin"}
$emptySubject = strpbrk('', 'abc');
try {
strpbrk('abc', '');
$emptySet = 'no error';
} catch (ValueError $e) {
$emptySet = get_class($e);
}
$zero = strpbrk('abc0', '0');
echo json_encode([
'empty_subject' => $emptySubject,
'empty_set' => $emptySet,
'zero' => $zero,
'truthy' => (bool) $zero,
'found' => $zero !== false,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"empty_subject":false,"empty_set":"ValueError","zero":"0","truthy":false,"found":true}