fseek()
La fonction fseek() de PHP permet de déplacer le pointeur de position dans un fichier ouvert vers n'importe quel octet.
Lorsque PHP lit ou écrit dans un fichier, il maintient un curseur interne — le pointeur de position dans le fichier — qui indique à quel endroit aura lieu la prochaine lecture ou écriture. Normalement, ce curseur avance automatiquement à chaque appel à fread() ou fwrite(). La fonction fseek() vous permet de le déplacer manuellement vers n'importe quelle position en octets, afin de reculer, d'avancer ou de relire une partie d'un fichier sans avoir à le fermer puis le rouvrir.
Ce chapitre couvre la syntaxe de fseek(), les trois modes whence, sa valeur de retour, ainsi que des cas pratiques tels que la lecture d'un enregistrement à un décalage connu et le déplacement du curseur au-delà de la fin d'un fichier.
Syntaxe
fseek(resource $stream, int $offset, int $whence = SEEK_SET): int| Paramètre | Description |
|---|---|
$stream | Un pointeur de fichier retourné par fopen(). |
$offset | Le nombre d'octets à déplacer. Peut être négatif avec SEEK_CUR et SEEK_END. |
$whence | Le point de référence à partir duquel le décalage est mesuré. Par défaut SEEK_SET. |
fseek() retourne 0 en cas de succès et -1 en cas d'échec. Elle ne retourne pas la nouvelle position — utilisez ftell() pour cela.
Les trois modes whence
La constante $whence détermine à partir de quel endroit le décalage est compté :
| Constante | Position résultante |
|---|---|
SEEK_SET | offset octets depuis le début du fichier (valeur par défaut). |
SEEK_CUR | offset octets depuis la position actuelle. |
SEEK_END | offset octets depuis la fin du fichier. Utilisez un décalage négatif pour reculer. |
<?php
fseek($file, 10); // 10 bytes from the start (SEEK_SET is implied)
fseek($file, 5, SEEK_CUR); // 5 bytes forward from where we are now
fseek($file, -4, SEEK_END); // 4 bytes before the end of the fileUn exemple concret
Créons un fichier, puis déplaçons-nous à l'octet 6 et lisons à partir de là. Comme nous écrivons et lisons dans le même script, l'exemple est entièrement autonome :
<?php
$filename = 'demo.txt';
// Create a file with known contents.
file_put_contents($filename, 'Hello, World!');
$file = fopen($filename, 'r');
fseek($file, 7, SEEK_SET); // move the cursor to byte 7
$data = fread($file, 5); // read 5 bytes: W, o, r, l, d
echo $data; // World
fclose($file);La chaîne 'Hello, World!' est stockée sous forme d'octets H(0) e(1) l(2) l(3) o(4) ,(5) (6) W(7) o(8) r(9) l(10) d(11) !(12). Se déplacer à l'octet 7 pointe sur le W, et lire 5 octets affiche World.
Toujours vérifier la valeur de retour
Puisque fseek() retourne 0 en cas de succès et -1 en cas d'échec, comparez-la explicitement. Un test de véracité approximatif est incorrect ici — 0 est falsy :
<?php
$file = fopen('demo.txt', 'r');
if (fseek($file, 7) === -1) {
echo "Seek failed";
} else {
echo "Seek succeeded"; // Seek succeeded
}
fclose($file);Points d'attention
- Tous les flux ne sont pas cherchables. Les pipes, les sockets réseau et le flux
php://stdinne supportent pas le déplacement du curseur ;fseek()retourne-1sur ces flux. - Le déplacement au-delà de la fin est autorisé. Avec un fichier ouvert en écriture, vous pouvez appeler
fseek()au-delà de la fin actuelle puis écrire — l'espace intermédiaire est rempli d'octets\0(null), créant une région creuse. - Prudence avec
SEEK_CURen mode ajout. Les fichiers ouverts avec le mode'a'écrivent toujours à la fin quel que soit le curseur ;fseek()n'affecte que les lectures dans ce mode. fseek()efface l'indicateur de fin de fichier, ce qui permet de relire des données déjà dépassées sans rouvrir le fichier.
Fonctions associées
ftell()— indique la position actuelle du curseur (le complément defseek()).rewind()— raccourci pourfseek($file, 0).fread()/fwrite()— lire ou écrire à partir de la position du curseur.fopen()/fclose()— ouvrir et fermer le flux.
Consultez le chapitre Gestion des fichiers PHP pour une vue d'ensemble.
Conclusion
fseek() offre un accès aléatoire dans un fichier : déplacez le curseur avec un $offset mesuré depuis SEEK_SET, SEEK_CUR ou SEEK_END, puis lisez ou écrivez depuis le nouvel emplacement. N'oubliez pas de vérifier la valeur de retour -1, utilisez ftell() pour connaître votre position exacte, et gardez à l'esprit que tous les flux ne supportent pas le déplacement du curseur.