You are currently viewing PHP substr : extraire une sous-chaîne facilement

PHP substr : extraire une sous-chaîne facilement

Dans cet article

  • La fonction php substr accepte trois paramètres : la chaîne source, la position de départ et la longueur optionnelle
  • Un offset négatif permet d’extraire depuis la fin de la chaîne, ce qui simplifie de nombreux traitements
  • Depuis PHP 8.0, substr renvoie une chaîne vide au lieu de false quand l’extraction échoue
  • Pour les chaînes multi-octets (UTF-8), il faut utiliser mb_substr afin d’éviter les caractères tronqués
  • Les fonctions complémentaires strpos, substr_count et substr_replace couvrent 90 % des manipulations courantes de sous-chaînes
  • En production, combiner substr avec mb_detect_encoding protège vos traitements contre les encodages imprévus

En formation BTS SIO, la manipulation de chaînes de caractères revient dans presque tous les projets. Que vous construisiez un slug d’URL, affichiez un aperçu tronqué ou validiez un format de fichier, php substr est la première fonction à maîtriser. Je l’utilise quotidiennement depuis plus de dix ans et je vais vous montrer comment l’exploiter efficacement, sans mauvaise surprise.

Syntaxe et paramètres de substr

La documentation officielle PHP de substr décrit la signature suivante :

substr(string $string, int $offset, ?int $length = null): string

Trois paramètres, dont un seul est optionnel. Voici le détail :

  • $string : la chaîne source dans laquelle vous souhaitez extraire un segment. C’est le texte de départ.
  • $offset : la position de départ de l’extraction. L’index commence à 0, comme dans la plupart des langages. Si vous passez un entier négatif, PHP compte depuis la fin de la chaîne.
  • $length (optionnel) : le nombre de caractères à extraire. Sans ce paramètre, substr renvoie tout le reste de la chaîne à partir de l’offset. Une valeur négative indique le nombre de caractères à ignorer depuis la fin.

Le type de retour est toujours string depuis PHP 8.0. Dans les versions antérieures, la fonction pouvait renvoyer false en cas d’échec, ce qui était source de bugs silencieux. Je vous recommande de toujours travailler avec PHP 8.0 ou supérieur pour bénéficier de ce comportement cohérent.

Les paramètres offset et length de substr contrôlent précisément l'extraction
Les paramètres offset et length de substr contrôlent précisément l’extraction

Exemples pratiques de php substr

Commençons par les cas d’usage les plus fréquents que je rencontre en cours et en production.

Extraire les premiers caractères

<?php
$titre = "Introduction à PHP substr";
$apercu = substr($titre, 0, 12);
echo $apercu; // Affiche : Introduction

L’offset 0 démarre au tout début. La longueur 12 capture exactement les douze premiers caractères. C’est le schéma classique pour générer un aperçu de texte dans une liste d’articles.

Extraire à partir d’une position donnée

<?php
$email = "[email protected]";
$domaine = substr($email, 6);
echo $domaine; // Affiche : web-sio.fr

Sans troisième paramètre, php substr renvoie tout le reste de la chaîne. Pratique, mais dans ce cas précis je vous conseille plutôt d’utiliser strpos combiné à substr pour trouver dynamiquement la position du @. Nous verrons cette technique plus loin.

Tronquer un texte avec des points de suspension

<?php
function tronquer(string $texte, int $max = 100): string {
    if (strlen($texte) <= $max) {
        return $texte;
    }
    return substr($texte, 0, $max) . '…';
}

echo tronquer("Un texte très long pour tester la troncature", 20);
// Affiche : Un texte très long p…

Cette fonction utilitaire revient dans quasiment tous mes projets. Notez que j’utilise le caractère Unicode plutôt que trois points, ce qui est plus propre typographiquement. Attention toutefois : cette approche peut couper un mot en plein milieu. Pour un résultat plus élégant, combinez avec strrpos afin de couper au dernier espace avant la limite.

Extraire une extension de fichier

<?php
$fichier = "rapport-2026.pdf";
$extension = substr($fichier, strrpos($fichier, '.') + 1);
echo $extension; // Affiche : pdf

