Mauvaise extension !

Eléphanteau du PHP | 28 Messages

28 sept. 2005, 09:10

J'ai le code suivant et je n'arrive pas à envoyer du .pdf ou .wmv
On me retourne "Mauvaise extension !"
remarque un fichier .odt passe bien

Code : Tout sélectionner

<?php /** * function formatFileName * @access public * @param string - nom de fichier à formater * @param int - longueur maximale autorisée pour le nom de fichier * @return string - nom de fichier formaté * @desc Tronque éventuellement le nom de fichier, le convertit en minuscules et y élimine les caractères potentiellement dangereux. */ function formatFileName($aFileName, $aMaxLength = 50) { $aFileName = strToLower(subStr($aFileName, 0, $aMaxLength)); $aFileName = ereg_replace('[^a-zA-Z0-9,._\+\()\-]', '_', $aFileName); return $aFileName; } // end of function formatFileName() /2 /* PARAMETRES DE CONFIGURATION DU SCRIPT */ // chemin d'accès au répertoire d'upload (vers où le fichier uploadé temporaire sera transféré) // ce répertoire doit EXISTER et être ACCESSIBLE EN ECRITURE !! $destination_dir = 'textes/'; // taille maximale en octets du fichier à uploader $file_max_size = 10000000000; // extensions de fichiers autorisées $authorized_extensions = array('jpg','gif','doc','xls','pdf','odt','ott','sxw','stw','wmv','mp3','ogg'); /* TRAITEMENT PRINCIPAL */ // vérifie l'existence du répertoire de destination if (!is_dir($destination_dir)) { echo 'Veuillez indiquer un r&eacute;pertoire destination correct !'; die(); } // vérifie que répertoire de destination a des droits en écriture if (!is_writeable($destination_dir)) { echo 'Veuillez spécifier des droits en écriture pour le r&eacute;pertoire destination !'; die(); } // réception du formulaire if (isSet($_POST['submitFile'])) { // vérifie qu'un fichier a bien été soumis if (isSet($_FILES) && is_array($_FILES)) { // pas d'erreur lors de l'upload if ($_FILES['aFile']['error'] == UPLOAD_ERR_OK) { // vérifie la taille en octets if ($_FILES['aFile']['size'] <= $file_max_size) { // vérifie l'extension du fichier recu // il est aussi possible (et sans doute mieux) de se baser sur $_FILES['aFile']['type'] // qui retourne le type MIME correspondant (par exemple: image/pjpeg) $lastPos = strRChr($_FILES['aFile']['name'], "."); if ($lastPos !== false && in_array(strToLower(subStr($lastPos, 1)), $authorized_extensions)) { // définit un nom de fichier destination unique à partir du nom du fichier original formaté $destination_file = time().formatFileName($_FILES['aFile']['name']); // déplace le fichier uploadé du répertoire temporaire // vers les répertoire/fichier destination spécifiés if (move_uploaded_file($_FILES['aFile']['tmp_name'], $destination_dir.DIRECTORY_SEPARATOR.$destination_file)) { echo 'Fichier valide et upload&eacute; correctement.'; } else { // error sur move_uploaded_file echo 'Le fichier n\'a pas &eacute;t&eacute; upload&eacute; correctement !'; } } else { // pas d'extension ou mauvaise extension echo 'Mauvaise extension !'; } } else { // Taille maximale dépassée echo 'Fichier trop volumineux !'; } } else { // Erreur lors de l'upload switch ($_FILES['aFile']['error']){ case UPLOAD_ERR_INI_SIZE: echo 'Le fichier upload&eacute; d&eacute;passe la valeur sp&eacute;cifi&eacute;e pour upload_max_filesize dans php.ini.'; break; case UPLOAD_ERR_FORM_SIZE: echo 'Le fichier upload&eacute; d&eacute;passe la valeur sp&eacute;cifi&eacute;e pour MAX_FILE_SIZE dans le formulaire d\'upload.'; break; case UPLOAD_ERR_PARTIAL: echo 'Le fichier n\'a &eacute;t&eacute que partiellement upload&eacute;.'; break; default: echo 'Aucun fichier n\'a &eacute;t&eacute upload&eacute;.'; } // switch } } else { // aucun fichier reçu echo 'Pas de fichier recu'; } } // fin de réception de formulaire ?>
Que faut-il modifier ?

d'avance merci.
Eric
Modifié en dernier par Isaric le 05 oct. 2005, 09:09, modifié 2 fois.

Mammouth du PHP | 19672 Messages

28 sept. 2005, 09:22

Salut,
tu fais une utilisation incomplète de strrchr : cette fonction te retourne un entier qui indique la dernière occurence d'un élément dans une chaine, mais pas la chaine elle même. Tu dois t'en servir pour avoir le point de départ qui te servira dans l'utilisation de substr() qui te permettra alors d'isoler l'extrait de chaîne qui dans ton cas correspondra à l'extention de fichier.

