Soucis avec un formulaire contenant une partie upload

WRInaute passionné
Bonjour,

J'ai créé un simple formulaire contenant d'une part un simple textarea et de l'autre un formulaire d'upload d'images. Le truc bête est que quelque soit la méthode que j'utilise, je ne parvient jamais à garder les données du textarea. En gros, si je note un texte dans mon textarea puis que j'upload une image, mon textarea s'efface. Idem si j'efface une image, plus rien dans le textarea.

Donc, je cherche un moyen de garder le texte de mon champ (en faite mes champs) quelque soit la manœuvre que j'effectue avec l'upload .. vous me suivez ??

Des suggestions ou un tuto que je n'aurais pas encore lut ?

ps:J'ai testé "l'iframe loading".

Merci
 
WRInaute accro
A mon avis, c'est que tu ne recharges pas ta textarea avec la valeur qu'elle contient au moment où tu fais un submit du formulaire.
 
WRInaute accro
Tu as l'exemple de code qui foire ?
A tout hasard, quand tu re affiches le formulaire avec le textarea, tu fais bien un htmlentities() sur le contenu du _POST du textarea ?

<hs>J'ai déjà vu plusieurs fois ton code sur WRI, ce n'est guère propre, tu n'as jamais pensé utiliser un framework ?</hs>
 
WRInaute passionné
spout a dit:
<hs>J'ai déjà vu plusieurs fois ton code sur WRI, ce n'est guère propre, tu n'as jamais pensé utiliser un framework ?</hs>

Je ne sais même pas ce que c'est un framework ni à quoi ça sert et je ne suis qu'un simple bidouilleur ^^.

Soit un fichier nommé teste8.php pour l'occasion :
Code:
<?php
if(isset($_POST["envoyer"]))
{
	$titre = html_entity_decode(strip_tags($titre));
	$texte = html_entity_decode(strip_tags($texte));
	if($texte ==''){
		$erreur_texte='<div class="erreur"> Veuillez insérer le texte.</div>';
	}
	if($titre==''){
		$erreur_titre='<div class="erreur"> Veuillez insérer le titre.</div>';
	}
}
?>
<form name="listes" action="#" method="post">

<?php echo $erreur_titre;?>
<label>Titre :</label>
<input name="titre" size="50" maxlength="50" value="<?php
if (!empty($_POST["titre"])) {
echo stripcslashes(htmlspecialchars($_POST["titre"],ENT_QUOTES));
}?>" type="text">

<br/>

<?php echo $erreur_texte;?>
<label class="textarea">Texte:</label>
<textarea cols="50" rows="10" name="texte"><?php
if (!empty($_POST["texte"])) {
	echo stripcslashes(htmlspecialchars($_POST["texte"],ENT_QUOTES));
}?></textarea>
<br/>

<input name="envoyer" value="Valider" type="submit"/> 
</form> 


<form method="POST" action="#ancre_formulaire" enctype="multipart/form-data">
<span class="espace">Photos:
<a name="ancre_formulaire">Vous pouvez ajouter 3 photos.<br/>
<label for="photo">Photo :</label>
<input type="file" name="photo" />
<input type="submit" name="envoi" value="Envoyer la photo" />
</form>

