NeuroAgent

How to Implement startsWith() and endsWith() in PHP

Learn how to implement efficient startsWith() and endsWith() functions in PHP. Discover built-in solutions for PHP 8.0+ and custom implementations for older versions with performance comparisons and best practices.

Question

How to Implement startsWith() and endsWith() Functions in PHP

How can I create two PHP functions that check if a string starts with or ends with a specified character or substring?

For example, I need functions that would:

  • Return true if a string starts with a given prefix
  • Return true if a string ends with a given suffix

Example usage:

php
$str = '|apples}';

echo startsWith($str, '|'); // Should return true
echo endsWith($str, '}');   // Should return true

What is the most efficient way to implement these functions in PHP, and are there any built-in alternatives?

NeuroAgent

PHP provides several ways to implement startsWith() and endsWith() functionality, with the most efficient approach being the built-in str_starts_with() and str_ends_with() functions available in PHP 8.0 and later. For older PHP versions, you can create custom implementations using various string manipulation techniques.

Contents

Built-in PHP Functions (PHP 8.0+)

Since PHP 8.0, you can use native functions that are optimized and type-safe:

php
$str = '|apples}';

// Using built-in functions
echo str_starts_with($str, '|'); // Returns true
echo str_ends_with($str, '}');   // Returns true

These functions offer several advantages over custom implementations:

  • Type safety: They perform strict type checking
  • Performance: They’re implemented in C and faster than PHP alternatives
  • Unicode support: Properly handle multi-byte characters
  • Null safety: Return false instead of throwing warnings on null inputs

The TYPO3 Core Changelog specifically mentions that these built-in functions support proper typing and are faster than previous implementations.

Custom Implementations for Older PHP Versions

For PHP versions before 8.0, here are several implementation approaches:

1. Using Substring Comparison

php
function startsWith($haystack, $needle) {
    return substr($haystack, 0, strlen($needle)) === $needle;
}

function endsWith($haystack, $needle) {
    return substr($haystack, -strlen($needle)) === $needle;
}

2. Using strpos() for startsWith()

php
function startsWith($haystack, $needle) {
    return strpos($haystack, $needle) === 0;
}

function endsWith($haystack, $needle) {
    return strrpos($haystack, $needle) === strlen($haystack) - strlen($needle);
}

3. Using Regular Expressions

php
function startsWith($haystack, $needle) {
    return preg_match('/^' . preg_quote($needle, '/') . '/', $haystack) === 1;
}

function endsWith($haystack, $needle) {
    return preg_match('/' . preg_quote($needle, '/') . '$/', $haystack) === 1;
}

4. Case-Insensitive Versions

php
function startsWithIgnoreCase($haystack, $needle) {
    return stripos($haystack, $needle) === 0;
}

function endsWithIgnoreCase($haystack, $needle) {
    return stripos(strrev($haystack), strrev($needle)) === 0;
}

Performance Comparison

Built-in functions significantly outperform custom implementations:

Method Performance PHP Version Notes
str_starts_with()/str_ends_with() Fastest PHP 8.0+ C-based implementation
substr() comparison Good All versions Reliable and readable
strpos() method Good All versions Slightly faster than substr
Regular expressions Slowest All versions Most flexible but slowest

According to the TYPO3 documentation, the built-in PHP 8.0 functions are faster than their custom counterparts.


Best Practices and Framework-Specific Solutions

Framework Implementations

Laravel provides convenient helper functions as mentioned in the search results:

php
// Laravel helpers
starts_with($str, '|');  // Returns true
ends_with($str, '}');    // Returns true

Modern PHP Techniques

For modern PHP development:

  1. Always use built-in functions when possible (PHP 8.0+)
  2. Add type hints for better code quality
  3. Handle edge cases like empty needles
  4. Consider performance for high-frequency operations

Complete Type-Safe Implementation

php
function startsWith(string $haystack, string $needle): bool {
    if ($needle === '') {
        return true;
    }
    return str_starts_with($haystack, $needle);
}

function endsWith(string $haystack, string $needle): bool {
    if ($needle === '') {
        return true;
    }
    return str_ends_with($haystack, $needle);
}

For PHP < 8.0 compatibility:

php
function startsWith(string $haystack, string $needle): bool {
    if ($needle === '') {
        return true;
    }
    return substr($haystack, 0, strlen($needle)) === $needle;
}

function endsWith(string $haystack, string $needle): bool {
    if ($needle === '') {
        return true;
    }
    return substr($haystack, -strlen($needle)) === $needle;
}

Complete Implementation Examples

Here’s a comprehensive solution that works across PHP versions:

php
<?php

/**
 * Check if a string starts with a given prefix
 * 
 * @param string $haystack The string to search in
 * @param string $needle The prefix to search for
 * @return bool True if string starts with prefix
 */
function startsWith(string $haystack, string $needle): bool {
    if ($needle === '') {
        return true;
    }
    
    if (function_exists('str_starts_with')) {
        return str_starts_with($haystack, $needle);
    }
    
    return substr($haystack, 0, strlen($needle)) === $needle;
}

/**
 * Check if a string ends with a given suffix
 * 
 * @param string $haystack The string to search in
 * @param string $needle The suffix to search for
 * @return bool True if string ends with suffix
 */
function endsWith(string $haystack, string $needle): bool {
    if ($needle === '') {
        return true;
    }
    
    if (function_exists('str_ends_with')) {
        return str_ends_with($haystack, $needle);
    }
    
    return substr($haystack, -strlen($needle)) === $needle;
}

// Usage examples
$str = '|apples}';

echo startsWith($str, '|') ? 'true' : 'false'; // true
echo endsWith($str, '}') ? 'true' : 'false';   // true

// Edge cases
echo startsWith('hello', '') ? 'true' : 'false'; // true (empty prefix)
echo endsWith('hello', '') ? 'true' : 'false';   // true (empty suffix)
?>

This implementation:

  • Automatically detects PHP version and uses optimal functions
  • Handles empty needles correctly (returns true)
  • Provides type hints for better IDE support
  • Works across all PHP versions with consistent behavior
  • Is backward compatible with the example usage pattern

Sources

  1. TYPO3 Core Changelog - StringUtility::beginsWith() and StringUtility::endsWith() Deprecation
  2. Stop Guessing! The Ultimate PHP String Starts With Code (PHP 5-8+)
  3. PHP - Wikipedia
  4. Reverse String in PHP – Easy Code Examples

Conclusion

When implementing startsWith() and endsWith() functionality in PHP, consider these key points:

  • For PHP 8.0+: Always use the built-in str_starts_with() and str_ends_with() functions for optimal performance and type safety
  • For older PHP versions: Implement custom functions using substr() comparison for best performance and readability
  • Framework integration: Leverage framework helpers like Laravel’s starts_with() and ends_with() when available
  • Edge case handling: Always consider empty needles and type consistency
  • Performance matters: Choose the right implementation based on your PHP version and performance requirements

The most efficient approach is to use PHP’s built-in functions when available, and fall back to well-tested custom implementations for older versions. This ensures both performance and compatibility across different PHP environments.