substr($string, $offset, $length) retorna a parte de $string que começa na posição $offset (contada a partir de 0) e tem $length caracteres. substr('Hello world', 0, 5) retorna "Hello". Deixe de fora $length para pegar tudo até o fim.
O substr() conta bytes. Isso é o mesmo que caracteres para texto em inglês, mas não para japonês, chinês, emoji ou letras acentuadas. Para esses, use mb_substr(), mostrado abaixo.
Sintaxe
substr(string $string, int $offset, ?int $length = null): string
$offseté onde começar.0é o primeiro caractere. Um valor negativo conta a partir do fim.$lengthé quantos bytes pegar (um byte é um caractere em texto ASCII simples). Um valor negativo deixa essa quantidade de fora no fim.null(ou omitir) significa "até o fim".
Offset e tamanho negativos: trabalhar a partir do fim
Um $offset negativo começa a contar a partir do fim da string, então -1 é o último caractere. Um $length negativo para essa quantidade de caracteres antes do fim.
substr($s, 0, -1) é o jeito comum de remover o último caractere, por exemplo uma vírgula que sobrou de um loop.
Pegar o primeiro ou o último caractere
Para um único byte, você também pode indexar a string diretamente. $s[0] é o primeiro caractere e, desde o PHP 7.1, $s[-1] é o último.
Indexar uma posição que não existe imprime um aviso, enquanto o substr() só retorna uma string vazia. Se a string puder estar vazia, prefira o substr().
Fora do intervalo: uma string vazia, não false
Se $offset estiver depois do fim da string, o substr() retorna "" no PHP 8. No PHP 7 ele retornava false, então código antigo que verifica === false não funciona mais.
Texto em japonês: use mb_substr
O UTF-8 guarda kana e kanji comuns em 3 bytes cada (kanji raros como 𠮷 e emoji ocupam 4). O substr() conta bytes, então substr('こんにちは', 0, 3) retorna só こ, e um tamanho que não cai numa fronteira de caractere corta um caractere ao meio e produz texto quebrado. O mb_substr() recebe os mesmos argumentos e conta caracteres.
O mesmo vale para emoji e letras acentuadas como é. Para contar caracteres, use mb_strlen(); veja strlen() sobre bytes e caracteres.
Encurtar texto com reticências
Cortar um título longo para uma lista ou um card é o uso real mais comum do substr(). Use mb_substr() para que um título em japonês nunca seja cortado no meio de um caractere, e só adicione ... quando você realmente encurtou algo.
mb_strimwidth($text, 0, $width, '...') faz o mesmo pela largura de exibição, em que um caractere japonês de largura total conta como 2 colunas e uma letra latina como 1. Serve para layouts de largura fixa.
Contar uma substring com substr_count
substr_count($haystack, $needle) retorna quantas vezes $needle aparece. Ele diferencia maiúsculas e minúsculas e não conta correspondências sobrepostas.
substr com strpos: texto antes ou depois de um caractere
Combine substr() com strpos() para cortar num caractere cuja posição você não sabe de antemão, como o @ de um endereço de e-mail:
Verifique se o strpos() não retornou false antes de usar o resultado: se o caractere não existe, false é tratado como 0 sem aviso, então substr('nobody', 0, $at) retorna "" e substr('nobody', $at + 1) retorna "obody".
Perguntas frequentes
Como pego os últimos caracteres de uma string no PHP?
Use um offset negativo: substr($s, -3) retorna os 3 últimos caracteres. Para texto que pode conter japonês ou outros caracteres multibyte, use mb_substr($s, -3).
Qual a diferença entre substr e mb_substr?
O substr() conta bytes e o mb_substr() conta caracteres. Em UTF-8, kana e kanji comuns ocupam 3 bytes cada, então substr('日本語', 0, 2) corta um caractere ao meio, enquanto mb_substr('日本語', 0, 2) retorna "日本".
O que o substr retorna se o início estiver depois do fim da string?
Uma string vazia. Desde o PHP 8.0, substr('abc', 5) retorna ""; o PHP 7 retornava false.
Como removo o último caractere de uma string no PHP?
substr($s, 0, -1) retorna tudo menos o último byte. Use mb_substr($s, 0, -1) para texto multibyte, ou rtrim($s, ',') se você só quer remover um caractere final específico.
Como conto quantas vezes uma substring aparece no PHP?
substr_count($haystack, $needle): substr_count('banana', 'an') retorna 2. Ele diferencia maiúsculas e minúsculas e não conta correspondências sobrepostas.