Ici, strrpos trouve la position du dernier point, et substr extrait tout ce qui suit. C’est une combinaison que vous utiliserez souvent pour valider les types de fichiers uploadés. On retrouve une logique similaire dans le traitement conditionnel avec PHP switch pour aiguiller le traitement selon l’extension détectée.

Offset négatif et longueur négative

C’est l’une des fonctionnalités les plus puissantes de php substr, et pourtant elle reste sous-utilisée par beaucoup de développeurs.

Offset négatif : compter depuis la fin

<?php
$code = "CMD-2026-FR-1234";
$quatre_derniers = substr($code, -4);
echo $quatre_derniers; // Affiche : 1234

Avec un offset de -4, PHP démarre l’extraction quatre caractères avant la fin. C’est idéal pour récupérer un suffixe de longueur connue : code postal, identifiant court, derniers chiffres d’un numéro de série.

Longueur négative : ignorer la fin

<?php
$url = "https://web-sio.fr/php-substr/";
$sans_slash_final = substr($url, 0, -1);
echo $sans_slash_final; // Affiche : https://web-sio.fr/php-substr

Une longueur négative retire des caractères depuis la fin. C’est extrêmement pratique pour supprimer un slash final, un retour chariot ou tout suffixe indésirable.

Combiner les deux

<?php
$reference = "[REF-42-ABC]";
$contenu = substr($reference, 1, -1);
echo $contenu; // Affiche : REF-42-ABC

Offset 1 pour sauter le crochet ouvrant, longueur -1 pour ignorer le crochet fermant. En une seule ligne, vous extrayez le contenu entre délimiteurs. Ce genre de manipulation se retrouve fréquemment quand on travaille avec des PHP Enum pour parser des valeurs encapsulées.

Les offsets négatifs simplifient l'extraction depuis la fin d'une chaîne
Les offsets négatifs simplifient l’extraction depuis la fin d’une chaîne

substr et encodage UTF-8 : mb_substr

Voici le piège numéro un en production. La fonction substr travaille sur des octets, pas sur des caractères. Tant que votre texte ne contient que des caractères ASCII, il n’y a pas de différence. Mais dès qu’un accent, un emoji ou un caractère CJK apparaît, les résultats divergent.

<?php
$texte = "Développement web";
echo substr($texte, 0, 5);    // Affiche : Déve (ou un caractère tronqué selon l'encodage)
echo mb_substr($texte, 0, 5); // Affiche : Dével

Le caractère é occupe deux octets en UTF-8. Avec substr, un offset de 5 capture cinq octets, ce qui peut couper un caractère multi-octets en plein milieu et produire un symbole illisible. mb_substr respecte les frontières de caractères.

Quand utiliser mb_substr

  • Tout texte saisi par un utilisateur (noms, commentaires, descriptions)
  • Tout contenu provenant d’une base de données en utf8mb4
  • Tout affichage destiné au navigateur

Quand substr suffit

  • Manipulation de chaînes purement ASCII : identifiants techniques, hash, codes hexadécimaux
  • Protocoles binaires où vous travaillez volontairement en octets
  • Extraction d’en-têtes HTTP ou de tokens techniques

Mon conseil : si vous avez le moindre doute, utilisez mb_substr. La différence de performance est négligeable sur des volumes normaux. Pour mesurer l’impact, vous pourriez compter les occurrences de certains patterns avec la même logique que PHP array sizeof vs count : choisir la bonne fonction évite les surprises.

Fonctions complémentaires : strpos, substr_count, substr_replace

La fonction php substr ne travaille jamais seule. Elle s’inscrit dans un écosystème de fonctions de chaînes que je regroupe par famille.

strpos : trouver avant d’extraire

<?php
$email = "[email protected]";
$pos = strpos($email, '@');
if ($pos !== false) {
    $utilisateur = substr($email, 0, $pos);
    $domaine = substr($email, $pos + 1);
    echo "$utilisateur → $domaine"; // contact → web-sio.fr
}

Le couple strpos + substr est l’un des plus utilisés en PHP. Vous localisez d’abord le séparateur avec strpos, puis vous extrayez les segments avec substr. C’est une alternative légère à explode quand vous n’avez besoin que d’un ou deux segments.

