str_contains(), str_starts_with(), str_ends_with()
This was the single most-requested feature in PHP's history, and 8.0 finally delivered. No more strpos() !== false gymnastics, no more off-by-one risks with index 0, no more substr($str, 0, strlen($prefix)) === $prefix.
// Before — the classic footgun
if (strpos($url, 'https') !== false) { /* ... */ } // Easy to write === 0 when you mean !== false
if (substr($file, -4) === '.php') { /* ... */ } // Works but reads terribly
// After — say what you mean
if (str_contains($url, 'https')) { /* ... */ }
if (str_starts_with($file, '/var/www')) { /* ... */ }
if (str_ends_with($file, '.php')) { /* ... */ }
These functions are named exactly as you'd expect. They take the haystack first, needle second — consistently. They return booleans. There is zero ambiguity about what they do or how to use them. This is what consistency looks like when a language team listens to its community.
Significance: Consistency
Consistent naming and behavior let developers write code from memory instead of constantly checking documentation. These three functions fixed one of PHP's most-cited inconsistencies and proved that the language is willing to evolve based on real developer pain.