startsWith() and endsWith() functions in PHP
PHP 8.0 and higher
Since PHP 8.0 you can use the str_starts_with
and the str_ends_with
functions.
echo str_starts_with($str, '|');
PHP before 8.0
function startsWith( $haystack, $needle ) { $length = strlen( $needle ); return substr( $haystack, 0, $length ) === $needle;}
function endsWith( $haystack, $needle ) { $length = strlen( $needle ); if( !$length ) { return true; } return substr( $haystack, -$length ) === $needle;}
You can use substr_compare
function to check start-with and ends-with:
function startsWith($haystack, $needle) { return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;}function endsWith($haystack, $needle) { return substr_compare($haystack, $needle, -strlen($needle)) === 0;}
This should be one of the fastest solutions on PHP 7 (benchmark script). Tested against 8KB haystacks, various length needles and full, partial and no match cases. strncmp
is a touch faster for starts-with but it cannot check ends-with.
Updated 23-Aug-2016
Functions
function substr_startswith($haystack, $needle) { return substr($haystack, 0, strlen($needle)) === $needle;}function preg_match_startswith($haystack, $needle) { return preg_match('~' . preg_quote($needle, '~') . '~A', $haystack) > 0;}function substr_compare_startswith($haystack, $needle) { return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;}function strpos_startswith($haystack, $needle) { return strpos($haystack, $needle) === 0;}function strncmp_startswith($haystack, $needle) { return strncmp($haystack, $needle, strlen($needle)) === 0;}function strncmp_startswith2($haystack, $needle) { return $haystack[0] === $needle[0] ? strncmp($haystack, $needle, strlen($needle)) === 0 : false;}
Tests
echo 'generating tests';for($i = 0; $i < 100000; ++$i) { if($i % 2500 === 0) echo '.'; $test_cases[] = [ random_bytes(random_int(1, 7000)), random_bytes(random_int(1, 3000)), ];}echo "done!\n";$functions = ['substr_startswith', 'preg_match_startswith', 'substr_compare_startswith', 'strpos_startswith', 'strncmp_startswith', 'strncmp_startswith2'];$results = [];foreach($functions as $func) { $start = microtime(true); foreach($test_cases as $tc) { $func(...$tc); } $results[$func] = (microtime(true) - $start) * 1000;}asort($results);foreach($results as $func => $time) { echo "$func: " . number_format($time, 1) . " ms\n";}
Results (PHP 7.0.9)
(Sorted fastest to slowest)
strncmp_startswith2: 40.2 msstrncmp_startswith: 42.9 mssubstr_compare_startswith: 44.5 mssubstr_startswith: 48.4 msstrpos_startswith: 138.7 mspreg_match_startswith: 13,152.4 ms
Results (PHP 5.3.29)
(Sorted fastest to slowest)
strncmp_startswith2: 477.9 msstrpos_startswith: 522.1 msstrncmp_startswith: 617.1 mssubstr_compare_startswith: 706.7 mssubstr_startswith: 756.8 mspreg_match_startswith: 10,200.0 ms