substr_compare()
A função substr_compare() do PHP compara duas strings a partir de uma posição inicial especificada até um comprimento definido.
Introdução
A função substr_compare() compara uma parte de uma string com outra string, a partir de um deslocamento especificado. Funciona como comparar uma substring de $main_str contra $str — mas sem precisar chamar substr() primeiro para extrair a string. Isso a torna a forma idiomática e sem alocação de memória para responder perguntas como "essa string começa com X?" ou "essa string termina com Y?" em versões mais antigas do PHP.
Este capítulo explica os parâmetros, o significado do valor de retorno e os padrões comuns (verificações de prefixo, sufixo e comparação sem distinção de maiúsculas/minúsculas) onde substr_compare() se destaca.
Sintaxe
substr_compare(
string $haystack,
string $needle,
int $offset,
?int $length = null,
bool $case_insensitive = false
): intNota: O parâmetro
$lengthé opcional. No PHP 8+ ele é explicitamente tipado como nullable (?int); passarnull(ou omiti-lo) compara até o fim de$haystack.
| Parâmetro | Descrição |
|---|---|
$haystack | A string principal. A comparação lê uma fatia dessa string. |
$needle | A string comparada contra a fatia de $haystack. |
$offset | Onde em $haystack a comparação começa. Um valor negativo conta a partir do final de $haystack. |
$length | Quantos caracteres comparar. Se null, o maior entre o restante de $haystack e o $needle completo é utilizado. |
$case_insensitive | Se true, maiúsculas e minúsculas são ignoradas ("A" é igual a "a"). Padrão é false. |
Valor de retorno
substr_compare() retorna um int:
0— as partes comparadas são iguais.- um número negativo — a fatia de
$haystacké menor que$needle(vem antes na ordenação). - um número positivo — a fatia de
$haystacké maior que$needle(vem depois na ordenação).
O sinal é o que importa; a magnitude exata é definida pela implementação e não deve ser utilizada como referência. Para verificar igualdade, compare explicitamente com 0: substr_compare(...) === 0.
Exemplo básico
Aqui comparamos os primeiros strlen($string2) (6) caracteres de "Hello World!" contra "Hello!". O sexto caractere é um espaço (" ") na primeira string, mas um ponto de exclamação ("!") na segunda; um espaço (ASCII 32) vem antes de ! (ASCII 33), portanto a função retorna um inteiro negativo (-1).
Verificando se uma string começa com um prefixo
Comparar no deslocamento 0 com $length igual ao comprimento do prefixo é um teste limpo de "começa com":
<?php
function startsWith(string $haystack, string $prefix): bool
{
return substr_compare($haystack, $prefix, 0, strlen($prefix)) === 0;
}
var_dump(startsWith("php-fpm", "php")); // bool(true)
var_dump(startsWith("python", "php")); // bool(false)No PHP 8.0+ você pode usar a função nativa
str_starts_with()em vez disso.substr_compare()continua útil em runtimes mais antigos e quando você também precisa de insensibilidade a maiúsculas/minúsculas.
Verificando se uma string termina com um sufixo
Um deslocamento negativo conta a partir do final da string, o que torna as verificações de "termina com" simples — você não precisa calcular a posição manualmente:
<?php
function endsWith(string $haystack, string $suffix): bool
{
return substr_compare($haystack, $suffix, -strlen($suffix)) === 0;
}
var_dump(endsWith("report.pdf", ".pdf")); // bool(true)
var_dump(endsWith("report.txt", ".pdf")); // bool(false)Comparação sem distinção de maiúsculas/minúsculas
Defina o quinto argumento como true para ignorar maiúsculas e minúsculas:
<?php
$sensitive = substr_compare("Hello", "hello", 0);
$insensitive = substr_compare("Hello", "hello", 0, null, true);
echo $sensitive; // non-zero: 'H' and 'h' differ
echo PHP_EOL;
echo $insensitive; // 0: equal when case is ignoredArmadilhas
- Deslocamento fora do intervalo. Um
$offsetpositivo maior que o comprimento de$haystackgera umValueErrorno PHP 8+ (um aviso retornandofalseno PHP 7). Valide os deslocamentos contrastrlen($haystack)quando vierem de entrada do usuário. $lengthmaior que o restante disponível. Se$lengthexceder os caracteres disponíveis, apenas os caracteres disponíveis são comparados — a função não gera erro, simplesmente compara menos.- Baseado em bytes, não compatível com multibyte.
substr_compare()trabalha com bytes. Para texto UTF-8 onde um caractere pode ocupar vários bytes, os deslocamentos e comprimentos são deslocamentos de bytes, não de caracteres.
Funções relacionadas
strcmp()— comparação binária segura de duas strings completas.strncmp()— compara apenas os primeiros n caracteres de duas strings.strcasecmp()— comparação sem distinção de maiúsculas/minúsculas de duas strings completas.substr()— extrai uma parte de uma string.
Conclusão
substr_compare() compara uma fatia de uma string contra outra sem precisar extraí-la primeiro, o que a torna eficiente para verificações de prefixo e sufixo. Lembre-se de testar o resultado contra 0 para igualdade, use um $offset negativo para testes de "termina com" e passe true como último argumento quando maiúsculas/minúsculas devem ser ignoradas.