substr en PHP : découper une chaîne de caractères

La fonction substr() en PHP est l’outil de base pour extraire une portion précise d’une chaîne de caractères dans vos scripts. Introduite dès PHP 4, elle constitue la fondation de toute manipulation de chaînes dans les langages modernes comme PHP. Que vous souhaitiez découper un segmenttronquer du texte ou isoler une tranche spécifique, substr() offre un contrôle total avec une syntaxe simple et efficace.

Signature complète et paramètres décryptés

La syntaxe officielle de substr() s’écrit ainsi avec tous ses paramètres :

substr(string $chaine, int $debut, ?int $longueur = null): string

Chaque paramètre a un rôle précis que les développeurs doivent bien spécifier :

  • $chaine (obligatoire) : La chaîne de caractères source entre guillemets à découper.
  • $debut (obligatoire) : Position de départ en entiers (0 = premier caractère, négatif = fin de la chaîne).
  • $longueur (optionnel) : Nombre de caractères à extraire (null = jusqu’à la fin).

La fonction retourne toujours une string ou une chaîne vide "" en cas d’échec.

Extraction simple : découpage de base expliqué

Pour extraire une portion basique d’une chaîne de caractèressubstr() excelle par sa simplicité. Imaginez que vous gérez des scripts de traitement de texte où vous devez isoler des segments précis pour l’affichage ou le stockage.

$texte = "Bonjour le monde";  
echo substr($texte, 8);      // "le monde" (dès la position 8)
echo substr($texte, 8, 2);   // "le" (position 8, 2 caractères)

Ces exemples montrent comment substr() localise instantanément une position et découpe la tranche demandée avec une précision chirurgicale.

Positions négatives : comptage depuis la fin de la chaîne

La véritable puissance de substr() réside dans les positions négatives qui permettent de localiser des éléments depuis la fin de la chaîne. Cette technique avancée est indispensable pour extraire des suffixesextensions de fichiers ou codes en fin d’URL.

$texte = "Bonjour le monde";

// Derniers caractères
echo substr($texte, -5);     // "monde" (5 derniers)
echo substr($texte, -7, 3);  // "mon" (3 caractères depuis -7)

Attention : les positions négatives + longueur positive peuvent sembler contre-intuitives. Depuis la position -7 (espace avant « monde »), prendre 3 caractères donne bien « mon ».

Cas limites : chaînes vides et hors limites gérés

substr() gère robustement les cas limites sans planter votre script. Cette fiabilité en fait un choix sûr pour les langages de production :

echo substr("abc", 5);       // "" (position après la fin)
echo substr("abc", 1, 0);    // "" (longueur nulle)
echo substr("", 0);          // "" (chaîne vide)
echo substr("abc", 1, 10);   // "bc" (s'arrête à la fin)

Cette tolérance aux erreurs est parfaite pour traiter des données utilisateur imprévisibles.

Cas d’usage professionnels concrets

1. Extraction de domaine email : isoler après un séparateur précis

Dans les applications web, vous devez souvent extraire le domaine d’une adresse email pour la valider ou l’afficher séparément. L’utilisateur saisit contact@mon-site.com, mais votre script a besoin uniquement de mon-site.com pour vérifier la légitimité du domaine. La combinaison substr() + strpos() est la technique standard :

$email_utilisateur = "contact@mon-site.com";
$position_arobase = strpos($email_utilisateur, '@');  // Trouve la position 7
$domaine_extrait = substr($email_utilisateur, $position_arobase + 1);
echo "Domaine de l'email : " . $domaine_extrait;  
// Résultat : "mon-site.com"

Cette approche est utilisée dans tous les systèmes de validation d’emails professionnels.

2. Tronquer les titres pour un affichage responsive

Sur un blog ou site e-commerce, les titres longs cassent souvent la mise en page responsive. Votre script doit limiter automatiquement la longueur tout en ajoutant des points de suspension pour indiquer la troncature. Cette manipulation de chaînes est quotidienne :

$titre_article = "Ceci est un très long titre d'article qui dépasse largement la limite habituelle";
$longueur_maximum = 30;
$titre_limite = substr($titre_article, 0, $longueur_maximum) . '...';
echo $titre_limite;  
// Résultat : "Ceci est un très long titre..."

Les moteurs de recherche adorent cette technique car elle améliore l’expérience utilisateur sur mobile.

3. Récupération de codes promo depuis des URLs dynamiques

Les URLs de promotion contiennent souvent un code unique en fin de chemin. Votre système de suivi marketing doit isoler ce code pour l’identifier et appliquer la réduction. substr() + strrpos() est la solution la plus efficace :

$url_promotionnelle = "https://mon-site.com/promo/PRINTEMPS2026";
$dernier_separateur = strrpos($url_promotionnelle, '/');  // Dernier slash
$code_promo = substr($url_promotionnelle, $dernier_separateur + 1);
echo "Code promotionnel détecté : " . $code_promo;  
// Résultat : "PRINTEMPS2026"

Ce pattern est universel pour tous les systèmes de tracking d’URL.

4. Extraction automatique des extensions de fichiers

Lors du traitement d’uploads, votre script doit identifier l’extension pour la valider (jpg, pdf, etc.). La localisation du dernier point suivi d’un découpage précis est la méthode standard :

$chemin_upload = "/uploads/documents/contrat-client.pdf";
$dernier_point = strrpos($chemin_upload, '.');  // Position du dernier "."
$extension_fichier = substr($chemin_upload, $dernier_point + 1);
echo "Extension détectée : " . strtoupper($extension_fichier);  
// Résultat : "PDF"

Cette technique protège contre les fichiers malveillants avec double extension.

Pièges critiques à éviter absolument

Piège 1 : Positions négatives + longueur mal comprises

