Der eigentliche Code Smell an der Stelle ist weder das vorhandensein verschiedener Vergleichsoperatoren noch die Wahl des Startindexes - sondern dass eine Funktion verschiedene Datentypen zurückgibt. Aber lustig, dass DAS niemanden zu stören scheint

Liegt wohl daran, dass das in einer dynamischen Sprache kein Code-Smell, sondern ein Feature ist

Wobei das immer weniger wird. Interessanterweise ist da Code-Completion und Dokumentation der Treiber dahinter. Da kann eine Rückgabe nur einen Typ haben.
Wirklich fies ist, dass die Funktionen teils str_* teils str* heißen und haystack und needle auch noch munter vertauscht werden. Und das das dann auch noch Inhalt der Zertifizierungsprüfung ist