pb upload (changement : caractère spéciaux et UTF-8)

ViPHP
AB
ViPHP | 5818 Messages

01 sept. 2011, 04:25

Le tuto c'est pour comprendre. Après tu pourrais utiliser la classe donnée en lien en fin de message puisque c'est la suite optimisée avec plus de fonctions disponibles (tu pourrais par exemple, par la même occasion, proposer le téléchargement d'une vignette d'illustration avec si besoin redimensionnement automatique avec cette même classe...).

Je te donne un exemple complet fonctionnel avec deux champs (le fichier et sa catégorie) :
<?php
// Chargement de la classe
require('Classe_upload.php');

$repertoire_destination = 'Test';

//Déclaration de la classe
$up = new Telechargement($repertoire_destination,'form1','song','controle_form');

//Extensions autorisées (sans les .)
$extensions = array("mp3", "mp4","ogg");
$up->Set_Extensions_accepte ($extensions);

// Rennommage des fichiers (en mode incrémentiel) si déjà présents sur le serveur.
$up->Set_Renomme_fichier('incr');

// Téléchargement
$up->Upload();


// Enregistrement en bdd des valeurs récupérées par le post
if (isset($_POST['form1']))
	{
		// Récupération des valeurs du transfert de fichiers
		$transfert = $up->Get_Tab_upload();
		
		// Si un fichier a été transférer
		if (!empty ($transfert))
			 {
			 	// Récupération du non du fichier transféré
				$resultat = $transfert['resultat'];//tableau à trois dimensions (c.f. Doc de la class pour plus de détails)
		   
				foreach ($resultat as $num => $rep)
					{
						foreach ($rep as $key => $value)
								{                                                      
									$fichier =  $value['nom'];// Nom du fichier transféré
									$dossier =  $key; // Nom du dossier                       
								}    
					} 
				
				
				// Récupération de tes autres valeurs
				//...
				
				// Connexion à ta bdd
				//...
				
				//exemple de requête avec mysql (protéger les valerurs par mysql_real_escape_string) ou utiliser PDO
				$sql = "INSERT INTO chansons(fichier, description) VALUES('".$fichier."', '".$_POST['style']."')";
				
				// Ligne temporaire pour vérification
				echo $sql;exit;
				
				// exécution de la requête
				//...

			
				 // Rechargement de la page pour éviter un multi upload	
				 $up->Get_Reload_page();
			   } 
	}


// Récupération des messages d'information
$resultat = $up->Get_Tab_message();
?>
<form enctype = "multipart/form-data" action = "<?php echo htmlspecialchars($_SERVER['PHP_SELF']).'?controle_form=1' ?>" method = "post">
     
      <input type="hidden" name="MAX_FILE_SIZE" value="5242880" />

      <input type="file" name="song[]" /><br  />
	  
		<label for="style"> Style musical de la chanson : </label>
		<select name="style" id="style" >
				<option value="blues" > Blues </option>
				<option value="chanson_francaise" > Chanson Fran&ccedil;aise </option>
				<option value="classique" id="classique" > Classique </option>
				<option value="club" > Club </option>
		</select>
		<input type="submit" name = "form1" value="Envoyer le fichier">
</form>

<?php //affichage des résultats
if (!empty($resultat))
	{
		echo '<p>';
			foreach ($resultat as $num)
				{
					foreach ($num as $value)
					echo htmlspecialchars($value).'<br />';
				}
		echo '</p>';
	}
?>
Pour que ça fonctionne tu as juste à copier le code de la classe (situé vers la fin de ce lien) et à l'enregistrer dans un fichier que tu nommeras 'Classe_upload.php' (à mettre dans le même répertoire que ton script) puis à mettre le nom de ton dossier dans la variable $repertoire_destination (2 ème ligne du code ci-dessus).

Eléphant du PHP | 188 Messages

01 sept. 2011, 12:52

@Moogli :

