PHP - Suppression de caractères UTF8 avec la fonction escapeshellarg, UTF8 et locales



La fonction de PHP escapeshellarg permet de protéger une chaine mais peut vous supprimer des caractères UTF8 si votre configuration système est insuffisante. J'ai rencontré l'erreur lors de l'utilisation de mysqldump via la fonction shell_exec:

shell_exec(mysqldump.' -u '.escapeshellarg(user).' -p'.escapeshellarg(pwd).' --host="'.host.'" --port="'.port.'" '.bdd.' > '.$path.$file);

Si la constante pwd contient des caractères UTF8 alors ils seront supprimés

define('pwd', '12677bonéééjour&é#');
Resultat:

La fonction shell_exec va executer la commande suivante si le système est pas configuré:

mysqldump -u user -p'12677bonjour&#' --host=127.0.0.1 --port=3308 dbb > /var/www);

On remarque que la fonction escapeshellarg supprime tous les caractères UFT8 dans notre exemple tous les "é".



Comment corriger le problème ?

La fonction PHP escapeshellarg dépend de du paramètre "locale".

Si comme moi, votre "locale" par défaut est "C", vous perdez tous les caractères UTF8.

Pour corriger le problème sans modifier votre configuration serveur il faut forcer la "locale" avec la fonction setlocale :

setlocale (LC_CTYPE, "en_US.UTF-8");

Note:

Selon votre système il est possible que la "locale" ne soit pas présente dans ce cas je vous conseille de tester une autre Ex. :

setlocale (LC_CTYPE, "fr_FR.UTF-8");
ou
setlocale (LC_CTYPE, "de_DE.utf8");
ou
...

Vous devrez tous les essayer jusqu'à ce que vous trouviez un paramètre régional correspondant à UTF8.

Une fois que vous avez correctement défini la "locale" la fonction shell_exec va executer la commande suivante en gardant les caractères UFT8:

mysqldump -u user -p'12677bonéééjour&é#' --host=127.0.0.1 --port=3308 dbb > /var/www);


Documentation officielle

http://php.net/manual/fr/function.escapeshellarg.php