substr_count : compter les occurrences

<?php
$code = "A-B-C-D-E";
$nb_tirets = substr_count($code, '-');
echo $nb_tirets; // Affiche : 4

Cette fonction compte le nombre d’apparitions d’une sous-chaîne dans une chaîne. Elle accepte aussi un offset et une longueur pour restreindre la zone de recherche. C’est utile pour valider un format avant de le découper.

substr_replace : remplacer un segment positionnel

<?php
$carte = "4242424242424242";
$masquee = substr_replace($carte, '****', 0, 12);
echo $masquee; // Affiche : ****4242

Là où str_replace cherche une valeur, substr_replace remplace par position. C’est la fonction idéale pour masquer des données sensibles comme des numéros de carte ou des tokens. La documentation officielle de substr_replace détaille également son comportement avec des tableaux en entrée.

Extraire une sous-chaîne après un caractère donné

<?php
$chemin = "/var/www/html/index.php";
$fichier = substr($chemin, strrpos($chemin, '/') + 1);
echo $fichier; // Affiche : index.php

Cette technique répond à la recherche fréquente « PHP substring after character ». En combinant strrpos (dernière occurrence) avec substr, vous isolez proprement le segment final d’un chemin, d’une URL ou d’un identifiant hiérarchique.

Évolutions PHP 8 et dépréciations

Plusieurs changements importants affectent php substr dans les versions récentes. Je les détaille ici pour éviter les erreurs de migration.

PHP 8.0 : fin du retour false

Avant PHP 8.0, substr('abc', 5) renvoyait false. Depuis PHP 8.0, la même instruction renvoie une chaîne vide. Ce changement semble anodin, mais il a cassé du code qui testait le retour avec === false. Vérifiez vos comparaisons strictes si vous migrez un projet ancien.

PHP 8.0 : str_contains, str_starts_with, str_ends_with

PHP 8.0 a introduit trois fonctions natives qui remplacent de nombreux usages de substr :

<?php
// Avant PHP 8.0
if (substr($url, 0, 8) === 'https://') { /* ... */ }

// Depuis PHP 8.0
if (str_starts_with($url, 'https://')) { /* ... */ }

Ces fonctions sont plus lisibles, plus performantes et moins sujettes aux erreurs de longueur. Je recommande de les adopter systématiquement. Cependant, substr reste indispensable pour l’extraction proprement dite : str_starts_with ne fait que tester, elle ne renvoie pas le segment.

La question de la dépréciation

Certains développeurs recherchent « php substr deprecated ». Soyons clairs : substr n’est pas dépréciée et ne le sera probablement jamais. C’est une fonction fondamentale du langage. Ce qui a changé, c’est le comportement du type de retour et l’apparition d’alternatives pour certains cas d’usage. Vous pouvez continuer à l’utiliser sereinement.

Adopter les bonnes pratiques substr évite les bugs d'encodage en production
Adopter les bonnes pratiques substr évite les bugs d’encodage en production

Cas réels et bonnes pratiques

Voici des situations concrètes tirées de mes projets et de ceux de mes étudiants en BTS SIO.

Générer un slug d’URL

<?php
function genererSlug(string $titre, int $maxLength = 60): string {
    $slug = strtolower(trim($titre));
    $slug = preg_replace('/[^a-z0-9]+/', '-', $slug);
    $slug = trim($slug, '-');
    if (strlen($slug) > $maxLength) {
        $slug = substr($slug, 0, $maxLength);
        $slug = rtrim($slug, '-');
    }
    return $slug;
}

echo genererSlug("PHP substr : extraire une sous-chaîne facilement");
// Affiche : php-substr-extraire-une-sous-cha-ne-facilement

Le substr ici garantit que le slug ne dépasse pas la longueur maximale autorisée par votre système d’URL. Le rtrim final évite un tiret orphelin en bout de chaîne.

Parser un identifiant structuré

<?php
$reference = "FR-2026-0042";
$pays     = substr($reference, 0, 2);    // FR
$annee    = substr($reference, 3, 4);    // 2026
$numero   = substr($reference, 8);       // 0042