Mais comme tu l'as également noté dans tes commentaires de code, le test sur le type mime dans $_FILES['fichier']['type'] serait tout aussi valable et même peut-être plus simple. Il te suffirait de stocker les types mime autorisés et de faire une comparaison dessus en utilisant in_array comme tu le fais dans ton système actuel.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphanteau du PHP | 28 Messages

28 sept. 2005, 10:13

Cette programmation n'est pas de moi, je ne fais que de l'utiliser.

Tout ce que tu me dis est bien compliqué pour moi. As tu quelque chose de plus pratique à me proposer ?

déjà merci pour tes explications !

Mammouth du PHP | 19672 Messages

28 sept. 2005, 10:26

Peut-être bien : voici le code complet, regarde les lignes 30, 64 et 65, j'ai simplifié. La ligne 30, j'ai rajouté le point précédent l'extension et j'ai midifié la vérification aux lignes 64 et 65:
<?php
/**
 * function formatFileName
 * @access public
 * @param string - nom de fichier à formater
 * @param int - longueur maximale autorisée pour le nom de fichier
 * @return string - nom de fichier formaté
 * @desc Tronque éventuellement le nom de fichier, le convertit en minuscules et
 *           y élimine les caractères potentiellement dangereux.
 */         
function formatFileName($aFileName, $aMaxLength = 50)
{
    $aFileName = strToLower(subStr($aFileName, 0, $aMaxLength));
    $aFileName = ereg_replace('[^a-zA-Z0-9,._\+\()\-]', '_', $aFileName);
    return $aFileName;
} // end of function formatFileName() /2


/* PARAMETRES DE CONFIGURATION DU SCRIPT
*/

// chemin d'accès au répertoire d'upload (vers où le fichier uploadé temporaire sera transféré)
// ce répertoire doit EXISTER et être ACCESSIBLE EN ECRITURE !!
$destination_dir = 'textes/';

// taille maximale en octets du fichier à uploader
$file_max_size = 10000000000;

// extensions de fichiers autorisées
$authorized_extensions = array('.jpg','.gif','.doc','.xls','.pdf','.odt','.ott','.sxw','.stw','.wmv','.mp3','.ogg');

/* TRAITEMENT PRINCIPAL
*/

// vérifie l'existence du répertoire de destination
if (!is_dir($destination_dir))
{
    echo 'Veuillez indiquer un r&eacute;pertoire destination correct !';
    die();
}

// vérifie que répertoire de destination a des droits en écriture
if (!is_writeable($destination_dir))
{
    echo 'Veuillez spécifier des droits en écriture pour le r&eacute;pertoire destination !';
    die();
}

// réception du formulaire
if (isSet($_POST['submitFile']))
{
    // vérifie qu'un fichier a bien été soumis
    if (isSet($_FILES) && is_array($_FILES))
    {
        // pas d'erreur lors de l'upload
        if ($_FILES['aFile']['error'] == UPLOAD_ERR_OK)
        {
            // vérifie la taille en octets
            if ($_FILES['aFile']['size'] <= $file_max_size)
            {
                // vérifie l'extension du fichier recu
                // il est aussi possible (et sans doute mieux) de se baser sur $_FILES['aFile']['type']
                // qui retourne le type MIME correspondant (par exemple: image/jpeg)
                $extension = substr($_FILES['aFile']['name'], -4, 4);
                if (in_array(strToLower($extension), $authorized_extensions))
                {
                    // définit un nom de fichier destination unique à partir du nom du fichier original formaté
                    $destination_file = time().formatFileName($_FILES['aFile']['name']);
                    // déplace le fichier uploadé du répertoire temporaire
                    // vers les répertoire/fichier destination spécifiés
                    if (move_uploaded_file($_FILES['aFile']['tmp_name'], $destination_dir.DIRECTORY_SEPARATOR.$destination_file))
                    {
                        echo 'Fichier valide et upload&eacute; correctement.';
                    }
                    else
                    {
                        // error sur move_uploaded_file
                        echo 'Le fichier n\'a pas &eacute;t&eacute; upload&eacute; correctement !';
                    }
                }
                else
                {
                    // pas d'extension ou mauvaise extension
                    echo 'Mauvaise extension !';
                }
            }
            else
            {
                // Taille maximale dépassée
                echo 'Fichier trop volumineux !';
            }
        }
        else
        {
            // Erreur lors de l'upload
            switch ($_FILES['aFile']['error'])
            {
                case UPLOAD_ERR_INI_SIZE:
                    echo 'Le fichier upload&eacute; d&eacute;passe la valeur sp&eacute;cifi&eacute;e
                       pour upload_max_filesize dans php.ini.';
                break;
                case UPLOAD_ERR_FORM_SIZE:
                    echo 'Le fichier upload&eacute; d&eacute;passe la valeur sp&eacute;cifi&eacute;e
                       pour MAX_FILE_SIZE dans le formulaire d\'upload.';
                break;
                case UPLOAD_ERR_PARTIAL:
                    echo 'Le fichier n\'a &eacute;t&eacute que partiellement upload&eacute;.';
                break;
                default:
                    echo 'Aucun fichier n\'a &eacute;t&eacute upload&eacute;.';
            } // switch
        }
    }
    else
    {
        // aucun fichier reçu
        echo 'Pas de fichier recu';
    }
} // fin de réception de formulaire
?>
Pour comprendre le fonctionnement, je t'ai préparé ces quelques lignes: teste-les en modifiant l'extension dans la variable $fichier:
<?php
$authorized_extensions = array('.jpg','.gif','.doc','.xls','.pdf','.odt','.ott','.sxw','.stw','.wmv','.mp3','.ogg');
$nom_fichier = "fichier.jpg";
$extension = substr($nom_fichier, -4, 4);
if (in_array(strToLower($extension), $authorized_extensions))
{
    echo("<p>Extension ". $extension ." autorisée</p>\n");
}
else
{
    echo("<p>Extension ". $extension ." interdite</p>\n");
}
?>
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphanteau du PHP | 28 Messages

