PHP : remplacer eregi(), ereg() et corriger l’erreur “function eregi() is deprecated”

Il vous est peut-être déjà arrivé de tomber sur ce message d’avertissement dans un vieux script PHP :

Function eregi() is deprecated.

Ou, sur une version plus récente de PHP, sur une erreur fatale encore moins sympathique :

Fatal error: Uncaught Error: Call to undefined function eregi()Langage du code : JavaScript (javascript)

Dans les deux cas, le problème vient du même endroit : les anciennes fonctions POSIX regex de PHP, comme ereg(), eregi(), ereg_replace(), eregi_replace(), split() et spliti(), ne doivent plus être utilisées.

Elles ont été dépréciées à partir de PHP 5.3, puis retirées de PHP 7. Le RFC PHP consacré au retrait des fonctionnalités obsolètes indique que l’extension ereg était dépréciée depuis PHP 5.3 et que l’extension PCRE devait être utilisée à la place. Voir le RFC PHP sur la suppression des fonctions obsolètes en PHP 7.

La solution consiste donc à remplacer ces anciennes fonctions par la famille preg_*, principalement preg_match(), preg_replace() et preg_split().

Pourquoi eregi() ne fonctionne plus ?

eregi() servait à faire une recherche par expression régulière sans tenir compte de la casse. Elle était basée sur l’ancien moteur POSIX regex de PHP.

Exemple historique :

$is_image = eregi( 'jpg|gif', $file_type );Langage du code : PHP (php)

Le problème, c’est que cette famille de fonctions est obsolète depuis longtemps. Sur PHP 5.3 à 5.6, elle générait des avertissements de dépréciation. Depuis PHP 7, elle n’existe plus. Sur PHP 8.x, un appel à eregi() provoque donc une erreur fatale.

En clair : si votre code contient encore eregi(), il appartient à une autre époque. Une époque sympathique, certes, mais une autre époque quand même.

Par quoi remplacer eregi() ?

Le remplacement direct de eregi() est preg_match() avec le modificateur i, qui rend la recherche insensible à la casse.

Ancien code :

$is_image = eregi( 'jpg|gif', $file_type );Langage du code : PHP (php)

Nouveau code :

$is_image = preg_match( '~jpg|gif~i', $file_type );Langage du code : PHP (php)

Le manuel PHP montre justement l’usage du modificateur i dans preg_match() pour effectuer une recherche insensible à la casse. Voir la documentation PHP de preg_match().

Le délimiteur ici est ~, mais vous pouvez aussi utiliser /, # ou un autre caractère supporté. L’important est de bien encadrer le motif avec un délimiteur, puis d’ajouter les modificateurs après le délimiteur final.

Distingo, le livret à 2%

Attention : convertir le motif ne suffit pas toujours

Les expressions régulières POSIX utilisées par ereg() et les expressions PCRE utilisées par preg_match() se ressemblent, mais elles ne sont pas identiques.

Dans les cas simples, la conversion est facile. Dans les cas complexes, il faut relire le motif, tester les captures, vérifier les échappements et contrôler le comportement sur des entrées réelles.

Par exemple, ce remplacement est trop approximatif si l’on veut détecter une vraie extension d’image :

$is_image = preg_match( '~jpg|gif~i', $file_type );Langage du code : PHP (php)

Ce motif matche aussi une chaîne comme not-a-gif-but-text. Pour vérifier une extension, mieux vaut être plus précis :

$is_image = (bool) preg_match( '~\.(?:jpe?g|gif|png|webp)$~i', $filename );Langage du code : PHP (php)

Ici, le motif vérifie une extension en fin de nom de fichier, accepte .jpg, .jpeg, .gif, .png et .webp, puis ignore la casse avec i.

Exemple moderne : vérifier une extension d’image

Voici une fonction PHP moderne, compatible PHP 8.3+, pour vérifier une extension d’image sans utiliser eregi().

<?php

declare(strict_types=1);