<?php
$dossier_upload = "./images-toto";
//si le dossier n'existe pas, on le créé
if (!file_exists($dossier_upload)) {
	//on créé automatiquement un dossier d'upload d'image 
	mkdir ("$dossier_upload", 0777);
}
//on verifie l'extension des images et on arrange la mise en forme du nom
if(isset($_FILES['photo']))
{
	unset($erreur);
	$extensions_ok = array('png', 'gif', 'jpg', 'jpeg', 'JPG', 'bmp');
	$taille_max = 500000;
	//url des dossiers images
	$dest_dossier = './images-toto/';
	// vérifications
	if( !in_array( substr(strrchr($_FILES['photo']['name'], '.'), 1), $extensions_ok ) )
	{
		$erreur = '<a name="ancre_formulaire"><div class="erreur">Veuillez sélectionner un fichier de type png, gif, bmp ou jpg !</div>';  
	}
	elseif( file_exists($_FILES['photo']['tmp_name']) 
			and filesize($_FILES['photo']['tmp_name']) > $taille_max)
	{
		$erreur = '<a name="ancre_formulaire"><div class="erreur">Votre fichier doit faire moins de 2500Ko !</div>';
	}
	// copie du fichier
	if(!isset($erreur))
	{
		$dest_fichier = basename($_FILES['photo']['name']);
		// formatage nom fichier
		// enlever les accents
		$dest_fichier = strtr($dest_fichier, 'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ', 'AAAAAACEEEEIIIIOOOOOUUUUYaaaaaaceeeeiiiioooooouuuuyy');
		// remplacer les caracteres autres que lettres, chiffres et point par _
		$dest_fichier = preg_replace('/([^.a-z0-1]+)/i', '_', $dest_fichier);
		// copie du fichier
		move_uploaded_file($_FILES['photo']['tmp_name'], $dest_dossier . $dest_fichier);
	}
}
?>

<?php 
if(isset($erreur)){
	echo '<p>', $erreur ,'</p>';
}
?>

<?php
$adresse = "./images-toto/";

if(isset($_GET['nom'])) //Si $_GET['nom'] existe, on supprime le fichier...
{
	if ($Fichier != "." && $Fichier != "..") 
	{
		$nom=''.$adresse.$_GET['nom'].'';
		unlink($nom);
		echo 'Le fichier "'.$_GET['nom'].'" a été éffacé !<br/>';
		//header('location:teste8.php');
	}
} 

$dossier = opendir($adresse); //Ouverture du dossier. 
echo '<h2>Liste de vos photos</h2>';
while ($Fichier = readdir($dossier)) //Affichage...
{  
	if ($Fichier != "." && $Fichier != ".." && $Fichier != "index.php") 
	{ 
		echo '<img style="margin: 5px 10px 5px 5px; width: 90px; height: 90px;" alt="" src="'.$adresse.$Fichier.'">  <b><a href="teste8.php?nom='.$Fichier.'">Supprimer cette photo</a></b> ou <b><a href='.$adresse.$Fichier.' target="_blank">Visualiser cette photo</a></b><br/>'; 
	}
}
closedir($dossier); 
?>
 
WRInaute passionné
sur la récup de ton $_POST tu fais un :
Code:
echo '<pre>'; var_dump($_POST); var_dump($_GET); echo '</pre>';
t'auras déjà une idée.
Pour l'upload d'image, si tu as des soucis à ce niveau fait attention, c'est presque "insécurisable" comme script.
 
WRInaute accro
Tryan tu mériterai un botage de fesse en règle :wink: , ton code html simplifié :

Code:
<form name="listes" action="#" method="post">
<label>Titre :</label>
<input name="titre" size="50" maxlength="50" value="" type="text">
<textarea cols="50" rows="10" name="texte"></textarea>
<input name="envoyer" value="Valider" type="submit"/>
</form>


<form method="POST" action="#ancre_formulaire" enctype="multipart/form-data">
<input type="file" name="photo" />
<input type="submit" name="envoi" value="Envoyer la photo" />
</form>

Le truc bête est que quelque soit la méthode que j'utilise, je ne parvient jamais à garder les données du textarea. En gros, si je note un texte dans mon textarea puis que j'upload une image, mon textarea s'efface. Idem si j'efface une image, plus rien dans le textarea.

Tu n'espère tout de même pas récupérer le texte ET l'image en les envoyant depuis deux formulaires distincts quand même ?
 
WRInaute accro
spout a dit:
<hs>J'ai déjà vu plusieurs fois ton code sur WRI, ce n'est guère propre, tu n'as jamais pensé utiliser un framework ?</hs>

Ce n'est pas l'utilisation d'un FrameWork X ou Y qui changera qque chose a une difficulté de conceptualisation du code ou de sa transcription propre.

