How can I write PHP functions to check if a string starts with or ends with a specified character or substring?
For example:
$str = '|apples}';
echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true
What is the implementation for startsWith() and endsWith() functions in PHP?
PHP offers multiple approaches to check if a string starts with or ends with a specified substring. For PHP 8.0+, you can use the native str_starts_with() and str_ends_with() functions, while older versions require custom implementations using functions like substr(), strpos(), or strncmp().
Contents
- Native PHP Functions
- Custom Implementation Methods
- Performance Considerations
- Complete Implementation Examples
- Best Practices and Recommendations
Native PHP Functions
PHP 8.0 introduced native functions specifically for checking string prefixes and suffixes, providing the most efficient and readable solution.
str_starts_with() Function
The str_starts_with() function checks if a string begins with a specified substring:
bool str_starts_with(string $haystack, string $needle): bool
Example:
$str = '|apples}';
echo str_starts_with($str, '|'); // Returns true
echo str_starts_with($str, 'app'); // Returns false
echo str_starts_with($str, ''); // Returns true
str_ends_with() Function
The str_ends_with() function checks if a string ends with a specified substring:
bool str_ends_with(string $haystack, string $needle): bool
Example:
$str = '|apples}';
echo str_ends_with($str, '}'); // Returns true
echo str_ends_with($str, 'les}'); // Returns true
echo str_ends_with($str, ''); // Returns true
Important Note: According to PHP.Watch, these functions are only available on PHP 8.0+. For empty needles, str_starts_with() returns true while str_ends_with() also returns true.
Custom Implementation Methods
For PHP versions before 8.0, you need to implement these functions manually. Here are several approaches:
Method 1: Using substr() and Direct Comparison
This is the most straightforward approach:
function startsWith($string, $startString) {
$len = strlen($startString);
return (substr($string, 0, $len) === $startString);
}
function endsWith($string, $endString) {
$len = strlen($endString);
if ($len == 0) {
return true;
}
return substr($string, -$len) === $endString;
}
Source: GeeksforGeeks
Method 2: Using strpos() for startsWith()
This method uses strpos() which returns the position of the first occurrence:
function startsWith($haystack, $needle) {
return strpos($haystack, $needle) === 0;
}
Source: TheoryApp
Method 3: Using strncmp() for Maximum Performance
For optimal performance, strncmp() is recommended as it only compares the specified number of characters:
function startsWith($haystack, $needle) {
return strncmp($haystack, $needle, strlen($needle)) === 0;
}
function endsWith($haystack, $needle) {
return $needle === '' || substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
Source: GitHub Gist
Method 4: Using strrpos() for endsWith()
This approach uses strrpos() to find the position of the last occurrence:
function startsWith(string $string, string $start): bool {
return strrpos($string, $start, - strlen($string)) !== false;
}
function endsWith(string $string, string $end): bool {
return ($offset = strlen($string) - strlen($end)) >= 0 &&
substr($string, $offset) === $end;
}
Source: Stack Overflow
Method 5: Using explode() for startsWith()
A creative approach using explode():
function startsWith($haystack, $needle) {
$cutsQuantity = 2;
$parts = explode($needle, $haystack, $cutsQuantity);
return ($parts[0] === '');
}
Source: Stack Overflow
Performance Considerations
The performance of different implementations varies significantly, especially with large strings:
Performance Comparison
According to benchmark results from Reddit:
strncmp()approach: ~0.029958s for 400,000 iterationssubstr()approach: ~0.027378s for 400,000 iterationsstrpos()approach: ~22.501702s for 400,000 iterations
The difference is dramatic because strpos() needs to search the entire string (O(n) complexity), while strncmp() and substr() only check the beginning/end (O(1) complexity).
Memory Efficiency
As noted in PHP Backend, some approaches are more memory-efficient than others:
substr()can be memory inefficient as it creates copies of string partsstrncmp()is both CPU and memory efficient- Native PHP 8.0 functions are optimized for performance
Complete Implementation Examples
Here’s a complete, production-ready implementation that works across all PHP versions:
Basic Implementation
<?php
if (!function_exists('startsWith')) {
function startsWith($string, $startString) {
$len = strlen($startString);
return (substr($string, 0, $len) === $startString);
}
}
if (!function_exists('endsWith')) {
function endsWith($string, $endString) {
$len = strlen($endString);
if ($len == 0) {
return true;
}
return substr($string, -$len) === $endString;
}
}
// Example usage
$str = '|apples}';
echo startsWith($str, '|') ? 'true' : 'false'; // true
echo endsWith($str, '}') ? 'true' : 'false'; // true
echo startsWith($str, 'app') ? 'true' : 'false'; // false
echo endsWith($str, 'les}') ? 'true' : 'false'; // true
Performance-Optimized Implementation
<?php
if (!function_exists('startsWith')) {
function startsWith($haystack, $needle) {
return strncmp($haystack, $needle, strlen($needle)) === 0;
}
}
if (!function_exists('endsWith')) {
function endsWith($haystack, $needle) {
if ($needle === '') {
return true;
}
return substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
}
// Example with empty strings
echo startsWith('test', '') ? 'true' : 'false'; // true
echo endsWith('test', '') ? 'true' : 'false'; // true
Case-Insensitive Versions
<?php
if (!function_exists('startsWithIgnoreCase')) {
function startsWithIgnoreCase($string, $startString) {
return stripos($string, $startString) === 0;
}
}
if (!function_exists('endsWithIgnoreCase')) {
function endsWithIgnoreCase($string, $endString) {
$len = strlen($endString);
if ($len == 0) {
return true;
}
return strtolower(substr($string, -$len)) === strtolower($endString);
}
}
// Case-insensitive examples
echo startsWithIgnoreCase('Hello World', 'hello') ? 'true' : 'false'; // true
echo endsWithIgnoreCase('Hello World', 'world') ? 'true' : 'false'; // true
Best Practices and Recommendations
1. Check PHP Version First
Always check if you’re running PHP 8.0+ before implementing custom functions:
if (version_compare(PHP_VERSION, '8.0.0') >= 0) {
// Use native functions
$result = str_starts_with($string, $prefix);
} else {
// Use custom implementation
$result = startsWith($string, $prefix);
}
2. Handle Edge Cases
Always consider edge cases like empty strings and null values:
function safeStartsWith($string, $prefix) {
if ($string === null || $prefix === null) {
return false;
}
return startsWith($string, $prefix);
}
3. Choose the Right Implementation
For maximum performance in older PHP versions:
- Use
strncmp()forstartsWith() - Use
substr_compare()forendsWith()
4. Consider Using Polyfills
For large projects, consider using a polyfill library that provides these functions for all PHP versions. WordPress has implemented polyfills for these functions.
5. Maintain Consistency
If you’re working on an existing codebase, follow the established patterns rather than introducing new implementations.
Sources
- How to Use the StartsWith() and EndsWith() Functions in PHP - W3Docs
- PHP | startsWith() and endsWith() Functions - GeeksforGeeks
- startsWith() and endsWith() functions in PHP - Stack Overflow
- New
str_starts_withandstr_ends_withfunctions - PHP 8.0 • PHP.Watch - String StartsWith and EndsWith in PHP – TheoryApp
- PHP: startsWith & endsWith functions · GitHub
- str_starts_with and str_ends_with functions in PHP - Stack Overflow
- What’s New in PHP 8 (Features, Improvements, and the JIT Compiler) - Kinsta
- PHP 8.0 feature: quality of life improvements | Platform.sh
- Replace usage of strpos with str_starts_with – WordPress Trac
Conclusion
Implementing startsWith() and endsWith() functions in PHP can be done through native PHP 8.0+ functions or custom implementations for older versions. The native str_starts_with() and str_ends_with() functions provide the most readable and performant solution. For compatibility with older PHP versions, use strncmp() and substr_compare() for optimal performance. Always consider edge cases like empty strings and null values in your implementations. The choice between different implementation methods should be based on your PHP version, performance requirements, and code maintainability needs.