/**
 * Check whether a filename uses an allowed image extension.
 *
 * @param string $filename Filename or path to inspect.
 * @return bool True when the filename has an allowed image extension.
 */
function sky_is_supported_image_filename( string $filename ): bool {
	return 1 === preg_match( '~\.(?:jpe?g|gif|png|webp|avif)$~i', $filename );
}Langage du code : HTML, XML (xml)

Utilisation :

$filename = 'photo.JPG';

if ( sky_is_supported_image_filename( $filename ) ) {
	echo 'Image valide';
}Langage du code : PHP (php)

Pour du WordPress, on pourrait ensuite adapter la sortie avec esc_html(), mais la logique de détection reste identique.

Tableau de remplacement des anciennes fonctions

Voici les remplacements les plus courants :

Ancienne fonctionRemplacement moderneRemarque
ereg()preg_match()Recherche sensible à la casse
eregi()preg_match() avec iRecherche insensible à la casse
ereg_replace()preg_replace()Remplacement par expression régulière
eregi_replace()preg_replace() avec iRemplacement insensible à la casse
split()preg_split() ou explode()explode() suffit si le séparateur est fixe
spliti()preg_split() avec iDécoupe insensible à la casse
sql_regcase()À réécrireSouvent inutile avec i

Le RFC PHP indique aussi que PCRE offre un meilleur support Unicode et davantage de fonctionnalités que l’ancienne extension ereg. Voir le RFC PHP.

Remplacer ereg() par preg_match()

Ancien code avec ereg() :

if ( ereg( '^[0-9]+$', $value ) ) {
	echo 'Nombre valide';
}Langage du code : PHP (php)

Nouveau code avec preg_match() :

if ( 1 === preg_match( '~^[0-9]+$~', $value ) ) {
	echo 'Nombre valide';
}Langage du code : PHP (php)

J’aime comparer explicitement le retour à 1, car preg_match() retourne 1 si le motif correspond, 0 s’il ne correspond pas, et false en cas d’erreur. Cette distinction est utile dans du code robuste.

Distingo, le livret à 2%

Remplacer eregi() par preg_match() avec le modificateur i

Ancien code avec eregi() :

if ( eregi( 'firefox', $user_agent ) ) {
	echo 'Firefox détecté';
}Langage du code : PHP (php)

Nouveau code avec preg_match() :

if ( 1 === preg_match( '~firefox~i', $user_agent ) ) {
	echo 'Firefox détecté';
}Langage du code : PHP (php)

Le i placé après le délimiteur final rend la recherche insensible à la casse.

Remplacer ereg_replace() par preg_replace()

Ancien code :

$clean = ereg_replace( '[^a-zA-Z0-9_-]', '', $slug );Langage du code : PHP (php)

Nouveau code :

$clean = preg_replace( '~[^a-zA-Z0-9_-]~', '', $slug );Langage du code : PHP (php)

Comme preg_replace() peut retourner null en cas d’erreur, vous pouvez sécuriser le résultat :

$clean = preg_replace( '~[^a-zA-Z0-9_-]~', '', $slug );

if ( null === $clean ) {
	$clean = '';
}Langage du code : PHP (php)

Remplacer split() par preg_split() ou explode()

split() utilisait une expression régulière POSIX. Il faut le remplacer par preg_split() si vous avez besoin d’une expression régulière.

Ancien code :

$parts = split( '[,;]', $value );Langage du code : PHP (php)

Nouveau code :

$parts = preg_split( '~[,;]~', $value );

if ( false === $parts ) {
	$parts = array();
}Langage du code : PHP (php)

Mais si vous découpez simplement une chaîne avec un séparateur fixe, explode() est plus simple et plus rapide :

$parts = explode( ',', $value );Langage du code : PHP (php)

Bien choisir le délimiteur PCRE

Avec les fonctions preg_*, le motif doit être encadré par des délimiteurs.

Exemples valides :

preg_match( '/jpg|gif/i', $file_type );
preg_match( '~jpg|gif~i', $file_type );
preg_match( '#jpg|gif#i', $file_type );Langage du code : PHP (php)