Au pire ça oblige a faire l'apprentissage d'une nouvelle API qui a encore une nouvelle spécification et syntaxe pour faire un truc qui est possible en natif php / html / javascript tout en rajoutant une couche de code sur un serveur (ou chez le client) qui n'en a pas besoins.

Perso quand je valide les Maitrise d'info, et qu'il me causent du FrameWork X ou Y, je leur demande de m'exposer ce que fait ce Framework et comment il ferait eux pour réaliser ce travail sans. C'est a mourir de rire comme beaucoup sont perdus pour trois bricoles de bases qu'un superbe framework bien lourd leur fourni.

Pense tu vraiment que rajouter des couches peut transformer qqun en codeur ?
 
WRInaute passionné
Tryan tu mériterai un botage de fesse en règle :wink: , ton code html simplifié :
Bhaaa @zeb, pourquoi ? Faut bien que je puisse ré afficher les données si erreurs en plus des erreurs ... il est ou le blême :?: :mrgreen:

Tu n'espère tout de même pas récupérer le texte ET l'image en les envoyant depuis deux formulaires distincts quand même ?

D'où ma question : comment qu'on fait pour tout récupérer/afficher sur une seule page ?
Je ne trouve rien sur le net concernant le sujet.

@Julia41 : je vais tester ton code pour voir ce que ça sort :)

Merci de vos réponses
 
WRInaute accro
1/ tu met toutes les données dans un unique formulaire avec un seul submit genre :

Code:
<form method="POST" action="" enctype="multipart/form-data">
 <input name="titre" size="50" maxlength="50" value="" type="text">
 <textarea cols="50" rows="10" name="texte"></textarea>
 <input type="file" name="photo" />
 <input type="submit" name="envoi" value="Envoyer" />
</form>

2/ dans ton traitement POST tu récupère donc toutes tes variables $_POST['qque_chose'] ET ton contenu image.
Code:
if(isset($_POST['envoi'])){...}

3/ tu fait le traitement dans cette condition après avoir "nettoyé" ce qu'il fallait dans tes variables (penser injection, fichier image vérolé etc ...)

4/ tu procède a un ré-affichage du formulaire avec le contenu POST nettoyé si jamais tu détecte qque chose de pas catholique nécessitant une intervention de l'utilisateur.
 
WRInaute passionné
Pour sécu tes images, pense à bien les recoder derrière avec gd2 ou autre joyeuserie de traitement d'image php sinon ça va aller vite. Mais si ton niveau en PHP n'est pas génial prends un truc tout fait récent.

Pour tes formulaires utilise les fonctions PHP filter_, ça fera déjà du bien.
 
WRInaute accro
bon puisque ça fait plusieurs fois que je te voie galérer sur les formulaires te donne ma façon de faire qui n'est pas la meilleure mais qui a le mérite de séparer ce qui peut l'être de façon claire :