var_dump($insert->execute); ne retourne rien.
try
						{
						$insert = $connexion->prepare('INSERT INTO chansons(titre, artiste, idartiste, dateenvoi, vues, note, description) VALUES(:titre, :idartiste, NOW(), :vues, :note, :description)');
						$insert->execute(array(
								'titre' => $titre,
								'artiste' => $artiste,
								'idartiste' => $idartiste,
								'vues' => $vues,
								'note' => $note,
								'description' => $description
								));
						}
						catch(Exception $e)
			{
			/* erreur connection */
			echo 'Une erreur est survenue !';
			echo 'Erreur : '.$e->getMessage().'<br />';
			echo 'N° : '.$e->getCode();
			die();
			}
ne retourne non plus aucune message d'erreur. L'upload est effectué mais rien dans la BDD.

Je ne comprends pas ta dernière phrase ...

@AB :

Le script de ton tuto est plus simple je trouve, et je n'ai pas besoin d'images ou d'options supplémentaires via ta classe ...

Eléphant du PHP | 188 Messages

04 sept. 2011, 00:45

J'ai rajouté des
echo 'test';
avant et après mon insertion dans la BDD, et aucun d'eux ne s'affiche. L'upload fonctionne toujours correctement, je retrouve tous mes fichiers dans mon dossiers que j'avait choisi. J'en ai conclu que j'ai mal placé mon script d'enregistrement en BDD ? Dans une mauvaise boucle et qui donc ne s'execute jamais ? J'utilise toujours le script du tuto d'AB (le script juste, pas la classe). Et j'ai placé mon code d'enregistrement BDD dans la boucle :
// Si chargement du fichier - avec le nom temporaire créé par le serveur - vers l'adresse de destination
         if(@move_uploaded_file($_FILES['userfile']['tmp_name'], $adresse_fichier))
                                                                                                                                                                            
                 {
                         // Nom du fichier final
                         $nom_fichier = basename($adresse_fichier);
        
                         // Préparation des messages de confirmation
                         $resultat1 = 'Le fichier "'.$localfile.'" a été téléchargé sur le serveur';
                         $resultat2 = 'Le fichier "'.$localfile.'" renommé "'.$nom_fichier.'" a été téléchargé sur le serveur';
                                                 
                         // Création du message de confirmation
                         $_SESSION['resultat_telecharg'] = $localfile === $nom_fichier ?  $resultat1 : $resultat2;
                 }
, après la "création du message de confirmation" et bien entendu avant le } fermant la boucle ...
Est ce que l'erreur vient de là, j'ai mal placé le code ? Sinon qu'elle est mon erreur ?

Merci :D

Eléphant du PHP | 188 Messages

07 sept. 2011, 16:24

J'ai modifié le code, j'ai placé maintenant le code d'enregistrement BDD (et en peu plus) après l'upload dans une boucle qui vérifie le texte d'upload avec une regex, voila le code :
	 //maintenant on va récupérer le message de confirmation créer, s'il est positif on effectue les actions post-upload sur BDD et XML
    if (isset($_POST['chargement'])) //si les infos sont postées
		{
	 if (preg_match("#sur le serveur$#", $_SESSION['resultat_telecharg'])) //si le résultat est positif
		{
		
		//enregistrement dans la BDD
		if (isset($_POST['description'])) //si la description est remplie
			{
			$description = $_POST['description'];
			}
		else   // si la description est vide
			{
			$description = ''; 
			}
		
		//on transfere les infos sur l'artiste
		$titre = $nom_fichier;
		$artiste = $pseudo;
		$idartiste = $_SESSION['id'];
		$vues = 0;
		$note = 0;
		//et on créer la nouvelle musique dans la BDD "musiques" avec les infos récupérées
		try
		{
		$insert = $connexion->prepare('INSERT INTO chansons(titre, artiste, id_artiste, date_envoi, vues, note, description) VALUES(:titre, :id_artiste, NOW(), :vues, :note, :description)');
		$insert->execute(array(
				'titre' => $titre,
				'artiste' => $artiste,
				'id_artiste' => $idartiste,
				'vues' => $vues,
				'note' => $note,
				'description' => $description
				));
		}
		catch(Exception $e)
			{
					/* erreur connection */
			echo 'Une erreur est survenue !';
			echo 'Erreur : '.$e->getMessage().'<br />';
			echo 'N° : '.$e->getCode();
			die();
			}
		//on met a jour le  fichier XML de l'artiste en ajoutant cette chanson a la fin
						$adresse_img = $_SESSION['avatar'];
							//on prepare d'abord le texte a ajouter
							$new_text = '
							<track>
								<location>'.$adresse_fichier.'</location>
								<creator>'.$pseudo.'</creator>
								<title>'.$nom_fichier.'</title>
								<annotation>'.$description.'</annotation>
								<image>'.$adresse_img.'</image>
							</track>
							 ';
							 //on récupère l'adresse du fichier XML de l'artiste
							 $adresse_fichier_xml = $_SESSION['xml'];
							 //puis on écrit dans le fichier
							 $fichier_xml = fopen($adresse_fichier_xml, 'a+');
							 fputs($fichier_xml, $new_text);
							 fclose($fichier_xml);
						
						$insert->closeCursor();
		//maintenant on va incrémenter de 1 le nombre de chanson du compositeur
						
						$nb_chanson = $_SESSION['nb_chanson'];
						$nb_chanson = $nb_chanson + 1;
						$id = $_SESSION['id'];
						$req = $connexion->prepare('UPDATE user SET nb_chanson = :nb_chanson WHERE id = :id');
						$req->execute(array(
										'nb_chanson' => $nb_chanson,
										'id' => $id
										));
	}
	}