Pour des formats fixes, substr est plus rapide et plus explicite qu’une regex ou un explode. Ce type de parsing positionnel est courant dans les systèmes de facturation, les codes EAN ou les identifiants internes. Quand la logique de branchement devient complexe selon la valeur extraite, je vous invite à consulter mon guide sur le PHP case statement.

Masquer des données personnelles

<?php
function masquerEmail(string $email): string {
    $pos = strpos($email, '@');
    if ($pos === false || $pos < 2) {
        return '***@***';
    }
    $debut = substr($email, 0, 2);
    $domaine = substr($email, $pos);
    return $debut . str_repeat('*', $pos - 2) . $domaine;
}

echo masquerEmail("[email protected]");
// Affiche : lu***********@web-sio.fr

Le respect du RGPD selon la CNIL impose de minimiser l'affichage des données personnelles. Cette fonction masque l'essentiel de l'adresse tout en laissant assez d'information pour que l'utilisateur reconnaisse son propre email.

Valider un préfixe de token

<?php
$token = "sk_live_abc123def456";
$prefixe = substr($token, 0, 7);

if ($prefixe === 'sk_live') {
    echo "Token de production détecté";
} elseif ($prefixe === 'sk_test') {
    echo "Token de test détecté";
}

Avec PHP 8.0+, préférez str_starts_with($token, 'sk_live'). Mais pour les projets encore en PHP 7.x, ce pattern avec substr reste la solution la plus fiable. On peut aussi envisager un PHP switch dans un switch pour gérer plusieurs niveaux de validation sur ces préfixes.

Erreurs fréquentes et pièges à éviter

Après des années de corrections de copies et de revues de code, voici les erreurs que je vois le plus souvent avec php substr.

Confondre offset et position humaine

L'index commence à 0, pas à 1. Si vous voulez le troisième caractère, l'offset est 2. C'est une source d'erreur classique pour les débutants, et même parfois pour des développeurs expérimentés qui passent fréquemment d'un langage à l'autre.

Oublier le cas de la chaîne vide

<?php
$resultat = substr("", 0, 5);
// PHP 8.0+ : renvoie ""
// PHP 7.x  : renvoie false

Testez toujours avec des chaînes vides. C'est une bonne habitude qui évite les erreurs en production quand un champ optionnel est vide.

Ignorer l'encodage multi-octets

Je l'ai déjà mentionné, mais j'insiste : sur du contenu utilisateur en français, utilisez mb_substr. Les accents, cédilles et ligatures (œ, æ) occupent plus d'un octet. Un substr naïf peut produire des caractères illisibles ou des erreurs d'affichage.

Ne pas vérifier la longueur avant extraction

<?php
// Dangereux si $code est trop court
$segment = substr($code, 10, 5);

// Plus sûr
if (strlen($code) >= 15) {
    $segment = substr($code, 10, 5);
}

Même si PHP 8 ne lève pas d'exception, extraire au-delà de la longueur produit une chaîne vide ou incomplète. Vérifiez la longueur en amont pour les formats stricts. De la même manière que l'on vérifie la taille d'un tableau avant d'y accéder, comme expliqué dans l'article sur COUNT DISTINCT SQL, vérifier la longueur d'une chaîne est un réflexe de robustesse.

Utiliser substr pour du HTML

Ne tronquez jamais du HTML brut avec substr. Vous risquez de couper une balise en plein milieu et de casser toute la mise en page. Utilisez plutôt strip_tags avant la troncature, ou une bibliothèque dédiée comme HTMLPurifier.

Tableau comparatif des fonctions d'extraction

Ce tableau synthétise les principales fonctions PHP liées à l'extraction et la manipulation de sous-chaînes.

Fonction Rôle principal Multi-octets Depuis PHP Cas d'usage typique
substr Extraire par position Non 4.0 Extraction de segments fixes (slug, code)
mb_substr Extraire par position (UTF-8) Oui 4.0.6 Troncature de texte utilisateur
substr_count Compter les occurrences Non 4.0 Validation de format
substr_replace Remplacer par position Non 4.0 Masquage de données sensibles
str_starts_with Tester un préfixe Oui 8.0 Remplacement de substr($s,0,n)==='x'
str_ends_with Tester un suffixe Oui 8.0 Vérification d'extension de fichier
str_contains Tester la présence Oui 8.0 Remplacement de strpos !== false
strtok Découper par token Non 4.0 Parsing séquentiel léger

