[RESOLU] Formulaire avec requête préparée et LIKE

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : [RESOLU] Formulaire avec requête préparée et LIKE

Re: Formulaire avec requête préparée et LIKE

par zeor » 02 déc. 2012, 14:58

Je n'ai plus ce message d'erreur, pour y remèdier j'ai fermé l'accolade du
if(!empty($_POST['genre']) OR !empty($_POST['nationalite']) OR !empty($_POST['epoque']) OR !empty($_POST['acteur']) OR !empty($_POST['realisateur']))
tout à la fin (après le $req->closeCursor() ;)

Je vais essayer de faire en sorte que lorsqu' aucun élément du formulaire est rempli, tous les films de la bdd soient affichés.
Quant à la solution que tu m'as proposé, il est vrai qu'actuellement, je n'aurais jamais réussi à faire cela tout seul, on voit que tu maitries le PHP. Je comprends maintenant le code mais de là à savoir le refaire tout seul...
Enfin comme on dit, c'est en bûchant qu'on devient bûcheron :lol:

Un grand merci à vous =D>

Re: Formulaire avec requête préparée et LIKE

par audaxman » 02 déc. 2012, 13:20

l'erreur semble être à la ligne
while ($donnees = $req->fetch())
en fait c'est là qu'est le pb, parce que la variable $req est définie à l'intérieur de la condition if(!empty(...) OR ... ) et que tu y fait appel ici dans tous les cas, même quand $req n'a pas été définie.

tu peux par exemple rajouter une condition isset() dans ton while() :
while ( isset($req) && $donnees = $req->fetch())
par exemple.

dans tous les cas, tu as certainement intérêt a essayer de reformuler le code à ta manière pour le comprendre totalement, ce que je t'ai proposé comme code n'est pas la seule solution possible.

Re: Formulaire avec requête préparée et LIKE

par zeor » 02 déc. 2012, 12:58

Cette condition existe puisqu'il y a:
if(!empty($_POST['genre']) OR !empty($_POST['nationalite']) OR !empty($_POST['epoque']) OR !empty($_POST['acteur']) OR !empty($_POST['realisateur']))

Re: Formulaire avec requête préparée et LIKE

par schim59 » 02 déc. 2012, 12:27

Faudrait ajouter une condition alors pour pas faire la requete tout de suite.

Re: Formulaire avec requête préparée et LIKE

par zeor » 02 déc. 2012, 11:00

Oui c'est étrange, cependant lorsque je remplis ne serait ce qu'un élément de mon formulaire, ces messages disparaissent et la requête fonctionne.

Re: Formulaire avec requête préparée et LIKE

par schim59 » 02 déc. 2012, 08:54

Pour fetch ca concerne la mise ne page du résultat.
http://php.net/manual/fr/pdostatement.fetch.php

Dans ton cas il n'y a rien en paramètre de la fonction (ligne 148) qui soit un objet. je crois que les deux erreurs sont liées.
Il faut régler le probleme de $req.
Qui vient de $valeurs[] je pense.

pour undifined variable, tu peux faire
var_dump($req) et var_dump($valeurs)
qui te confirmera surement que tu fais référence à une variable inexistante soit l'une soit l'autre.

Puis remonter jusqu’à la source.
$req -> execute($valeurs);
juste après ca :
$req = $bdd->prepare('SELECT titre, resume, annee, realisateur, pochette, acteur, genre FROM film WHERE ('.conditions.')') ;
C'est bizarre il me semble.

Bon codage

Re: Formulaire avec requête préparée et LIKE

par zeor » 02 déc. 2012, 01:31

Je m'en suis même pas rendu compte, merci
Plus que 2 erreurs sur 4,
undefined variable :req ainsi que Fatal error: Call to a a member function fetch() on a non object à la ligne 148 pour les deux.

Je vois pas pourquoi il dit que req n'est pas définie mais bon... j'y regarderai demain matin limite.

Merci à toi.

Re: Formulaire avec requête préparée et LIKE

par audaxman » 02 déc. 2012, 01:22

j'avais oublié le '$' de '$conditions' à la ligne
$req = $bdd->prepare('SELECT titre, resume, annee, realisateur, pochette, acteur, genre FROM film WHERE ('.$conditions.')') ;

Re: Formulaire avec requête préparée et LIKE

par zeor » 02 déc. 2012, 00:51

Merci pour ta réponse, je t'avouerai être un peu perdu quand à la syntaxe de tout ça, j'ai essayé ce code,malheureusement, j'ai des erreurs que je ne comprends pas:

