2009-06-26 8 views
9

J'ai besoin d'assainir certaines données qui seront utilisées dans les noms de fichiers. Certaines données contiennent des espaces et des caractères d'esperluette. Existe-t-il une fonction permettant d'échapper ou de désinfecter des données pouvant être utilisées dans un nom de fichier (ou un chemin)? Je ne pouvais pas en trouver un dans la section 'Filesystem Function' du manuel PHP. Donc, en supposant que je doive écrire ma propre fonction, quels caractères dois-je échapper (ou changer)?Quels caractères dois-je échapper/désinfecter pour les noms de fichiers?

Répondre

5

Si vous avez la possibilité de stocker le nom d'origine dans une base de données, je créerais simplement un fichier avec un hash aléatoire (mt_rand()/md5/sha1). L'avantage serait que vous ne comptez pas sur le système d'exploitation sous-jacent (caractères/longueur de chemin), la valeur ou la longueur de l'entrée de l'utilisateur et en outre il est vraiment difficile de deviner/forger un nom de fichier. Peut-être même un encodage en base64 est une option.

10

Pour Windows:

/ \ : * ? " < > | 

Pour Unix, rien sur le plan technique, mais dans la pratique la même liste que Windows serait raisonnable.

Il n'y a rien de mal avec les espaces ou les esperluettes tant que vous êtes prêt à utiliser des guillemets sur les lignes de commande lorsque vous manipulez les fichiers.

(BTW, je suis arrivé cette liste en essayant de renommer un fichier sous Windows pour quelque chose, y compris deux points, et la copie du message d'erreur.)

2

Lorsque désinfectante des chaînes pour les noms de fichiers, nous filtrons tous les caractères ci-dessous 0x20 , ainsi que <,>,:, ", /, \, |,? et *

2

Pour Windows, ajoutez" & "à la liste si vous ne souhaitez pas d'effets secondaires. C'est le caractère qui dit "le caractère suivant est mon raccourci clavier" dans certains affichages de données. (Le plus commun dans Windows ancien, mais saute encore ici et là.) Ainsi au lieu de "M & M" vous verriez "M _M "... le personnage suivant le esperluette (un espace) est un "raccourci clavier", et ainsi souligné.

3

Cela peut être une bonne idée de tout enlever en dehors de [a-z0-9 _ \ -.]. Il n'est pas nécessaire d'être aussi strict, mais il est confortable d'avoir une liste de répertoires sans aucune surprise. Si vous travaillez avec des jeux de caractères étranges, vous voulez peut-être convertir le codage ascii plat avant d'enlever les caractères offensants (ou vous pourriez finir avec tout supprimer) ...

au moins, c'est i faites-le :-)

4

Au lieu de filtrer les caractères pourquoi ne pas autoriser [a-z0-9- [email protected]#$%^()]? C'est certainement plus facile que d'essayer de deviner tous les personnages qui pourraient causer des problèmes.

Vos utilisateurs ne devraient pas avoir besoin d'un fichier avec d'autres caractères de toute façon, non?

+1

En effet, la liste blanche semble toujours la meilleure en matière de sécurité/fiabilité, etc. –

0

Mise en œuvre de @merkuro answer:

function getSafeFilesystemFileName() { 
    return (
     md5($id . '-' . $filename) . 
     '.' . pathinfo($filename, PATHINFO_EXTENSION) 
    ); 
} 

Où:

  • $id est l'ID d'enregistrement de la base de données
  • $filename est le nom de l'original upload (également stocké dans le dossier)

Un important thing: ajoute l'extension d'origine sur le fichier généré. Si jamais vous avez besoin de donner le fichier à un outil qui se soucie de l'extension, il sera beaucoup plus facile de l'avoir que d'avoir à créer un fichier temporaire avec l'extension.

Questions connexes