Ce tableau montre clairement que php substr reste la fonction de référence pour l'extraction positionnelle, tandis que les fonctions PHP 8 couvrent les tests de présence. Pour un travail similaire côté base de données, la fonction ROUND en SQL illustre le même principe : choisir la bonne fonction native plutôt que de réinventer la roue.

À retenir

  • Utilisez mb_substr dès que le texte peut contenir des accents ou caractères spéciaux
  • Combinez strpos + substr pour extraire dynamiquement autour d'un séparateur
  • Adoptez str_starts_with et str_ends_with (PHP 8+) pour les tests de préfixe et suffixe
  • Vérifiez toujours la longueur de la chaîne avant une extraction positionnelle sur un format strict
  • Ne tronquez jamais du HTML brut avec substr : utilisez strip_tags avant

Questions fréquentes


Quelle est la différence entre substr et mb_substr en PHP ?

La fonction substr travaille sur les octets tandis que mb_substr travaille sur les caractères. Pour du texte en UTF-8 contenant des accents, des emojis ou des caractères spéciaux, mb_substr garantit de ne pas couper un caractère multi-octets en plein milieu. En pratique, utilisez mb_substr pour tout contenu destiné à l'affichage utilisateur et réservez substr aux chaînes purement ASCII comme les identifiants techniques ou les hash.


Est-ce que php substr est dépréciée ?

Non, substr n'est pas dépréciée et ne le sera probablement jamais. C'est une fonction fondamentale du cœur de PHP. Ce qui a changé avec PHP 8.0, c'est son type de retour : elle renvoie désormais une chaîne vide au lieu de false quand l'extraction échoue. Par ailleurs, PHP 8.0 a introduit str_starts_with, str_ends_with et str_contains qui remplacent certains usages de substr pour les tests de présence, mais pas pour l'extraction.


Comment extraire une sous-chaîne après un caractère en PHP ?

Combinez strpos (ou strrpos pour la dernière occurrence) avec substr. Par exemple : $domaine = substr($email, strpos($email, '@') + 1); extrait tout ce qui suit le caractère @. Cette technique fonctionne avec n'importe quel délimiteur. Pensez à vérifier que strpos ne renvoie pas false avant d'appeler substr, sinon vous risquez un comportement inattendu si le caractère est absent.


Comment utiliser un offset négatif avec substr ?

Un offset négatif indique à PHP de compter depuis la fin de la chaîne. Par exemple, substr($chaine, -4) renvoie les quatre derniers caractères. Vous pouvez aussi combiner un offset positif avec une longueur négative : substr($chaine, 1, -1) supprime le premier et le dernier caractère, ce qui est pratique pour retirer des délimiteurs encadrants comme des crochets ou des guillemets.


Quelle fonction utiliser pour compter les occurrences d'une sous-chaîne en PHP ?

Utilisez substr_count. Sa syntaxe est substr_count($haystack, $needle) et elle renvoie le nombre d'occurrences de $needle dans $haystack. Elle accepte aussi des paramètres optionnels offset et length pour restreindre la zone de recherche. Pour les chaînes multi-octets, utilisez mb_substr_count. Cette fonction est souvent utilisée pour valider un format avant de le découper avec explode ou substr.


substr est-elle plus rapide que preg_match pour extraire une sous-chaîne ?

Oui, substr est significativement plus rapide que preg_match pour une extraction positionnelle simple. Les expressions régulières compilent un automate à chaque appel (sauf mise en cache), tandis que substr effectue un simple calcul de pointeurs sur la chaîne. Pour des extractions basées sur une position connue, substr est le meilleur choix. Réservez les regex aux patterns complexes avec des alternatives, des répétitions ou des captures multiples.


Lucie Moreau
Lucie Moreau

Formatrice IT indépendante depuis 2016, ancienne étudiante BTS SIO SLAM. 6 ans d'expérience en entreprise.

Lucie Moreau

Formatrice IT indépendante depuis 2016, ancienne étudiante BTS SIO SLAM. 6 ans d'expérience en entreprise.