et pourtant toujours aucune trace dans aucune des BDD ni du fichier XML d'ailleurs.
Je ne sais plus quoi faire, j'attend votre aide, merci :D

ViPHP
AB
ViPHP | 5818 Messages

08 sept. 2011, 02:14

A ta place j'essaierais de tester la requête dans une page séparée et ensuite quand ça fonctionne tu l'intègre.

Sinon bon, je t'ai donné plus haut un code prêt à l'emploi très simple à mettre en place, et qui fonctionne ... avec appel à une classe à la fois plus sécurisée et plus évolutive que le code du tuto. Qu'est-ce que ça peut faire que le code de la classe soit plus compliqué que le tuto puisque tu n'a pas à intervenir dessus ?

Autre exemple de facilité en utilisant cette classe, il te suffirait de rajouter une ligne pour proposer l'upload multiple (si l'envie t'en prenait un jour) alors qu'il faudrait presque tout refaire si tu utilise le code du tuto... (en plus elle est compatible avec les hébergements gratuits comme free alors que le code du tuto ne l'est pas encore).

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

08 sept. 2011, 16:49

Qu'est-ce que ça peut faire que le code de la classe soit plus compliqué que le tuto puisque tu n'a pas à intervenir dessus ?
De mon point de vue pouvoir comprendre et dans certaine mesure pouvoir modifier la classe :)
ce qui dans un but didactique n'est pas simple, le code du tuto permettant de comprendre le principe.

ceci dit l'utilisation de la classe facilite grandement l'exploitation du formulaire :)

en attente du résultat des validations du formulaire et de la requête séparément ^^


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 188 Messages

08 sept. 2011, 22:34

Oui voila Moogli a raison c'est pour ça que je préferais le tuto, mais bon on est jeune on s'adapte ! alors voila j'ai utilisé la classe, je n'ai pas encore testé il me manque juste l'adresse finale de destination du fichier ! Où est-elle stockée sur la page d'upload ? Je l'ai trouvée dans la classe mais je m'y connais pas trop en relation avec les classes donc je sais pas ... Merci ! :D

ViPHP
AB
ViPHP | 5818 Messages

08 sept. 2011, 22:55

Qu'est-ce que ça peut faire que le code de la classe soit plus compliqué que le tuto puisque tu n'a pas à intervenir dessus ?
De mon point de vue pouvoir comprendre et dans certaine mesure pouvoir modifier la classe :)
ce qui dans un but didactique n'est pas simple, le code du tuto permettant de comprendre le principe.
Oui oui, je parlais simplement de résoudre le pb facilement. Comme j'ai donné le code prêt à l'emploi, cela ne demande pas d'investissement temps d'utiliser la classe. Donc cela n'entame pas le temps nécessaire pour développer ses connaissances tout en ayant, en attendant d'en savoir plus, un code fonctionnel.

