Sur un fond bleu clair, un texte noir indique "< ? PHP ?", avec une icône d'éléphant géométrique bleue remplaçant le deuxième "P". Il s'agit d'un clin d'œil au langage de programmation PHP, souvent rencontré dans les problèmes d'erreur preg_match ou de plage invalide dans la classe de caractères.

PHP : solution pour l’erreur “preg_match(): Compilation failed: invalid range in character class”

Lors de la mise à jour d’un vieux site vers PHP 8.4, je suis tombé sur cette erreur dans les logs PHP :

preg_match(): Compilation failed: invalid range in character class at offset 20 session.php on line 278Code language: JavaScript (javascript)

Le message peut paraître obscur au premier abord. Pourtant, la cause est souvent toute simple : une expression régulière contient un tiret mal placé dans une classe de caractères.

Depuis PHP 7.3, PHP utilise PCRE2 pour gérer les expressions régulières. Cette migration a rendu la validation des expressions régulières plus stricte. Résultat : certains patterns qui fonctionnaient auparavant ne compilent plus correctement après une mise à jour de PHP. La migration vers PCRE2 a bien été introduite avec PHP 7.3, comme l’indiquent la RFC PHP et la documentation PHP sur l’installation de PCRE.

Pourquoi cette erreur apparaît-elle ?

Dans une expression régulière, les crochets permettent de définir une classe de caractères. Par exemple, [abc] signifie : “accepte a, b ou c”.

Le problème vient souvent du tiret -. Dans une classe de caractères, il peut indiquer une plage. Par exemple, [a-z] signifie : “toutes les lettres minuscules de a à z”.

Donc, quand PCRE2 rencontre une expression comme celle-ci, il peut interpréter le tiret comme le début d’une plage invalide :

preg_match('/[\w-.]+/', '');Code language: JavaScript (javascript)

Avant PHP 7.3, ce type de pattern pouvait passer sans bruit selon le contexte. Avec PCRE2, la validation devient plus stricte, et PHP renvoie alors une erreur du type Compilation failed: invalid range in character class. PHP.Watch donne exactement ce cas comme exemple de rupture possible après la migration vers PCRE2.

La solution : échapper le tiret dans la regex

Pour corriger l’erreur, il suffit généralement d’échapper le tiret avec un antislash :

preg_match('/[\w\-.]+/', '');Code language: JavaScript (javascript)

Ici, \- indique clairement à PCRE2 que le tiret doit être traité comme un caractère littéral, et non comme un opérateur de plage.

Autrement dit, cette classe de caractères accepte désormais les caractères alphanumériques, l’underscore, le tiret et le point, sans ambiguïté.

Autre solution : placer le tiret à la fin de la classe

Il existe aussi une autre correction valide : placer le tiret à la fin de la classe de caractères.

preg_match('/[\w.-]+/', '');Code language: JavaScript (javascript)

Dans cette position, le tiret ne peut plus être interprété comme une plage entre deux caractères. Personnellement, je préfère l’échapper explicitement, car l’intention reste plus lisible lors d’une relecture du code.

À quoi correspond “invalid range in character class” ?

Le message invalid range in character class signifie que PCRE2 a trouvé une plage invalide dans une classe de caractères.

Par exemple, dans une classe comme [\w-.], le moteur peut essayer de comprendre le segment \w-. comme une plage. Or cette plage n’a pas de sens. PCRE2 refuse donc de compiler l’expression régulière.

C’est pour cela que l’erreur mentionne une “compilation failed”. Le problème ne vient pas de la chaîne testée, mais du pattern lui-même. PHP n’arrive même pas à compiler la regex avant de l’exécuter.

Comment retrouver la regex responsable ?

Le message d’erreur indique généralement le fichier et la ligne concernés :

session.php on line 278Code language: CSS (css)

Il faut donc ouvrir ce fichier, puis chercher un appel à l’une de ces fonctions PHP :

  • preg_match()
  • preg_match_all()
  • preg_replace()
  • preg_split()
  • preg_grep()

Ensuite, vérifiez les classes de caractères entre crochets. Le cas le plus fréquent ressemble à ceci :

/[\w-.]+/

Il faut alors remplacer le pattern par une version explicite :

/[\w\-.]+/

Ou, si vous préférez placer le tiret à la fin :

/[\w.-]+/

Exemple concret avant / après

Voici le code qui peut provoquer l’erreur avec PHP 7.3 ou une version plus récente :

<?php

preg_match('/[\w-.]+/', 'exemple-test.php');Code language: HTML, XML (xml)

Et voici la version corrigée :

<?php

preg_match('/[\w\-.]+/', 'exemple-test.php');Code language: HTML, XML (xml)

Cette fois, le tiret est interprété comme un caractère normal. L’expression régulière compile donc correctement.

Faut-il modifier PHP ou le serveur ?

Non. Dans la grande majorité des cas, il ne faut pas rétrograder PHP ni modifier la configuration serveur. L’erreur vient du pattern regex. La bonne correction consiste donc à rendre l’expression régulière compatible avec PCRE2.

C’est une correction de code, pas une correction d’infrastructure.

À retenir

  • Depuis PHP 7.3, PHP utilise PCRE2 pour les expressions régulières.
  • PCRE2 valide les patterns plus strictement.
  • L’erreur invalid range in character class vient souvent d’un tiret mal placé dans une classe de caractères.
  • La solution la plus claire consiste à échapper le tiret avec \-.
  • Une autre solution consiste à placer le tiret au début ou à la fin de la classe.

Dans mon cas, la correction suivante a suffi :

preg_match('/[\w\-.]+/', '');Code language: JavaScript (javascript)

Une fois le tiret échappé, plus d’erreur à ce niveau.

Créer son propre serveur FTP avec Filezilla Server photo

Installer un serveur FTPS avec FileZilla Server

Créer son propre serveur FTPS avec FileZilla Server

FileZilla Server permet de transformer une machine Windows en serveur de transfert de fichiers.

Historiquement, on parlait simplement de “serveur FTP”. Aujourd’hui, il faut être plus précis : évitez le FTP en clair et configurez plutôt FTPS, c’est-à-dire FTP avec chiffrement TLS.

Le FTP classique transmet les identifiants et les données sans chiffrement. Sur un réseau privé, c’est déjà moyen. Sur Internet, c’est non. FileZilla Server reste utile, mais uniquement avec une configuration propre : comptes limités, répertoires précis, mode passif, ports contrôlés et certificat TLS.

Lire la suite

Un nuage orange avec un arc blanc stylisé se superpose à la mention "DDNS" en noir gras, représentant la redirection DynDNS (Dynamic DNS). Le design moderne présente le nuage en deux tons d'orange, symbolisant la facilité d'accès et de gestion en ligne.

Créer une adresse DDNS pour accéder à son serveur à distance

Une adresse DDNS permet d’associer un nom facile à retenir à une adresse IP qui change.

Au lieu de retenir une adresse comme 80.26.45.89, vous utilisez un nom du type monserveur.example.net, maison.no-ip.info ou radio.example.com.

C’est pratique pour accéder à un serveur personnel, un NAS, une caméra IP, une interface domotique, un serveur de jeu, une machine de test ou une webradio.

À l’époque, on parlait surtout de “redirection DynDNS”. Aujourd’hui, le terme le plus juste est DDNS, pour Dynamic DNS. Le principe reste le même, mais les services, les routeurs et les bonnes pratiques ont changé.

Lire la suite