soit 3 scripts (une bascule, un code d'affichage, et un code de traitement)

la bascule pour commencer :
formulaire.php
Code:
	if(isset($_POST['envoie'])){
		//traitement de la page en post
		//on vérifie le formulaire, et on fait éventuellement les traitements métiers
		include($_SERVER['DOCUMENT_ROOT']."/formulaire-traitement.php");		 
	}else{
		//traitement de la page en get
		//on fourni le formulaire
		include($_SERVER['DOCUMENT_ROOT']."/formulaire-affichage.php");
	}
Ce code est le point d'entré du formulaire, (un genre de bistable) il est destiné a aiguiller le traitement vers deux scripts distincts (pour des raisons de lisibilité)

ensuite le forulaire a proprement parler :
formulaire-affichage.php
Code:
    <form action="" method="post">
    <table>
    <tr>
     <td>Votre nom : </td><td><input name='nom' value="<? echo $_POST['nom']; ?>" type='text' size='30'/></td>
    </tr>
    <tr>
     <td>Votre prénom :</td><td><input name='prenom' value="<? echo $_POST['prenom']; ?>" type='text' size='30'/></td>
    </tr>
    <tr>
     <td></td><td><input type="submit" value="Ok..." name="envoie"/></td>
    </tr>
    </table>
    </form>
<? if($messpost!=''){ ?>
    <script language="JavaScript" type="text/javascript">
     <!--
    text = '<? echo $messpost; ?>';
    setTimeout("alert(text)",2000);
     //-->
    </script>
  
<? } ?>
note bien le "if($messpost!='')" il prend sa signification avec le script suivant.
ici surtout du code HTML c'est le côté présentation de ton formulaire.

troisième et dernière partie (la plus importante), le traitement du formulaire
formulaire-traitement.php
Code:
	// initialisation des variables (récupération et nettoyage)
	$form_nom = nettoyage($_POST['nom']);
	$form_prenom =  nettoyage($_POST['prenom']);
	$messpost = '';
	
	// vérification diverses lé a la nature des données attendues + composition de l'alerte utilisateur
	if($form_nom == ''){
		$messpost .= "Renseignez le champ nom. ";
	}
	
	if($form_prenom == ''){
		$messpost .= "Renseignez le champ prénom. ";
	}
		
	if($messpost!=''){
		// si un souci de saisie a été détecté par les conditions ci dessus je ré-affiche le formulaire
		// avec les données envoyées et j'aurais une alert javascript informant de ce qui ne va pas.
		include($_SERVER['DOCUMENT_ROOT']."/formulaire-affichage.php");
	}else{
		//cas tout est ok, on execute la fonction métier liée au formulaire
		(...)
		echo "<h1>Formulaire traité, merci</h1><br /><br />\n";
	}
	function nettoyage($in){ ( ... a toi de coder le nettoyage que tu souhaite ... ) ; return $out;}

Attention en cas de renvoie du formulaire, les données ré-affichées ne sont pas celles que tu as nettoyé ;-) te laisse voir si tu as besoins de ce genre de sécurité et la parade simple a cet exemple.

explication et déroulé :
Le visiteur arrive sur formulaire.php pour la première fois (GET puisque $_POST['envoie'] est indéfini) le bistable inclut donc le formulaire.
Le visiteur mamaille dans le formulaire et submit, on réentre donc dans formulaire.php mais cette fois ci avec $_POST['envoie'] qui est défini c'est donc formulaire-traitement.php qui est inclut ce coup ci.
Le script de traitement récupère les variables POST et fait le ménage (but de la fonction nettoyage())
Il procède ensuite a un contrôle des données (champs non vides, conforme a ce qui est demandé etc ... a toi de faire)
Chaque contrôle des données donne lieu a la concaténation d'un message explicatif dans la variable $messpost en cas de souci aux contrôles, et celle ci est préalablement initialisée avec une chaine vide ($messpost ='';)
Ensuite arrive un test :
* si $messpost n'est pas vide c'est qu'un contrôle n'est pas passé, on inclu alors le formulaire qui s'autocomplétera avec les valeurs saisies precedement et qui produira une alerte javascript avec le contenu de $messpost .
* si $messpost est vide (tout va bien on traite les données et on dit merci au gentil contributeur -> partie métier du formulaire)

fin de l'histoire.
 
WRInaute passionné
ça y est .. ça me re gonfle encore :D

Un formulaire de base blindé d'input, de textarea, de bouton radion, etc... + traitement, je m'en tire pas trop mal. Là, c'est la partie upload qui me saoule puisque dès que j'upload une image ou que j'en supprime une, mes champs se vide.

@zeb : L'upload doit permettre l'enregistrement de plusieurs images. Ton formulaire avec un seul bouton et si le formulaire ne retourne aucune erreur va m'envoyer les données directe en bd avec une seule et unique image. Regarde le code de mon poste (si pourrit soit il ^^) , il permet l'upload de plusieurs images.

Si c'était aussi simple, je ne demanderais pas de l'aide :wink:

Merci

Edit: j'ai pas fait gaffe à ton dernier poste zeb..
 
