PHP 8.0: New str_starts_with
and str_ends_with
functions
PHP 8.0 comes with two new functions to help you easily assert if a given string is present at the beginning or ending of a haystack string. This goes nicely with str_contains()
in PHP 8.0.
str_starts_with()
: Check if a given haystack string starts with the given needle stringstr_ends_with
: Check if a given haystack string ends with the given needle string
str_starts_with(string $haystack, string $needle): bool;
str_ends_with(string $haystack, string $needle): bool;
PHP 8 finally brings the total number of string-related functions in PHP to over 100, and the new functions can be easily mimicked with existing functions such as strpos
, substr
, strncmp
, and substr_compare
. However, these new functions were well-received due to possible engine-level optimizations and their frequent use-cases.
Case sensitivity
Both str_starts_with()
and str_ends_with()
functions are case-sensitive. There are no flags or other functions to make them case-insensitive. This is the same pattern with str_contains
Multi-byte strings
Multi-byte (mb_*
) variants for str_starts_with()
and str_ends_with()
are not currently planned.
Empty strings
Similar to str_contains
, PHP now considers empty string (""
) to be present in everywhere in a string. To quote Nikita:
As of PHP 8, behavior of '' in string search functions is well defined, and we consider '' to occur at every position in the string, including one past the end. As such, both of these will (or at least should) return true. The empty string is contained in every string.
The following calls will be always true:
str_starts_with('Foo', ''); // true
str_starts_with('', ''); // true
str_ends_with('Foo', ''); // true
str_ends_with('', ''); // true
Polyfills
Here is a polyfill for PHP 7.0 and later. Be sure to wrap them with function_exists()
calls where you use them. These functions pass the exact same tests in PHP core.
function str_starts_with(string $haystack, string $needle): bool {
return \strncmp($haystack, $needle, \strlen($needle)) === 0;
}
function str_ends_with(string $haystack, string $needle): bool {
return $needle === '' || $needle === \substr($haystack, - \strlen($needle));
}
Conflicts with current user-land implementations
Starts-with and ends-with functionality is often provided as helper functions in various frameworks. This includes Symfony String component, Laravel Str
helper, and Yii StringHelper
.
There are over 4,000 str_starts_with()
matches on GitHub, for PHP, most of which appear to be already namespaced.
Case-insensitivity support | Empty strings at every position | |
---|---|---|
PHP 8.0 str_starts_with str_ends_with |
No | Yes |
Polyfill (above) str_starts_with str_ends_with |
No | Yes |
Symfony String ::startsWith ::endsWith |
Yes With ::ignoreCase() |
No |
Laravel Str::startsWith Str::endsWith |
No | No |
Yii StringHelper::startsWith StringHelper::endsWith |
Yes (default) With parameter |
No |
Backwards compatibility impact
Both str_starts_with
and str_ends_with
functions are new functions. Unless you already have a str_contains()
function declared, there should be no BC impact.
PHP 8's new behavior that it considers there is an empty string at every position of a string can be tricky. Note that Laravel helpers and Symfony String component, among many others return false
when you search for an empty string needle (""
) at the start and end of strings, although PHP core returns true
.