strtok()
La funzione strtok() in PHP suddivide una stringa in parti più piccole chiamate token, usando uno o più caratteri come delimitatori.
Introduzione
La funzione strtok() in PHP suddivide una stringa in parti più piccole chiamate token. Un token è un frammento di testo compreso tra i delimitatori — singoli caratteri come uno spazio, una virgola o un carattere di nuova riga che indicano dove termina un pezzo e ne inizia un altro.
Ciò che rende strtok() insolita è che è con stato: ricorda la posizione nella stringa tra una chiamata e l'altra. Si legge il primo token, poi si continua a chiamarla per ottenere il token successivo, e così via, finché la stringa non è esaurita. Questa pagina tratta la sintassi, il funzionamento del puntatore interno, le insidie più comuni e quando è preferibile usare explode().
Sintassi
strtok(string $string, string $delimiter): string|false
// continuation call:
strtok(string $delimiter): string|falseEsistono due modi per chiamarla:
| Forma | Significato |
|---|---|
strtok($string, $delimiter) | Avvia la tokenizzazione di $string, restituisce il primo token. |
strtok($delimiter) | Continua dal punto in cui si era fermata la chiamata precedente, restituisce il token successivo. |
Punti chiave sui parametri:
$delimiterè un insieme di caratteri, non un separatore multi-carattere." !?"significa "dividi su uno spazio, un punto esclamativo oppure un punto interrogativo" — ogni carattere è un delimitatore a sé. Non suddivide sulla stringa letterale di tre caratteri" !?".- Il delimitatore può cambiare tra una chiamata e l'altra, ed è il motivo principale per usare
strtok()al posto diexplode(). - La funzione restituisce
falsequando non ci sono più token (o se$delimiterè vuoto), quindi può essere usata come condizione di un ciclo.
In PHP 8.1+ la vecchia forma di continuazione
strtok(null, $delimiter)è deprecata. Usa la forma a singolo argomentostrtok($delimiter)per continuare.
Esempio di base: scorrere i token con un ciclo
Il pattern tipico prevede una chiamata iniziale, poi un ciclo while che continua a estrarre token finché strtok() non restituisce 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)
}Output:
Hello
World
How
are
youUsa un confronto rigoroso con !== false, non semplicemente while ($token). Un token uguale a "0" è falso in PHP, quindi un confronto generico si interromperebbe prematuramente su dati legittimi.
I delimitatori consecutivi vengono ignorati
A differenza di explode(), strtok() tratta una sequenza di caratteri delimitatori come un unico separatore e non restituisce mai token vuoti:
<?php
$tok = strtok("a,,b", ",");
while ($tok !== false) {
echo "[$tok]\n";
$tok = strtok(",");
}Output:
[a]
[b]Il pezzo vuoto tra le due virgole viene silenziosamente scartato. explode(",", "a,,b") restituirebbe invece ["a", "", "b"]. Se preservare i campi vuoti è importante (ad esempio per il CSV), non usare strtok().
Cambiare il delimitatore durante il parsing
Poiché il puntatore interno viene conservato, è possibile cambiare delimitatore tra una chiamata e l'altra — utile per analizzare dati in stile chiave=valore:
<?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";Output:
name
JohnOttenere solo la prima riga
Un idioma rapido per leggere solo la prima riga di una stringa su più righe, senza costruire un array di tutte le righe:
<?php
$text = "first line\nsecond line\nthird line";
$firstLine = strtok($text, "\n");
echo $firstLine . "\n";Output:
first linestrtok() vs explode()
Entrambe suddividono le stringhe, ma si comportano in modo diverso:
strtok() | explode() | |
|---|---|---|
| Restituisce | un token per chiamata | un intero array in una volta |
| Delimitatore | un insieme di singoli caratteri | una stringa multi-carattere fissa |
| Campi vuoti | ignorati | preservati |
| Stato | con stato (puntatore interno) | senza stato |
Per la maggior parte del codice moderno, explode() è più facile da comprendere e funziona bene con le funzioni per gli array. Opta per strtok() quando hai bisogno di una lettura pigra token per token o vuoi cambiare il delimitatore a metà elaborazione. Per dati separati da virgole con virgolettatura, preferisci str_getcsv().
Insidie comuni
- Il puntatore interno è globale per la stringa. Chiamare un'altra funzione che usa
strtok()nel mezzo del tuo ciclo corromperà la posizione. Termina una tokenizzazione prima di iniziarne un'altra. - Non passare nuovamente la stringa sorgente nella continuazione.
strtok($string, $delimiter)ricomincia dall'inizio ogni volta. La continuazione deve usare la forma a singolo argomento. - I campi vuoti scompaiono. Come mostrato sopra,
strtok()non può indicare che un campo era vuoto.
Conclusione
strtok() percorre una stringa un token alla volta, suddividendo su qualsiasi carattere dell'insieme dei delimitatori e mantenendo un puntatore interno tra le chiamate. La sua natura con stato la rende ideale per il parsing pigro e per cambiare delimitatori a metà flusso, mentre la sua tendenza a eliminare i campi vuoti la rende inadatta per dati a colonne fisse. Quando hai semplicemente bisogno di tutti i pezzi come array, explode() è solitamente la scelta più chiara; per suddividere in blocchi di lunghezza fissa, vedi str_split().