http://www.casimages.com/img.php?i=1212 ... 254207.jpg

j'ai une erreur: undefined variable:req à la ligne 146 ainsi qu'un erreur call to a member function fetch on a non-object à la ligne 146 également...
<?php
									try
									{
										$bdd = new PDO ('mysql:host=localhost; dbname=film', 'root', '');
									}
									catch(Exception $e)
									{
										die('Erreur : '.$e->getMessage());
									}
									
									?>
									<?php
									if(!empty($_POST['genre']) OR !empty($_POST['nationalite']) OR !empty($_POST['epoque']) OR !empty($_POST['acteur']) OR !empty($_POST['realisateur']))
									{
									$conditions = '';
									$valeurs = array();
									
									if(!empty($_POST['genre']))
										{
										$conditions .=  'genre=:genre';
										$valeurs['genre'] = $_POST['genre'];
										}
										
									if(!empty($_POST['nationalite']))
									{
									$conditions .=  empty($conditions)?'nationalite=:nationalite':' AND nationalite=:nationalite';
									$valeurs['nationalite'] = $_POST['nationalite'];
									}
									
									if(!empty($_POST['epoque']))
									{
									$conditions .=  empty($conditions)?'epoque=:epoque':' AND epoque=:epoque';
									$valeurs['epoque'] = $_POST['epoque'];
									}
									
									if(!empty($_POST['acteur']))
									{
									$conditions .=  empty($conditions)?'acteur LIKE :acteur':' AND acteur LIKE :acteur';
									$valeurs['acteur'] = '%'.$_POST['acteur'].'%';
									}
									
									if(!empty($_POST['realisateur']))
									{
									$conditions .=  empty($conditions)?'realisateur LIKE :realisateur':' AND realisateur LIKE :realisateur';
									$valeurs['realisateur'] = '%'.$_POST['realisateur'].'%';
									}
									$req = $bdd->prepare('SELECT titre, resume, annee, realisateur, pochette, acteur, genre FROM film WHERE ('.conditions.')') ;
									$req -> execute($valeurs);
									}
									?>
									<div class="content">
									<h3>Ma sélection selon vos <span>critères</span></h3>
									</div>
									<?php
									while ($donnees = $req->fetch())
										{
											?>
											<div class="content">
												<ul class="list">
													<li><img src="<?php echo ($donnees['pochette']) ;?>" alt=""/><strong><h3><?php echo htmlspecialchars(utf8_encode($donnees['titre'])) ;?></h3></strong></a>
														<strong>Date de sortie: </strong><?php echo htmlspecialchars($donnees['annee']);?></br>
														<strong>Realisateur: </strong><?php echo htmlspecialchars(utf8_encode($donnees['realisateur']));?></br>
														<strong>Acteurs Principaux: </strong><?php echo htmlspecialchars(utf8_encode($donnees['acteur']));?></br>
														<strong>Genre: </strong><?php echo htmlspecialchars(utf8_encode($donnees['genre']));?></br>
														<strong>Résumé: </strong><?php echo htmlspecialchars(utf8_encode($donnees['resume']));?></br>
													</li>
												</ul>
											</div>

									<?php
										}
									$req -> closeCursor() ;
									?>

Re: Formulaire avec requête préparée et LIKE

par audaxman » 02 déc. 2012, 00:01

Lorsque tu soumets un formulaire avec des champs que tu laisse vide ça envoie des chaînes vide dans les variables $_POST correspondante, du coup ces variables sont bien définie est sont égales à la chaîne vide.

tu peux faire un test si tu veux avec
if( $_POST['genre'] == '' ) echo "genre est égale à la chaîne vide" ;
donc pour faire ce que tu cherche à faire, il te faut utiliser la fonction empty() pour savoir s'il y a quelque chose dans les variables

ta condition devient
if(!empty($_POST['genre']) OR !empty($_POST['nationalite']) OR !empty($_POST['epoque']) OR !empty($_POST['acteur']) OR !empty($_POST['realisateur']) )
{

}
ensuite pour ta requête, tu as une erreur de logique, il te faut utiliser des 'AND' et non des 'OR',
ce qui se passe c'est que dans ta requête tu as par exemple 'acteur LIKE :acteur' et tu envoie la valeur '%%' pour ta variable :acteur, ceci va te renvoyer toutes les lignes de ta table pour lesquelles le champ 'acteur' contient au moins une fois la chaîne vide '', et cette condition est évidemment vérifiée pour toutes les lignes du tableau, d'où le fait que tu as tous les films qui apparaissent,