Si le motif contient beaucoup de slashs, comme une URL ou un chemin, ~ ou # évite d’échapper chaque /.

Exemple plus lisible avec ~ :

preg_match( '~^https?://~i', $url );Langage du code : PHP (php)

Échapper une chaîne dynamique dans une regex

Si vous insérez une variable dans une expression régulière, utilisez preg_quote(). Sinon, un caractère spécial dans la variable peut casser le motif ou modifier son sens.

Mauvaise idée :

$needle = 'file.name';
preg_match( "~$needle~i", $haystack );Langage du code : PHP (php)

Ici, le point dans file.name signifie “n’importe quel caractère”. Ce n’est probablement pas ce que vous voulez.

Bonne approche :

$needle  = 'file.name';
$pattern = '~' . preg_quote( $needle, '~' ) . '~i';

preg_match( $pattern, $haystack );Langage du code : PHP (php)

Ce réflexe évite pas mal de bugs subtils. Les regex sont déjà assez sportives sans leur laisser des chausse-trappes gratuites.

Cas WordPress : ne pas utiliser une regex si WordPress a déjà une fonction

Dans WordPress, évitez de réinventer la validation quand une fonction existe déjà.

Pour vérifier un email, utilisez :

is_email( $email );Langage du code : PHP (php)

Pour nettoyer une clé :

$key = sanitize_key( $key );Langage du code : PHP (php)

Pour nettoyer un slug :

$slug = sanitize_title( $title );Langage du code : PHP (php)

Pour obtenir le type MIME d’un fichier uploadé, regardez plutôt du côté des fonctions WordPress dédiées comme wp_check_filetype() ou wp_check_filetype_and_ext(), selon le contexte.

Une regex est utile quand elle exprime vraiment une règle métier. Elle devient pénible quand elle remplace une API robuste déjà disponible.

Exemple WordPress moderne : vérifier un type de fichier

Pour vérifier une extension d’image dans WordPress, on peut utiliser wp_check_filetype() plutôt qu’une regex artisanale.

<?php
/**
 * Check whether a filename is a supported image according to WordPress MIME handling.
 *
 * @param string $filename File name or path.
 * @return bool True when the file extension maps to an image MIME type.
 */
function sky_is_supported_wp_image_file( string $filename ): bool {
	$filetype = wp_check_filetype( $filename );

	if ( empty( $filetype['type'] ) ) {
		return false;
	}

	return str_starts_with( $filetype['type'], 'image/' );
}Langage du code : HTML, XML (xml)

Cette approche colle mieux à WordPress, respecte sa gestion des types autorisés et évite une regex trop simpliste.

Détecter les anciennes fonctions dans un projet

Pour trouver les anciens appels dans un projet PHP :

grep -RInE '\b(ereg|eregi|ereg_replace|eregi_replace|split|spliti|sql_regcase)\s*\(' .Langage du code : JavaScript (javascript)

Avec ripgrep, plus rapide et plus agréable :

rg '\b(ereg|eregi|ereg_replace|eregi_replace|split|spliti|sql_regcase)\s*\('Langage du code : JavaScript (javascript)

Ensuite, traitez les occurrences une par une. Les remplacements automatiques globaux sont tentants, mais les différences entre POSIX regex et PCRE peuvent produire des effets de bord.

Tester les remplacements

Après migration, testez les cas attendus et les cas limites.

Exemple rapide en PHP pur :

<?php

declare(strict_types=1);

$tests = array(
	'photo.jpg'     => true,
	'photo.JPG'     => true,
	'photo.jpeg'    => true,
	'photo.gif'     => true,
	'photo.webp'    => true,
	'photo.txt'     => false,
	'photo.jpg.php' => false,
);