ViPHP
AB
ViPHP | 5818 Messages

09 sept. 2011, 21:30

Oui voila Moogli a raison c'est pour ça que je préferais le tuto, mais bon on est jeune on s'adapte ! alors voila j'ai utilisé la classe, je n'ai pas encore testé il me manque juste l'adresse finale de destination du fichier ! ... :D
Dans l'exemple que je t'ai donné ici, c'est la deuxième ligne. Il suffit donc de remplacer 'Test' par l'adresse de ton dossier. A savoir qu'il faut indiquer le chemin du dossier par rapport à la racine "www" du serveur. Si dans ton dossier "www" tu as plusieurs sites (inclus dans des dossiers) il faudra écrire :
$repertoire_destination = 'nom_du_dossier_du_site/nom_du_repertoire';

sinon simplement :
$repertoire_destination = 'nom_du_repertoire';

Voilà c'est tout ce que tu as à faire.

Notes :
- comme tableau des extensions autorisées j'ai mis array("mp3", "mp4","ogg"), à toi d'ajouter ou de supprimer des éléments de ce tableau.

Et encore une fois, à moins d'avoir des besoins spécifiques non prévus dans la classe, tu n'as pas besoin d'intervenir dans le code de la classe. Tu la mets dans un fichier puis tu l'oublies. Tout se paramètre de l'extérieur comme dans le code que je t'ai montré (les autres possibilités sont indiquées dans le mode d'emploi de la classe).

Eléphant du PHP | 188 Messages

09 sept. 2011, 22:52

Oui ok merci pour l'adresse, mais ce que je demandais c'était comment récupérer l'adresse finale du fichier une fois uploadée sur mon serveur, pour l'enregistrer en BDD ...

Merci :D

ViPHP
AB
ViPHP | 5818 Messages

09 sept. 2011, 23:47

Bah c'est bien pour ça que je t'ai fais l'exemple, car c'est le "moins facile à faire" (la structure de récupération avec deux foreach vient du fait qu'on peut faire de l'upload multiple avec plusieurs redimensionnements d'image par fichiers). Je croyais que tu aurais compris puisque je t'ai montré la requête avec :

$sql = "INSERT INTO chansons(fichier, description) VALUES('".$fichier."', '".$_POST['style']."')";

Dans mon exemple c'est donc la variable $fichier qui est le nom de fichier final et $dossier le nom du dossier.

Eléphant du PHP | 188 Messages

11 sept. 2011, 13:10

Merci, j'ai adapté donc l'enregsitrement BDD a mon code et maintenant il m'affiche donc cette "ligne temporaire pour vérification" la bonne requette sauf pour la date, avec
$sql = "INSERT INTO chansons(titre, artiste, id_artiste, date_envoi, vues, note, description, adresse_chanson) VALUES('".$fichier."', '".$artiste."', '".$id_artiste."', '".NOW()."', '".$vues."', '".$note."', '".$adresse_chanson."')";
il m'indique
( ! ) Fatal error: Call to undefined function NOW() in C:\wamp\www\Code\pages\uploadtest.php on line 171
Call Stack
# Time Memory Function Location
1 0.0014 408504 {main}( ) ..\uploadtest.php:0
Alors j'ai essayé :
$sql = "INSERT INTO chansons(titre, artiste, id_artiste, date_envoi, vues, note, description, adresse_chanson) VALUES('".$fichier."', '".$artiste."', '".$id_artiste."', NOW(), '".$vues."', '".$note."', '".$adresse_chanson."')";
et il m'affiche la requette mais dans les VALUES le NOW() reste tel quel ...
Je ne sais pas quoi essayer de plus pour ce now.

Voici le code d'enregistrement BDD que j'ai placé (par rapport a ton exemple, AB) entre "$uo->Upload();" et "$resultat = $up->Get_Tap_Message();"
// Enregistrement en bdd des valeurs récupérées par le post
if (isset($_POST['form1']))
         {
                 // Récupération des valeurs du transfert de fichiers
                 $transfert = $up->Get_Tab_upload();
                 
                 // Si un fichier a été transférer
                 if (!empty ($transfert))
                          {
                                 // Récupération du non du fichier transféré
                                 $resultat = $transfert['resultat'];//tableau à trois dimensions (c.f. Doc de la class pour plus de détails)
                    
                                 foreach ($resultat as $num => $rep)
                                         {
                                                 foreach ($rep as $key => $value)
                                                                 {                                                      
                                                                         $fichier =  $value['nom'];// Nom du fichier transféré
                                                                         $dossier =  $key; // Nom du dossier                       
                                                                 }    
                                         } 
                                 
                                 
                                 // Récupération de tes autres valeurs
                                //on regarde si la description est remplie
								if ((isset($_POST['description'])) AND (!empty($_POST['description'])))
									{
									$description = $_POST['description'];
									}
								else
									{
									$description = '';
									}
								if ((isset($_POST['style'])) AND (!empty($_POST['style'])))
									{
									$style = $_POST['style'];
									}
								else
									{
									$style = '';
									$_SESSION['info_style'] = 0;
									}
                                 
                                 // Connexion à ta bdd
                                // connexion BDD par PDO

								$PARAM_hote='localhost';      // le chemin vers le serveur
								$PARAM_port='3306';
								$PARAM_nom_bd='monsite';          // le nom de votre base de données
								$PARAM_utilisateur='root';    // nom d'utilisateur pour se connecter
								$PARAM_mot_passe='';          // mot de passe de l'utilisateur pour se connecter

									try
										{
										$connexion = new PDO('mysql:host='.$PARAM_hote.';port='.$PARAM_port.';dbvalue='.$PARAM_nom_bd, $PARAM_utilisateur, $PARAM_mot_passe);
										/* BDD connectee */
										}
 
									catch(Exception $e)
										{
										/* erreur connection */
										echo 'Une erreur est survenue !';
										echo 'Erreur : '.$e->getMessage().'<br />';
										echo 'N° : '.$e->getCode();
										die();
										}

								//   /fin de la connexion BDD par PDO-->
                                 
                                 //exemple de requête avec mysql (protéger les valerurs par mysql_real_escape_string) ou utiliser PDO --> j'utilise PDO
								 $artiste = $_SESSION['pseudo'];
								 $id_artiste = $_SESSION['id'];
								 $vues = 0;
								 $note = 0;
								 $adresse_chanson = $dossier.'/'.$fichier; 
                                 $sql = "INSERT INTO chansons(titre, artiste, id_artiste, date_envoi, vues, note, description, adresse_chanson) VALUES('".$fichier."', '".$artiste."', '".$id_artiste."', NOW(), '".$vues."', '".$note."', '".$adresse_chanson."')";
                                 
                                 // Ligne temporaire pour vérification
                                 echo $sql;exit;
                                 
                                 // exécution de la requête
                                 $connexion->exec($sql);

                         
                                  // Rechargement de la page pour éviter un multi upload        
                                  $up->Get_Reload_page();
                            } 
         }
Merci :)

ViPHP
AB
ViPHP | 5818 Messages

11 sept. 2011, 16:44

Normal que le NOW() ne soit pas interprété quand tu fais un echo de ta requête puisque c'est une fonction mysql. Il faut regarder le résultat en bdd avec phpmyadmin.
Cela dit la requête de mon exemple était faite avec l'extension mysql. Pour l'exécuter il faudrait donc utiliser la commande adéquat soit mysql_query(). Mais comme tu utilises PDO autant faire ta requête suivant le modèle PDO.

Eléphant du PHP | 188 Messages

11 sept. 2011, 18:41

la page s'affiche correctement et l'upload est bien effucté, mais toujours aucune trace dans la BDD !
Je remet le code d'enregsitremment BDD :
// Enregistrement en bdd des valeurs récupérées par le post
if (isset($_POST['form1']))
         {
                 // Récupération des valeurs du transfert de fichiers
                 $transfert = $up->Get_Tab_upload();
                 
                 // Si un fichier a été transférer
                 if (!empty ($transfert))
                          {
                                 // Récupération du non du fichier transféré
                                 $resultat = $transfert['resultat'];//tableau à trois dimensions (c.f. Doc de la class pour plus de détails)
                    
                                 foreach ($resultat as $num => $rep)
                                         {
                                                 foreach ($rep as $key => $value)
                                                                 {                                                      
                                                                         $fichier =  $value['nom'];// Nom du fichier transféré
                                                                         $dossier =  $key; // Nom du dossier                       
                                                                 }    
                                         } 
                                 
                                 
                                 // Récupération de tes autres valeurs
                                //on regarde si la description est remplie
								if ((isset($_POST['description'])) AND (!empty($_POST['description'])))
									{
									$description = $_POST['description'];
									}
								else
									{
									$description = '';
									}
								if ((isset($_POST['style'])) AND (!empty($_POST['style'])))
									{
									$style = $_POST['style'];
									}
								else
									{
									$style = '';
									$_SESSION['info_style'] = 0;
									}
                                 
                                 // Connexion à ta bdd
                                // connexion BDD par PDO

								$PARAM_hote='localhost';      // le chemin vers le serveur
								$PARAM_port='3306';
								$PARAM_nom_bd='monsite';          // le nom de votre base de données
								$PARAM_utilisateur='root';    // nom d'utilisateur pour se connecter
								$PARAM_mot_passe='';          // mot de passe de l'utilisateur pour se connecter

									try
										{
										$connexion = new PDO('mysql:host='.$PARAM_hote.';port='.$PARAM_port.';dbvalue='.$PARAM_nom_bd, $PARAM_utilisateur, $PARAM_mot_passe);
										/* BDD connectee */
										}
 
									catch(Exception $e)
										{
										/* erreur connection */
										echo 'Une erreur est survenue !';
										echo 'Erreur : '.$e->getMessage().'<br />';
										echo 'N° : '.$e->getCode();
										die();
										}

								//   /fin de la connexion BDD par PDO-->
                                 
                                 //exemple de requête avec mysql (protéger les valerurs par mysql_real_escape_string) ou utiliser PDO --> j'utilise PDO
								 $artiste = $_SESSION['pseudo'];
								 $id_artiste = $_SESSION['id'];
								 $vues = 0;
								 $note = 0;
								 $adresse_chanson = $dossier.'/'.$fichier; 
                                 $sql = "INSERT INTO chansons(titre, artiste, id_artiste, date_envoi, vues, note, description, adresse_chanson) VALUES('".$fichier."', '".$artiste."', '".$id_artiste."', NOW(), '".$vues."', '".$note."', '".$adresse_chanson."')";
                                 
                                 // Ligne temporaire pour vérification
                                 echo $sql;
                                 
                                 // exécution de la requête
                                 $connexion->exec($sql);

                         
                                  // Rechargement de la page pour éviter un multi upload        
                                  $up->Get_Reload_page();
                            } 
         }
Merci de votre aide :D

ViPHP
AB
ViPHP | 5818 Messages

11 sept. 2011, 19:06

Heu ... tu lis un peu les messages ? Parce que j'ai l'impression que tu n'as tenu aucun compte de mon précédent message !

Une dernière fois si tu veux garder la requête telle que je te l'ai écrite, pour l'exécuter il faut utiliser mysql_query et employer mysql_real_escape_string pour protéger la requête :
$sql = "INSERT INTO chansons(titre, artiste, id_artiste, date_envoi, vues, note, description, adresse_chanson) VALUES('".mysql_real_escape_string($fichier)."', '".mysql_real_escape_string($artiste)."', '".mysql_real_escape_string($id_artiste)."', NOW(), '".mysql_real_escape_string($vues)."', '".mysql_real_escape_string($note)."', '".mysql_real_escape_string($adresse_chanson)."')";
                                 
// Ligne temporaire pour vérification (à effacer)
echo $sql;
                                 
// exécution de la requête
$query = mysql_query($sql);