strtok()
A função strtok() em PHP divide uma string em partes menores chamadas tokens, usando delimitadores definidos pelo usuário.
Introdução
A função strtok() em PHP divide uma string em partes menores chamadas tokens. Um token é um trecho de texto entre delimitadores — caracteres únicos como espaço, vírgula ou quebra de linha que marcam onde uma parte termina e a próxima começa.
O que torna strtok() incomum é que ela é stateful: ela lembra sua posição na string entre as chamadas. Você lê o primeiro token e continua chamando-a para obter o próximo token, e assim por diante, até que a string seja esgotada. Esta página aborda a sintaxe, como esse ponteiro interno funciona, as armadilhas comuns e quando você deve usar explode() em vez disso.
Sintaxe
strtok(string $string, string $delimiter): string|false
// continuation call:
strtok(string $delimiter): string|falseHá duas formas de chamá-la:
| Forma | Significado |
|---|---|
strtok($string, $delimiter) | Inicia a tokenização de $string, retorna o primeiro token. |
strtok($delimiter) | Continua a partir de onde a chamada anterior parou, retorna o próximo token. |
Pontos importantes sobre os parâmetros:
$delimiteré um conjunto de caracteres, não um separador de múltiplos caracteres." !?"significa "dividir em um espaço, um ponto de exclamação, ou um ponto de interrogação" — cada caractere é seu próprio delimitador. Ele não divide na string literal de três caracteres" !?".- O delimitador pode mudar entre chamadas, o que é o principal motivo para usar
strtok()em vez deexplode(). - A função retorna
falsequando não há mais tokens (ou se$delimiterestiver vazio), portanto pode ser usada como condição de loop.
No PHP 8.1+ a forma antiga de continuação
strtok(null, $delimiter)está descontinuada. Use a forma de argumento únicostrtok($delimiter)para continuar.
Exemplo básico: iterando pelos tokens
O padrão típico é uma chamada para iniciar, depois um loop while que continua obtendo tokens até que strtok() retorne false:
<?php
$string = "Hello World! How are you?";
$delimiter = " !?";
$token = strtok($string, $delimiter); // first token
while ($token !== false) {
echo $token . "\n";
$token = strtok($delimiter); // next token (single-arg form)
}Saída:
Hello
World
How
are
youUse uma comparação estrita !== false, não apenas while ($token). Um token "0" é falsy em PHP, então uma verificação solta pararia prematuramente em dados legítimos.
Delimitadores consecutivos são ignorados
Ao contrário de explode(), strtok() trata uma sequência de caracteres delimitadores como um único separador e nunca retorna tokens vazios:
<?php
$tok = strtok("a,,b", ",");
while ($tok !== false) {
echo "[$tok]\n";
$tok = strtok(",");
}Saída:
[a]
[b]A parte vazia entre as duas vírgulas é descartada silenciosamente. explode(",", "a,,b") retornaria ["a", "", "b"] em vez disso. Se preservar campos vazios for importante (CSV, por exemplo), não use strtok().
Alterando o delimitador durante a análise
Como o ponteiro interno é preservado, você pode trocar delimitadores entre chamadas — útil para analisar dados no estilo chave=valor:
<?php
$line = "name=John; age=30";
$key = strtok($line, "="); // split on "=" → "name"
$value = strtok(";"); // now split on ";" → " John"
echo trim($key) . "\n";
echo trim($value) . "\n";Saída:
name
JohnObtendo apenas a primeira linha
Um idioma rápido para ler apenas a primeira linha de uma string de múltiplas linhas, sem construir um array de todas as linhas:
<?php
$text = "first line\nsecond line\nthird line";
$firstLine = strtok($text, "\n");
echo $firstLine . "\n";Saída:
first linestrtok() vs explode()
Ambas dividem strings, mas se comportam de forma diferente:
strtok() | explode() | |
|---|---|---|
| Retorna | um token por chamada | um array inteiro de uma vez |
| Delimitador | um conjunto de caracteres únicos | uma string multi-caractere fixa |
| Campos vazios | ignorados | preservados |
| Estado | stateful (ponteiro interno) | stateless |
Para a maioria do código moderno, explode() é mais fácil de entender e funciona bem com funções de array. Use strtok() quando precisar de leitura lazy, token por token, ou quiser mudar o delimitador no meio do caminho. Para dados separados por vírgula com aspas, prefira str_getcsv().
Armadilhas comuns
- O ponteiro interno é global por string. Chamar outra função que usa
strtok()no meio do seu loop irá corromper sua posição. Termine uma tokenização antes de iniciar outra. - Não passe a string fonte novamente na continuação.
strtok($string, $delimiter)reinicia do início toda vez. A continuação deve usar a forma de argumento único. - Campos vazios desaparecem. Como mostrado acima,
strtok()não consegue informar que um campo estava em branco.
Conclusão
strtok() percorre uma string um token por vez, dividindo em qualquer caractere de um conjunto de delimitadores e mantendo um ponteiro interno entre as chamadas. Sua natureza stateful a torna ideal para análise lazy e para troca de delimitadores no meio do fluxo, enquanto seu hábito de descartar campos vazios a torna inadequada para dados de colunas fixas. Quando você simplesmente precisa de todas as partes como um array, explode() geralmente é a escolha mais clara; para dividir em partes de comprimento fixo, veja str_split().