foreach ( $tests as $filename => $expected ) {
	$result = 1 === preg_match( '~\.(?:jpe?g|gif|png|webp|avif)$~i', $filename );

	if ( $result !== $expected ) {
		printf(
			"Test failed for %s: expected %s, got %s\n",
			$filename,
			$expected ? 'true' : 'false',
			$result ? 'true' : 'false'
		);
	}
}Langage du code : HTML, XML (xml)

Ce petit test évite de remplacer une erreur visible par un bug discret. Et les bugs discrets sont les pires : ils ont une excellente stratégie de camouflage.

Liste des fonctions dépréciées à l’époque de PHP 5.3

PHP 5.3 avait marqué un tournant en dépréciant beaucoup de vieilles fonctions. Parmi celles que l’on rencontrait souvent dans les anciens scripts :

  • call_user_method() : utiliser call_user_func() ;
  • call_user_method_array() : utiliser call_user_func_array() ;
  • ereg() : utiliser preg_match() ;
  • eregi() : utiliser preg_match() avec i ;
  • ereg_replace() : utiliser preg_replace() ;
  • eregi_replace() : utiliser preg_replace() avec i ;
  • split() : utiliser preg_split() ou explode() ;
  • spliti() : utiliser preg_split() avec i ;
  • session_register(), session_unregister(), session_is_registered() : utiliser $_SESSION ;
  • set_socket_blocking() : utiliser stream_set_blocking() ;
  • mysql_escape_string() : utiliser les APIs modernes, idéalement PDO ou MySQLi avec requêtes préparées ;
  • mysql_db_query() : ne plus utiliser l’ancienne extension mysql_*.

Cette liste est surtout utile pour identifier du code legacy. Sur PHP 8.x, beaucoup de ces fonctions ne sont plus seulement dépréciées : elles ont disparu.

Résumé rapide

Ancien code :

$is_image = eregi( 'jpg|gif', $file_type );Langage du code : PHP (php)

Nouveau code équivalent :

$is_image = preg_match( '~jpg|gif~i', $file_type );Langage du code : PHP (php)

Nouveau code plus précis pour une extension de fichier :

$is_image = 1 === preg_match( '~\.(?:jpe?g|gif|png|webp|avif)$~i', $filename );Langage du code : PHP (php)

Règle générale :

  • ereg() devient preg_match() ;
  • eregi() devient preg_match() avec le modificateur i ;
  • ereg_replace() devient preg_replace() ;
  • split() devient preg_split() ou explode().

Conclusion

L’avertissement Function eregi() is deprecated indiquait déjà, à l’époque de PHP 5.3, que le code utilisait une fonction obsolète.

Sur PHP 7 et PHP 8, le problème devient plus sérieux : eregi() n’existe plus, et le script plante avec une erreur fatale.

La correction consiste à migrer les anciennes expressions régulières POSIX vers PCRE, avec preg_match(), preg_replace() ou preg_split() selon le cas.

Pour les cas simples, le remplacement est rapide. Pour les vieux projets, mieux vaut chercher toutes les occurrences, convertir avec méthode, puis tester les entrées réelles.

Sources utiles

Demandez à l'IA son opinion
Gravatar for Matt Biscay

Je suis Matt Biscay, développeur WordPress & WooCommerce certifié chez Codeable, administrateur système et enseignant.

J’aide les entreprises à créer, optimiser et fiabiliser leurs sites WordPress avec une approche technique propre : performance, sécurité, maintenance, développement sur mesure et résolution de problèmes complexes.

Sur Skyminds, je partage des tutoriels WordPress, WooCommerce, Linux et administration système, avec des solutions testées sur des cas réels et pensées pour durer.

Découvrez mes services WordPress et WooCommerce.

2 pensées sur “PHP : remplacer eregi(), ereg() et corriger l’erreur “function eregi() is deprecated””

  1. Je vous conseille de plutôt remplacer

    $is_image = eregi( "jpg|gif",$file_type );

    par

    $is_image = preg_match( "~jpg|gif~i",$file_type );

    Pour éviter les problèmes avec les répertoires de fichiers ou URL dans votre ancien code.

    Pierre

    Répondre

Opinions