28 sept. 2005, 12:14

Alors là, c'est en clair, merci. :D

Lorsque le fichier est téléchargé, il a un nombre devant
pour essa.pdf, j'obtiens :
1127902235essa.pdf
peut-on obtenir le même qu'au départ (essa.pdf) ?

Mammouth du PHP | 19672 Messages

28 sept. 2005, 12:15

:shock: D'où sortent ces chiffres ?
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphanteau du PHP | 28 Messages

28 sept. 2005, 12:33

Est-ce que cela peut-venir du fait que le site est chez FREE ?

Mammouth du PHP | 19672 Messages

28 sept. 2005, 13:00

Le nom temporaire du fichier est toujours bizarre, mais en principe, après un move_uploaded_file(), le nom d'origine reprend ses droits. Vérifie.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphanteau du PHP | 28 Messages

28 sept. 2005, 14:58

J'ai fait un nouveau téléchargement et
j'ai toujours des chiffres bizarres pour dance_e.gif
J'obtiens 1127912016dance_e.gif
Le nom temporaire du fichier est toujours bizarre, mais en principe, après un move_uploaded_file(), le nom d'origine reprend ses droits. Vérifie.
Pour moi, ce n'est plus un fichier temporaire, c'est le seul qui apparait dans le réprertoire.

Faut-il faire un autre essai ?

Mammouth du PHP | 19672 Messages

28 sept. 2005, 15:13

Tu dois pouvoir renommer le fichier: en principe, la valeur de $_FILES['champ_fichier']['name'] doit avoir le vrai nom, vérifie en faisant un echo dessus. Dans ce cas, une fois le fichier déplacé, renomme-le avec rename()
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Invité
Invité n'ayant pas de compte PHPfrance

28 sept. 2005, 19:11

Tu dois pouvoir renommer le fichier: en principe, la valeur de $_FILES['champ_fichier']['name'] doit avoir le vrai nom, vérifie en faisant un echo dessus. Dans ce cas, une fois le fichier déplacé, renomme-le avec rename()
Je rajoute

Code : Tout sélectionner

echo ($_FILES[$aFileName] );
à la fin des codes précédants

Mammouth du PHP | 19672 Messages

28 sept. 2005, 19:39

Attention, $_FILES est un tableau à deux dimensions et le second index est fixe au niveau du nommage : le premier index indique le nom correspondant à l'attribut "name" du champ input type file et le second t'indique la taille (['size'], le type (['type']), le nom (['name']) etc... donc vérifie $_FILES['nom_champ_file']['name']
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphanteau du PHP | 28 Messages

28 sept. 2005, 20:16

J'ai un peu de mal a tout suivre et je comprends juste un tout petit peu.
Je propose au hasard ou presque :

Code : Tout sélectionner

// définit un nom de fichier destination unique à partir du nom du fichier original formaté $destination_file = time().formatFileName($_FILES['aFile']['name']);
Un fichier unique ne m'intéresse pas !
Est-ce cette partie qui doit être modifié ? Est-ce le time() qui est en trop ?

Mammouth du PHP | 19672 Messages

28 sept. 2005, 21:04

J'avais pas vu ce détail: le voilà le paquet de chiffres en plus : time() retourne et ajoute l'heure au fichier.

Je dois dire que l'idée n'est pas idiote et ça éviterait le risque de voir un fichier qui aurait un nom déjà existant d'écraser un ancien toujours utilisé. Mais il faut gérer les liens correctement par la suite. Ceci dit, ce n'est pas impossible du tout :)
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphanteau du PHP | 28 Messages

29 sept. 2005, 07:24

J'ai donc fait :

Code : Tout sélectionner

// modif //$destination_file = time().formatFileName($_FILES['aFile']['name']); $destination_file = formatFileName($_FILES['aFile']['name']);
Cela marche ! :D

Merci beaucoup.

Eric