substr_compare()
La función substr_compare() de PHP compara dos cadenas desde una posición de inicio especificada hasta una longitud determinada.
Introducción
La función substr_compare() compara una porción de una cadena con otra cadena, comenzando en un desplazamiento dado. Funciona como comparar una subcadena de $main_str contra $str, pero sin necesidad de llamar primero a substr() para extraer esa porción. Esto la convierte en la forma idiomática y sin asignación de memoria para responder preguntas como "¿esta cadena comienza con X?" o "¿esta cadena termina con Y?" en versiones antiguas de PHP.
Este capítulo explica los parámetros, el significado del valor de retorno y los patrones comunes (comprobación de prefijos, sufijos, comparación sin distinción de mayúsculas) donde substr_compare() destaca.
Sintaxis
substr_compare(
string $haystack,
string $needle,
int $offset,
?int $length = null,
bool $case_insensitive = false
): intNota: El parámetro
$lengthes opcional. En PHP 8+ está tipado explícitamente como nullable (?int); pasarnull(u omitirlo) compara hasta el final de$haystack.
| Parámetro | Descripción |
|---|---|
$haystack | La cadena principal. La comparación lee una porción de esta cadena. |
$needle | La cadena que se compara contra la porción de $haystack. |
$offset | Posición en $haystack donde comienza la comparación. Un valor negativo cuenta desde el final de $haystack. |
$length | Número de caracteres a comparar. Si es null, se utiliza el mayor entre los caracteres restantes de $haystack y el total de $needle. |
$case_insensitive | Si es true, se ignora la distinción de mayúsculas ("A" es igual a "a"). Por defecto es false. |
Valor de retorno
substr_compare() devuelve un int:
0— las porciones comparadas son iguales.- un número negativo — la porción de
$haystackes menor que$needle(se ordena antes). - un número positivo — la porción de
$haystackes mayor que$needle(se ordena después).
Lo que importa es el signo; la magnitud exacta está definida por la implementación y no debe ser utilizada como referencia. Para comprobar la igualdad, compare contra 0 explícitamente: substr_compare(...) === 0.
Ejemplo básico
Aquí comparamos los primeros strlen($string2) (6) caracteres de "Hello World!" contra "Hello!". El sexto carácter es un espacio (" ") en la primera cadena pero un signo de exclamación ("!") en la segunda; un espacio (ASCII 32) se ordena antes que ! (ASCII 33), por lo que la función devuelve un entero negativo (-1).
Comprobar si una cadena comienza con un prefijo
Comparar en el desplazamiento 0 con $length igual a la longitud del prefijo es una prueba limpia de "comienza con":
<?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)En PHP 8.0+ puede usar la función integrada
str_starts_with()en su lugar.substr_compare()sigue siendo útil en versiones anteriores y cuando también se necesita insensibilidad a mayúsculas.
Comprobar si una cadena termina con un sufijo
Un desplazamiento negativo cuenta desde el final de la cadena, lo que hace que las comprobaciones de "termina con" sean sencillas — no necesita calcular la posición usted mismo:
<?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)Comparación sin distinción de mayúsculas
Establezca el quinto argumento en true para ignorar la distinción de mayú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 ignoredAdvertencias
- Desplazamiento fuera de rango. Un
$offsetpositivo mayor que la longitud de$haystackgenera unValueErroren PHP 8+ (una advertencia que devuelvefalseen PHP 7). Valide los desplazamientos contrastrlen($haystack)cuando provienen de la entrada del usuario. $lengthmayor que los caracteres restantes. Si$lengthsupera los caracteres disponibles, solo se comparan los disponibles — la función no genera un error, simplemente compara menos.- Basado en bytes, no en multibyte.
substr_compare()trabaja con bytes. Para texto UTF-8 donde un carácter puede abarcar varios bytes, los desplazamientos y las longitudes son desplazamientos de bytes, no de caracteres.
Funciones relacionadas
strcmp()— comparación binaria segura de dos cadenas completas.strncmp()— compara solo los primeros n caracteres de dos cadenas.strcasecmp()— comparación sin distinción de mayúsculas de dos cadenas completas.substr()— extrae una porción de una cadena.
Conclusión
substr_compare() compara una porción de una cadena contra otra sin necesidad de extraerla primero, lo que la hace eficiente para comprobaciones de prefijos y sufijos. Recuerde comparar el resultado contra 0 para verificar la igualdad, use un $offset negativo para pruebas de "termina con", y pase true como último argumento cuando se deba ignorar la distinción de mayúsculas.