du coup la solution c'est d'utiliser des AND à la place de tes OR et soit utiliser des LIKE pour tous les champs dans ta requête de telle sorte que les champs non remplis ne soient pas pris en compte, ou il te faut construire dynamiquement ta requête

par exemple
if(!empty($_POST['genre']) OR !empty($_POST['nationalite']) OR !empty($_POST['epoque']) OR !empty($_POST['acteur']) OR !empty($_POST['realisateur']) )
{
	$conditions = '';
	$valeurs = array();
	if(!empty($_POST['genre']){
		$conditions .=  'genre=:genre';
		$valeurs['genre'] = $_POST['genre'];
	}
	if(!empty($_POST['nationalite']){
		$conditions .=  empty($conditions)?'nationalite=:nationalite':' AND nationalite=:nationalite';
		$valeurs['nationalite'] = $_POST['nationalite'];
	}
	if(!empty($_POST['epoque']){
		$conditions .=  empty($conditions)?'epoque=:epoque':' AND epoque=:epoque';
		$valeurs['epoque'] = $_POST['epoque'];
	}
	if(!empty($_POST['acteur']){
		$conditions .=  empty($conditions)?'acteur LIKE :acteur':' AND acteur LIKE :acteur';
		$valeurs['acteur'] = '%'.$_POST['acteur'].'%';
	}
	if(!empty($_POST['realisateur']){
		$conditions .=  empty($conditions)?'realisateur LIKE :realisateur':' AND realisateur LIKE :realisateur';
		$valeurs['realisateur'] = '%'.$_POST['realisateur'].'%';
	}
	$req = $bdd->prepare('SELECT titre, resume, annee, realisateur, pochette, acteur, genre FROM film WHERE ('.$conditions.')') ;
	$req -> execute( $valeurs );
	
}

Formulaire avec requête préparée et LIKE

par zeor » 01 déc. 2012, 22:10

Bonsoir, tout d'abord merci à ceux qui prendront le temps de lire ce message.

Je me suis amusé à crée un petit sie web en local où j'ai référencé les films que je possédais. J'y ai crée un formulaire de recherche de film avec les éléments suivants:
- Genre
- Nationalite
- Epoque
- Acteur
- Realisateur

Je souhaite pour le moment faire en sorte que la recherche fonctionne si l'utilisateur ne remplit qu'un de ces 5 champs
J'ai fais un premier essai qui fonctionne, bien que cela ne soit pas ce que je veux:
<?php
if (isset($_POST['genre']) OR isset($_POST['nationalite']) OR isset($_POST['epoque']) OR isset($_POST['acteur']) OR isset($_POST['realisateur']))
{
$req = $bdd->prepare('SELECT titre, resume, annee, realisateur, pochette, acteur, genre FROM film WHERE (acteur LIKE :acteur )') ;
$req -> execute(array(
'acteur' => '%'.$_POST['acteur'].'%',
));
?>
Comme vous pouvez le constater, j'ai ici utilisé une requête préparée avec un LIKE afin de faire en sorte que si l'utilisateur ne se souvient qu'une partie du nom de l'acteur, cela fonctionne.
Ce code fonctionne très bien. Cependant je souhaite faire une requête préparée avec les 5 éléments de mon formulaire, j'ai donc essayé le code suivant:
<?php
if (isset($_POST['genre']) OR isset($_POST['nationalite']) OR isset($_POST['epoque']) OR isset($_POST['acteur']) OR isset($_POST['realisateur']))
{
$req = $bdd->prepare('SELECT titre, resume, annee, realisateur, pochette, acteur, genre FROM film WHERE (genre=:genre OR nationalite=:nationalite OR epoque=:epoque OR acteur LIKE :acteur OR realisateur LIKE :realisateur)') ;
$req -> execute(array(
'genre' => $_POST['genre'],
'nationalite' => $_POST['nationalite'],
'epoque' => $_POST['epoque'],
'acteur' => '%'.$_POST['acteur'].'%',
'realisateur' => '%'.$_POST['realisateur'].'%'
));
?>
Malheureusement, ce code ne fonctionne pas, il m'affiche tous les films et ne prend donc pas en compte les WHERE (de plus même si je ne remplis aucun champ, il me sélectionne tous les films et ce malgré le isset.
Je pense donc qu'il s'agit d'un problème de syntaxe dans ma requête mais j’avoue ne pas savoir que faire pour que mon formulaire puisse fonctionner correctement.

En espérant trouver une solution sur ce forum, je vous souhaite à toutes et à tous une bonne soirée :)