PHP 8

str_contains no PHP 8: parar de comparar strpos com !== false

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.

Antes e depois

// 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.

Ainda tem servidor no 7.4?

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.

Post Recentes

Data Patch Magento 2: criar atributo de produto sem InstallData

Copiou um InstallData.php de tutorial antigo e o atributo não apareceu depois do setup:upgrade? Veja a classe de Data Patch…

13 horas atrás

Criar cupom no WooCommerce por código: WC_Coupon com validade e limite

Função pronta para gerar um cupom único por cliente depois do pedido concluído, com WC_Coupon, data de expiração, limite de…

1 dia atrás

Modifier de produto no Magento 2: campo novo no form sem sobrescrever XML

Como registrar um modifier no pool do formulário de produto do Magento 2 e criar um campo próprio na aba,…

2 dias atrás

Tela branca no WordPress 6.9: como achar o erro com PHP 8.3

Site abrindo em branco sem mensagem nenhuma? Leia o log do PHP-FPM, identifique o plugin que causou o fatal e…

2 dias atrás

DateTimeImmutable modify: por que a data não muda no PHP 8.3

Trocou DateTime por DateTimeImmutable e a data parou de andar? O modify devolve uma cópia nova em vez de alterar…

3 dias atrás

Defer nos scripts do WordPress 6.9 sem plugin, com wp_enqueue_script

Use o parâmetro strategy do wp_enqueue_script para adiar o JavaScript do tema, sem plugin de otimização, e entenda por que…

4 dias atrás