WRInaute accro
tryan a dit:
Là, c'est la partie upload qui me saoule puisque dès que j'upload une image ou que j'en supprime une, mes champs se vide.

Utilise un seul formulaire, ca sera bien plus simple pour faire ce dont tu as besoin. Tu peux tout a fait avoir un formulaire avec des champs libres et un champ d'upload. Tu n'as pas besoin de mettre en place un formulaire dedié uniquement pour le champ upload.

Il faut juste penser a bien mettre l'attribut enctype (cf les exemples donnés par zeb plus haut).
 
WRInaute passionné
Un exemple fonctionnel sous la main qui permet l'upload de plusieurs images sans vider les champs?

ça fait plus d'une semaine que je teste différentes choses mais je suis toujours enquiquiné quelque part :?
 
WRInaute accro
$_FILE est un tableau, au même titre que $_POST. Donc tu peux très bien avoir plusieurs champ d'upload dans le même formulaire. Il suffit juste de les nommer différemment.

Un bout de code de formulaire :

Code:
<form name="myform" id="myform" action="<?php echo $_SERVER['PHP_SELF']; ?>" enctype="multipart/form-data">
<input type="file" name="fichier1">
<input type="file" name="fichier2">
<input type="text" name="titre" id="titre" value="<?php if (isset($titre){echo $titre;} ?>">
<input type="submit" name="action_form" value="Valider" />
</form>

Et en haut de la page du formulaire (perso je poste toujours sur la page sur laquelle je me trouve) :

Code:
<?php
if (isset($_POST['action_form']))
{
       foreach ($_POST as $key => $value)
      {
            case 'titre':
                  $titre = $value;
            break;
            ....
      }
      foreach ($_FILES as $key => $value)
      {
            //ici tu passes en revue tes champs d'upload et tu effectues sur chacun d'eux les actions de sécurisations nécessaires
      }
}
?>

C'est un exemple vite fait, pas testé mais niveau algo ca devrait fonctionner. Je n'ai pas non plus déroulé tout le process (notamment pour le traitement des fichiers, tout dépend de ce que tu attends comme type de fichier)
Mais je suis d'avis qu'il ne serait pas intéressant que tu te formes plutôt que de bidouiller.
 
WRInaute passionné
UsagiYojimbo a dit:
Mais je suis d'avis qu'il ne serait pas intéressant que tu te formes plutôt que de bidouiller.

Tu peux développer un peut? Tu pense qu'il est préférable que je continue à bidouiller ou tu t'est planter dans ta formulation?

Ceci dit, merci pour le bout de code, je vais tester cette nouvelle approche :) .

En passent et sur le principe d'un double formulaire, pourquoi un contrôle du champ $_FILES['photo']['name'] lors de l'envoie ne ré affiche pas mes champs texte ?
Code:
if(isset($_POST["envoyer"]) OR $_FILES['photo']['name']!=""){
//traitement du formulaire
}
<!--Ré affichage des données du formulaire-->
 
WRInaute accro
Me suis en effet planté dans ma formulation. Il fallait lire inintéressant pas intéressant.

Concernant ton souci de double formulaire, je ne procède jamais ainsi. Les rares fois où j'ai utilisé un système de double formulaire, c'était du à une gestion en ajax des dits formulaires.

A priori tu ne fais pas du tout ça en ajax, aussi je vois mal pourquoi tu continues à t'entêter avec cette solution prise de tête et absolument pas optimisée. C'est comme si tu utilisais un formulaire différent par champ.
 
WRInaute passionné
Je m'entête car je veux trouver une solution.

J'ai testé ton code et la 1ere chose qu'il m'a renvoyé, c'est une erreur.
Parse error: syntax error, unexpected T_CASE
Comme je ne connais pas cette méthode avec l'utilisation de case "": et break; , je cherche comment ça s'utilise et visiblement, il faut utiliser un switch() ... m'enfin, suis pas sûre non plus !
 
Discussions similaires
Haut