Utilisation de formulaires successifs

Eléphanteau du PHP | 37 Messages

07 juil. 2011, 17:44

Rebonjour,

Encore une question SVP. :?

Je bloque sur le pb suivant :

J'affiche d'abord un formulaire demandant le chemin du fichier à traiter pour lequel je place une instruction if(isSet($_POST['Nom_bouton']))
echo '<form id="Input_file" method="post" action="">
		<p>Please, enter the html file to be processed:</p>
		<p><input type="text" name="file_name" /></p>
		<p><input type="submit" value="OK" name="OK_Input_File" /></p>
		</form>';
if (isSet($_POST['OK_Input_File']))
qui marche bien (le traitement à l'intérieur du if est effectué quand je clique sur le bouton).

En fin de traitement, je demande le nom sous lequel enregistrer le fichier résultat. J'utilise la même technique
echo '<form id="Output_file" method="post" action="">
		<p>Enter the name of the output file</p>
		<p><input type="text" name="output_file_name" /></p>
		<p><input type="submit" value="OK" name="OK_Output_File" /></p>
		</form>' ;
if (isSet($_POST['OK_Output_File']))
qui cette fois ne marche plus (le traitement à l'intérieur du if n'est pas effectué et le programme continue sans que j'aie cliqué sur le bouton) !!!

J'ai pourtant recopié la première structure en donnant les noms ad hoc.

Pouvez-vous m'expliquer s'il vous plaît ?

Merci d'avance
Modifié en dernier par Bosyphe le 17 juil. 2011, 23:23, modifié 2 fois.

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

07 juil. 2011, 18:02

Normalement cela devrait fonctionner, mais dans la mesure où tu as deux formulaires, chacun avec son bouton submit, seuls les éléments du formulaire soumis sont envoyés...

En gros, si je clique sur le premier bouton ok (OK_Input_File), alors la valeur du second n'est pas envoyé (puisque dans un autre formulaire) ... peut être est-ce de là que vient ton problème ?
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 37 Messages

11 juil. 2011, 10:40

Merci de ta réponse, Ryle
(et excuse-moi s'il te plaît pour ma réponse tardive)

Les deux formulaires sont successifs :

D'abord mon script PHP affiche le premier, qui demande le chemin du fichier html à traiter.
Un clic sur le bouton de ce formulaire ("OK_Input_File) lance le traitement du fichier indiqué.

Ensuite, le script affiche le deuxième formulaire, qui demande si le nom d'enregistrement du fichier résultat généré par défaut convient.
Apparemment, il n'y a pas de lien de fonctionnement entre le premier et le second formulaires, le premier étant terminé quand s'affiche le second.
Le programme devrait donc attendre que je clique sur le bouton du 2ème formulaire ("OK_Output_File").

Je ne comprends donc pas d'où vient le problème. (Je cherche sur le Net "php formulaires successifs", d'où le changement du sujet de mon post. Les exemples que je rencontre procèdent de la même façon : boutons de validation portant des noms différents.)


Par ailleurs, je ne comprends pas trop la logique de l'instruction
if (isSet($_POST['OK_Input_File']))
:

une instruction if vérifie si la condition est vraie. Si c'est la cas, elle traite le bloc d'instructions associé à l'instruction. Sinon, elle passe aux instructions suivant le bloc if.
Il n'y a pas de notion d'attente d'un événement : soit à l'instant t la condition est vraie, soit elle est fausse.
Pourquoi alors
if (isSet($_POST['OK_Input_File']))
attend le clic sur le bouton. Est-ce que c'est $_POST qui génère cette attente ?

Merci

Mammouth du PHP | 2278 Messages

11 juil. 2011, 12:32

1) Le if (isset($_POST['quelquechose'])
Quand dans une page html noimmee index.html tu envoies un formulaire avec
<html>
<form method='post' action ='verifier.php'>
tapez un mot :<input type = 'text' name= 'mot'>
<button type ='submit'>ok</button>
</html>
, c'est la ligne <button type ='submit'> ou, comme tu écris, <input type='submit'> qui suspend les opérations.
Tant que tu n'actives pas le bouton en question, il ne se passe plus rien.
Quand tu actives ce bouton, la page verifier.php est activée
<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang = "fr">
<META http-equiv = 'Content-Type' content = 'text/html; charset = utf-8'>
<?PHP
print_r($_POST); // juste pour savoir ce qui se passe
if (isset ($_POST['mot'])): 
	$mot = $_POST['mot'] ; 
else:
	$mot = "rien";
endif;
if ($mot == "") $mot ="vide";
print "voici votre mot $mot";
?>
les if successifs testent une fois et on passe à la suite...
isset ($qqch) signifie que $qqch a été défini ou déclaré, mais pas s'il contient quelque chose.
Le premier if (isset($_POST['mot'])) ou
$mot = isset($_POST['mot'])? $_POST['mot'] : ""
permet de s"assurer d'une valeur pour mot au cas en particulier où on aurait abouti sur cette page sans passer par le chemin normal
Les valeurs d'un seul formulaire sont pasées à la page qu'il cible par son action=
2) Dans ton cas:
avec ce code :
<?PHP
echo '<form id="Input_file" method="post" action="">
                <p>Please, enter the html file to be processed:</p>
                <p><input type="text" name="file_name" /></p>
                <p><input type="submit" value="OK" name="OK_Input_File" /></p>
                </form>';
	if (isSet($_POST['OK_Input_File'])):
			echo '<form id="Output_file" method="post" action="">
                <p>Enter the name of the output file</p>
                <p><input type="text" name="output_file_name" /></p>
                <p><input type="submit" value="OK" name="OK_Output_File" /></p>
                </form>' ;
	endif;
?>
comme action ='', la page s'affiche correctement la première fois et attend le clic sur le bouton OK_input sans afficher le deuxième formulaire
Quand ce bouton est cliqué la page est rechargée et j'obtiens deux formulaires. Si je remplis le second, la page se recharge et on repasse normalement au premier. Au passage j'ai perdu le nom du fichier d'entrée

Pour moi je ferais :
<?PHP
$file_name = isset($_POST['file_name'] )? $_POST['file_name'] : "";

$passage = isset($_POST['passage']) ? $_POST['passage'] : 1;
switch ($passage):
	case 1:
		print "<form id='Input_file' method='post' action=''>
					<p>Please, enter the html file to be processed:</p>
					<p><input type='text' name='file_name' value = '$file_name'/></p>
					<p><input type='hidden' value='2'  name='passage' /></p>
					<button type='submit'>OK</button>
					</form>";
		break;
	case 2:
			$file_name = isset($_POST['file_name'] )? $_POST['file_name'] : "";
			print "$file_name";
				print "<form id='Output_file' method='post' action=''>
					<p><input type='text' name='file_name' value = '$file_name'/></p>
					<p>Enter the name of the output file</p>
					<p><input type='text' name='output_file_name' /></p>
					<p><input type='hidden' value='3' name='passage' /></p>
					<button type='submit'>OK</button>
					
					</form>'";
					break;
	case 3:
		$f_entree = $_POST['file_name'];
		$f_sortie = $_POST['output_file_name'];
		print "$f_entree => $f_sortie";
		break;
endswitch;	
?>
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Eléphanteau du PHP | 37 Messages

11 juil. 2011, 15:46

Merci grandement, Sirakawa, de ta réponse détaillée et du temps que tu y as consacré ! :?

Je vais d'ici ce soir analyser la solution que tu proposes afin d'en bien comprendre le fonctionnement.

Merci encore ! Je suis très impressionné !

Eléphanteau du PHP | 37 Messages

19 juil. 2011, 12:06

Bonjour à toutes et à tous

J'ai bien restructuré mon script php selon les indications de Sirakawa, que je remercie encore grandement :), après toutefois certains efforts de compréhension et de tâtonnements.

Je rappelle le contexte : je demande dans un premier formulaire le chemin du fichier xhtml devant être traité.
Le traitement de ce fichier me permet de définir le nom du fichier résultat par défaut selon la codification de l'entreprise pour laquelle je réalise ce script (référence, date, version, titre du document).

Dans un deuxième formulaire, je demande de confirmer ou de modifier le nom d'enregistrement par défaut.

Voici donc la structure générale du code :
$form_run = isset($_POST['form_run']) ? $_POST['form_run'] : 1; // $form_run is set to 1 if not previously defined
switch ($form_run)
{
	case "1" :
	/* Ask for the name of the input file */
	
	print "<form id='Input_file' method='post' action=''>
		<p>Please, enter the html file to be processed:</p>
		<p><input type='text' name='input_file_name' /></p>
		<input type='hidden' value='2'  name='form_run' />
		<p><button type='submit'>OK</button></p>
		</form>";
	 break;
	 

	case "2" :

	/* Processing of the input file */

	$input_file_name = $_POST['input_file_name'];
	$document_directory = pathinfo($input_file_name, PATHINFO_DIRNAME);
	$document = file_get_contents($input_file_name);

	[...]

	$output_file_name = $reference . " ed" . $edition . " " . $title . ".html";

	/* Ask for the name of the output file */

	print "<form id='Output_file' method='post' action=''>
		<p>Enter the name of the output file</p>
		<p><input type='text' name='output_file_name' value='$output_file_name' /></p>
		<input type='hidden' name='directory' value='$document_directory' />
		<input type='hidden' name='document' value='$document' />
		<input type='hidden' name='form_run' value='3' />
		<p><button type='submit'>OK</button></p>						
		</form>";
	
	/* exit of case "2" */	
	break;

	case "3" :

	/* Generation of the output file */
	$output_file_name = $_POST['output_file_name'];
	$output_file_path = $_POST['directory'] . "\\" . $output_file_name;
	$output_file = fopen($output_file_path, 'w');
	$document = $_POST['document'];
	print $document;
	
	 fputs($output_file, $document);
	 fclose($output_file);

/* End of switch */	
}
Si les variables sont bien transmises via les formulaires, il en est tout autrement du document lui-même qui se trouve bien intégralement copié dans le formulaire 2 (j'empêche son affichage dans le style du formulaire) mais est sérieusement tronqué à la sortie de l'instruction $document = $_POST['document'].

Comment puis-je correctement récupérer le document ? (c'est quand même le point le plus important : enregistrer le document traité dans le case "2").

Merci d'avance pour votre aide.

ViPHP
xTG
ViPHP | 7331 Messages

19 juil. 2011, 12:57

$document contient-elle des apostrophes ? Si c'est le cas il faut les échapper afin qu'elles ne rentrent pas en conflit avec celles du code HTML.

Eléphanteau du PHP | 37 Messages

19 juil. 2011, 13:03

Merci de ta réponse,

Effectivement, le document contient des apostrophes (typiquement, l'apostrophe du possessif en anglais : John's children) et $document s'arrête à la première apostrophe rencontrée. (La mise en forme est cependant conservée.)

J'ai essayé de placer
$document = addslashes($document) avant de le transmettre dans le formulaire 2. Mais là, le $document restitué perd sa mise en forme et s'arrête de toute façon en même endroit, en affichant le \ précédant l'apostrophe.

Comment donc récupérer $document en intégralité ? Je vais essayer d'inclure un petit traitement remplaçant toutes les apostrophes de texte par le caractère &rsquote; avant de transmettre le document au formulaire.

Eléphanteau du PHP | 37 Messages

20 juil. 2011, 00:08

Bonjour,

C'était bien l'apostrophe qui posait problème lors du transfert du document via le formulaire.

Le problème a donc pu être réglé en remplaçant toutes les apostrophes par son code numérique
$document = str_replace("'", "'" , $document);
(Le remplacement par son code littéral &apos; ne permet pas de régler le problème : le document renvoyé par le formulaire est tronqué à la première apostrophe rencontrée.)

Merci de votre aide

Mammouth du PHP | 2278 Messages

20 juil. 2011, 11:51

je me demande si htmlentity ne fait pas coreectement ce remplacement, fort utile quand il faut enregistrer des valeurs dans une bdd, où l'apostrophe sert à encadrer les champs texte...
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Eléphanteau du PHP | 37 Messages

20 juil. 2011, 23:50

Merci Sirakawa pour ta suggestion.

Effectivement, la fonction htmlentities
$document = htmlentities($document, ENT_QUOTES);

réalise ce remplacement et le document est correctement transmis via le formulaire. (Le paramètre ENT_QUOTES signifie que la fonction convertit aussi bien les guillemets doubles que les guillemets simples.)