
Código cheio de strpos comparado com !== false é herança de PHP 5. O PHP 8 trouxe str_contains, str_starts_with e str_ends_with: devolvem bool de verdade e acabam com o esquecimento clássico do !== que transforma posição zero em falso.
// PHP 7.4
if (strpos($ua, 'Googlebot') !== false) { ... }
if (substr($rota, 0, 7) === '/admin/') { ... }
if (substr($arquivo, -5) === '.webp') { ... }
// PHP 8.3
if (str_contains($ua, 'Googlebot')) { ... }
if (str_starts_with($rota, '/admin/')) { ... }
if (str_ends_with($arquivo, '.webp')) { ... } O bug que sempre aparece em revisão de código é if (strpos($rota, ‘/admin/’)) sem comparação nenhuma. Quando a agulha está no começo da string, strpos devolve 0, o if trata como falso e a regra some. Com str_starts_with isso não tem como acontecer.
As três são sensíveis a maiúsculas, igual strpos. Se o trecho antigo usava stripos, trocar direto por str_contains muda o comportamento: aí é str_contains(strtolower($a), strtolower($b)), ou mb_strtolower quando tem acento no meio.
Em projeto legado que roda em várias hospedagens eu escrevo o código novo e carrego o polyfill cedo, antes de qualquer coisa que use as funções:
if (!function_exists('str_contains')) {
function str_contains(string $palheiro, string $agulha): bool {
return $agulha === '' || strpos($palheiro, $agulha) !== false;
}
} Se o projeto usa Composer, prefira o pacote symfony/polyfill-php80: cobre as três funções de uma vez e sai de cena sozinho quando o servidor sobe de versão.
Um detalhe do comportamento com agulha vazia: str_contains($texto, ”) devolve true sempre, e str_starts_with também. Se você monta o termo a partir de um campo de busca que pode chegar em branco, valide antes, senão o filtro deixa passar a lista inteira.
Um grep por “!== false” no projeto costuma render uma limpeza rápida e sem risco de regressão.
A observação do pedido chegou com ordem embutida para gerar cupom. Delimite o texto do cliente e trate a resposta…
Um CSV com SKU e preço, um wp eval-file que agenda início e fim da promoção guardando o estado anterior,…
O erro 1040 aparece quando todas as conexões estão ocupadas. Antes de subir o max_connections, veja quem está segurando cada…
Allowed memory size exhausted no painel: qual das duas constantes do wp-config.php mexer, onde conferir o valor real e por…
strtotime com data brasileira devolve false e o INSERT quebra no MySQL 8. Use createFromFormat com getLastErrors antes de mandar…
O hash que o Magento mostra junto do erro é o nome de um arquivo em var/report. Veja como abrir,…