Keywords: PHP | string functions | prefix check | suffix check | case sensitivity
Abstract: This article comprehensively explores methods for checking string prefixes and suffixes in PHP, including built-in functions str_starts_with and str_ends_with in PHP 8.0 and above, as well as custom implementations for earlier versions. Through code examples and in-depth analysis, it covers function syntax, parameters, return values, case sensitivity handling, practical applications such as file extension validation and URL protocol checks, and performance considerations to assist developers in efficient string manipulation.
Introduction
In PHP development, string operations are common tasks, and checking whether a string starts or ends with a specific substring is particularly crucial. For instance, in validating user input, processing file paths, or analyzing URLs, such operations can significantly enhance code robustness and readability. Based on PHP official documentation and community best practices, this article systematically introduces the implementation of startsWith and endsWith functionalities, covering compatibility solutions across different PHP versions.
Built-in Functions in PHP 8.0 and Above
Since PHP 8.0, the language includes built-in functions str_starts_with and str_ends_with, simplifying the checking of string prefixes and suffixes. These functions return boolean values with concise syntax and high efficiency. The str_starts_with function takes two parameters: the main string and the substring to check, returning true if the main string starts with the substring, otherwise false. Similarly, str_ends_with checks if the string ends with the specified substring.
// Example: Using str_starts_with and str_ends_with
$exampleString = '|apples}';
$startsResult = str_starts_with($exampleString, '|'); // Returns true
$endsResult = str_ends_with($exampleString, '}'); // Returns true
var_dump($startsResult); // Output: bool(true)
var_dump($endsResult); // Output: bool(true)These built-in functions are optimized at a low level for fast execution and do not require additional custom code. However, note that they are case-sensitive, so preprocessing strings may be necessary in scenarios requiring case-insensitive checks.
Custom Functions for PHP Versions Before 8.0
For PHP versions prior to 8.0, developers need to implement similar functionalities through custom functions. The startsWith function compares the beginning of the string with the substring, while endsWith handles the end portion. Custom implementations must account for edge cases, such as handling empty strings.
// Custom startsWith function implementation
function startsWith($haystack, $needle) {
$needleLength = strlen($needle);
if ($needleLength === 0) {
return true; // Empty string is considered a match
}
return substr($haystack, 0, $needleLength) === $needle;
}
// Custom endsWith function implementation
function endsWith($haystack, $needle) {
$needleLength = strlen($needle);
if ($needleLength === 0) {
return true; // Empty string is considered a match
}
return substr($haystack, -$needleLength) === $needle;
}
// Usage example
$testString = '|apples}';
$startCheck = startsWith($testString, '|'); // Returns true
$endCheck = endsWith($testString, '}'); // Returns true
var_dump($startCheck); // Output: bool(true)
var_dump($endCheck); // Output: bool(true)The logic of these functions is straightforward: first, obtain the length of the substring, then use the substr function to extract the relevant part for comparison. Empty strings are specially handled to avoid errors. Although custom functions are less efficient than built-in ones, they provide backward compatibility.
Handling Case Sensitivity
By default, string comparisons in PHP are case-sensitive, which can cause issues in certain applications. For example, when checking filenames or URLs, ignoring case can improve flexibility. By combining with the strtolower function, case-insensitive versions can be implemented.
// Case-insensitive startsWith function
function startsWithCaseInsensitive($haystack, $needle) {
$needleLength = strlen($needle);
if ($needleLength === 0) {
return true;
}
return strtolower(substr($haystack, 0, $needleLength)) === strtolower($needle);
}
// Case-insensitive endsWith function
function endsWithCaseInsensitive($haystack, $needle) {
$needleLength = strlen($needle);
if ($needleLength === 0) {
return true;
}
return strtolower(substr($haystack, -$needleLength)) === strtolower($needle);
}
// Example: Case-insensitive check
$caseString = 'Apple Pie';
$insensitiveStart = startsWithCaseInsensitive($caseString, 'apple'); // Returns true
var_dump($insensitiveStart); // Output: bool(true)This method ensures consistency by converting strings to lowercase before comparison, but it may add slight performance overhead. In practical applications, the trade-off should be weighed based on requirements.
Practical Application Examples
startsWith and endsWith functions are widely used in real-world development, such as validating file types, analyzing URL protocols, or filtering email domains. The following examples demonstrate how to integrate these functions into common tasks.
// Application 1: Validating file extensions
function isImageFile($filename) {
$allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif'];
foreach ($allowedExtensions as $ext) {
if (endsWithCaseInsensitive($filename, $ext)) {
return true;
}
}
return false;
}
// Usage example
$file1 = 'photo.JPG';
$file2 = 'document.pdf';
echo isImageFile($file1) ? 'Is an image file' : 'Not an image file'; // Output: Is an image file
echo isImageFile($file2) ? 'Is an image file' : 'Not an image file'; // Output: Not an image file
// Application 2: Checking URL protocol
function getUrlProtocol($url) {
$protocols = ['http://', 'https://', 'ftp://'];
foreach ($protocols as $proto) {
if (startsWithCaseInsensitive($url, $proto)) {
return $proto;
}
}
return 'Unknown';
}
// Usage example
$urlExample = 'https://example.com';
echo 'Protocol: ' . getUrlProtocol($urlExample); // Output: Protocol: https://
// Application 3: Validating email domains
function isCompanyEmail($email) {
$domains = ['@company.com', '@company.org'];
foreach ($domains as $domain) {
if (endsWithCaseInsensitive($email, $domain)) {
return true;
}
}
return false;
}
// Usage example
$emailTest = 'user@COMPANY.com';
echo isCompanyEmail($emailTest) ? 'Company email' : 'Not a company email'; // Output: Company emailThese examples highlight the practicality of the functions while emphasizing security considerations, such as combining with MIME type checks for file extension validation to mitigate risks.
Performance Considerations
In performance-sensitive applications, choosing the appropriate string comparison method is essential. Built-in functions str_starts_with and str_ends_with in PHP 8.0 and above are optimized and generally faster than custom implementations. For earlier versions, using the substr_compare function may offer better performance, especially with long strings.
// Optimized version using substr_compare
function startsWithOptimized($haystack, $needle) {
return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
}
function endsWithOptimized($haystack, $needle) {
return substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
// Example: Performance comparison
$longString = str_repeat('a', 8192) . '|apples}';
$fastStart = startsWithOptimized($longString, '|'); // Quickly returns true
var_dump($fastStart); // Output: bool(true)Benchmark tests show that substr_compare performs well in PHP 7, but built-in functions are superior in PHP 8.0. Developers should select the implementation based on the PHP version and specific context to balance performance and maintainability.
Conclusion
In summary, the startsWith and endsWith functionalities in PHP can be efficiently handled through built-in functions or custom implementations. For PHP 8.0 and above, it is recommended to use str_starts_with and str_ends_with for optimal performance and simplicity; for older versions, custom functions provide a reliable alternative. By incorporating case sensitivity handling and practical examples, developers can flexibly address various string manipulation needs, enhancing code quality and efficiency. As PHP evolves, built-in functions will become more prevalent, and adopting standard solutions is advised.