Les développeurs débutants confondent souvent le comportement des positions négatives combinées à une longueur positive :

$texte = "abcdef";
echo substr($texte, 2, -1);  // "" ❌ (incohérent)

// ✅ Solutions claires
echo substr($texte, 1);      // "bcdef" (depuis position 1)
echo substr($texte, -4);     // "cdef" (4 derniers)

Piège 2 : Caractères multibytes UTF-8 cassés

La fonction substr() fonctionne en octets selon la logique ASCII, traitant chaque octet comme un caractère unique. Cependant, les caractères spéciaux Unicode (accents, émojis) occupent plusieurs octets (2, 3 ou 4). Si vous découpez au milieu d’un tel caractère, substr() produit un résultat corrompu illisible.

Prenons l’exemple concret d’une famille d’émojis qui représente 4 octets par caractère Unicode :

$emoji_famille = "👨‍👩‍👧";  // Chaque émoji = 4 octets
echo "Longueur en octets : " . strlen($emoji_famille) . "\n";  // 11 octets !
echo "substr() cassé : '" . substr($emoji_famille, 0, 1) . "'\n";  
// Résultat : "�" (caractère corrompu)

echo "mb_substr() correct : '" . mb_substr($emoji_famille, 0, 1, 'UTF-8') . "'\n";
// Résultat : "👨‍👩‍👧" (émoji complet)

Contexte professionnel : ce piège est particulièrement destructeur dans les applications internationales (noms clients asiatiques, descriptions produits avec émojis, réseaux sociaux). Un simple substr() sur du texte Unicode peut casser complètement l’affichage et dégrader l’expérience utilisateur.

Solution universelle : dans les scripts modernes, remplacez systématiquement substr() par mb_substr() quand vous traitez du contenu UTF-8 :

// Toujours sûr pour le web moderne
function tronquer_securise($texte, $longueur) {
    return mb_substr($texte, 0, $longueur, 'UTF-8') . '...';
}

Piège 3 : Longueur excédant la chaîne gérée intelligemment

Un piège fréquent survient quand les développeurs spécifient une longueur supérieure à la taille réelle de la chaîne de caractères. Beaucoup s’attendent à une erreur, mais substr() gère cela de manière intelligente en s’arrêtant simplement à la fin de la chaîne.

$texte_court = "abc";
echo "Texte original : '$texte_court'\n";

$demande_trop_long = substr($texte_court, 1, 10);
echo "Demande 10 caractères, résultat : '$demande_trop_long'\n";
// Résultat : "bc" (s'arrête à la fin, pas d'erreur !)

Contexte pratique : ce comportement sauve la vie dans les scripts de traitement de données utilisateur. Imaginez un formulaire où l’utilisateur peut saisir des titres de 10 à 100 caractères. Votre script de troncature doit fonctionner sans savoir la longueur exacte :

$titre_variable = $_POST['titre'] ?? "Court";  // Longueur inconnue
$longueur_securisee = 50;  // Limite d'affichage

$titre_affiche = substr($titre_variable, 0, $longueur_securisee) . '...';
echo $titre_affiche;  // Fonctionne toujours proprement

Avantage clé : pas d’erreur fatale, pas de try/catch nécessaire. Cette tolérance fait de substr() un choix sûr pour les langages de production.

Performance et limites techniques analysées

La fonction substr() est exceptionnellement rapide car implémentée nativement en C au cœur de l’interpréteur PHP. Sur des chaînes de caractères de longueur moyenne (< 10 000 caractères), elle exécute l’extraction en quelques microsecondes seulement. Cette performance native en fait l’outil incontournable pour les scripts de production à fort trafic.

Elle est également binary-safe, ce qui signifie qu’elle fonctionne parfaitement sur des données binaires (images, flux compressés) sans corruption. Cette fiabilité est cruciale pour les applications manipulant des fichiers ou des protocoles réseau.

Points forts techniques majeurs :

  • Vitesse extrême : < 1μs par appel sur chaînes typiques
  • Gestion automatique des cas limites (hors limites → chaîne vide "")
  • Binary-safe : compatible fichiers binaires et flux de données
  • Mémoire efficace : copie minimale des données

Limites critiques à connaître absolument :

  1. Encodage UTF-8 destructeur : substr() compte les octets, pas les caractères Unicode. Un émoji (4 octets) découpé au milieu devient illisible. Dans le web moderne où 90% du contenu est UTF-8, cette limitation est critique.
  2. Comportement contre-intuitif : Position négative + longueur positive produit des résultats surprenants. substr("abcdef", -3, 2) donne « de » car il commence 3 caractères avant la fin (« def ») puis prend 2 caractères.
  3. Chaînes très longues : Sur des textes > 1 Mo (articles longs, logs), mb_substr() est préférable pour sa gestion Unicode native et sa stabilité mémoire.

Recommandation professionnelle : utilisez substr() pour les chaînes ASCII courtes/pures. Pour tout contenu web moderne (accents, émojis, international), adoptez mb_substr() comme standard :

// Pattern moderne et sûr
function extraire_portion($texte, $debut, $longueur = null) {
    return mb_substr($texte, $debut, $longueur, 'UTF-8');
}

Alternatives selon vos besoins précis

Besoin spécifiqueFonction recommandéeContexte d’utilisation optimal
Encodage UTF-8mb_substr()Extraction sûre caractères spéciaux Unicode
Fin de chaînestrrpos() + substr()Localisation dernier séparateur + découpage
Plusieurs partiesexplode() + array_slice()Découpage avec séparateur puis tranche précise
Regex complexepreg_replace()Pattern expression régulière pour transformation avancée

retour à la liste des fonctions

Sources : php.net

Cours

Variables et types

Manipulation de chaînes

Tableaux

Fichiers et système

Sécurité, session et cookie