[RESOLU] Passage au Mysqli

Petit nouveau ! | 9 Messages

10 sept. 2014, 13:55

Bonjour à tous,
je suis actuellement en train de réaliser un petit site à titre personnel pour débuter mon apprentissage du PhP.
Le but du site est de permettre à des invités d'un mariage (qui ont donc reçu un faire part) de se connecter via un code de réservation présent sur le fameux faire-part et de dire si oui ou non ils seront présents et s'ils seront accompagnés d'enfants.

J'avais préalablement réalisé ma requête et son traitement en Mysql et qui fonctionnait correctement. Or, le Mysql devenant moins utilisé on m'a conseillé de passé en Mysqli et mon fameux code ne fonctionne plus malgré les modifications.
Je fais donc appel aux âmes charitables qui auront la gentillesse de m'expliquer ce que j'ai mal fait sur ce code.
Merci à vous

Voici mon ancien code fonctionnel en MYSQL
<?php 
	session_start();
        require("inc/connexion.php");
	if(isset($_POST) && !empty($_POST['pass'])){
			extract($_POST);
			$pass = sha1($pass);
			mysql_connect("xxxx","xxxxx", "xxxxxxx");
			mysql_select_db("xxxxxxx");	
			$sql = "SELECT id, nom, prenom, disponible, enfants, nb_enfants FROM Mariage WHERE pass='$pass'";
			$req = mysql_query($sql) or die(mysql_error());
			if(mysql_num_rows($req)>0){
				$data = mysql_fetch_assoc($req);
				$_SESSION['Auth'] = array(
					'id' => $data['id'],
					'pass' => $pass,
					'nom'=> $data['nom'],
					'prenom'=> $data['prenom'],
					'disponible' =>$data['disponible'],
					'enfants' => $data['enfants'],
					'nb_enfants' =>$data['nb_enfants']
						);
				header ('Location: reservation.php');
			}
			else{
				echo '<p class="error">CODE DE RESERVATION INEXISTANT</p>';
			}
	}
?>
Et voici le nouveau code, qui ne reponds pas...
<?php 
	session_start();
	require("inc/connexion.php");
	
	if(isset($_POST) && !empty($_POST['pass'])){
			extract($_POST);
			$pass = sha1($pass);
			// Requête        
			$query = mysqli_query($bdd, 'SELECT id, nom, prenom FROM Mariage WHERE pass='.$pass.' ');
			if($query) {
        		$donnees = mysqli_fetch_assoc($query); 
				$_SESSION['Auth'] = array(
					'id' => $donnees['id'],
					'pass' => $pass,
					'nom'=> $donnees['nom'],
					'prenom'=> $donnees['prenom']
					);
					header ('Location: reservation.php');
			}
			}
			
?>

Eléphant du PHP | 113 Messages

10 sept. 2014, 15:29

Cette ligne (n'est pas vraiment une erreur), mais !empty testeras déjà que la variable existe, donc pas besoin de faire le test isset
if(isset($_POST) && !empty($_POST['pass'])){


mysqli_query($bdd, 'SELECT id, nom, prenom FROM Mariage WHERE pass='.$pass.' ');
En sql ta requete donnerai pour $pass="exemple": SELECT id, nom, prenom FROM Mariage WHERE pass=exemple
exemple serait donc interprété comme un champ et pas une valeur, il te manque donc les " :
mysqli_query($bdd, 'SELECT id, nom, prenom FROM Mariage WHERE pass="'.$pass.'" ');

Et après ta requete n'oublie pas le mysqli_free_result($query);


Tout est ok autrement
Modifié en dernier par toytoy le 10 sept. 2014, 16:40, modifié 1 fois.

Petit nouveau ! | 9 Messages

10 sept. 2014, 16:28

Ah merci beaucoup!
Il ne manquait juste que les guillemets, merci à présent mon formulaire fonctionne et me redirige correctement.
Une dernière question, j'aurais aimé savoir ce que voulait dire ce message d'erreur concrètement ?
Warning: mysqli_free_result() expects parameter 1 to be mysqli_result, boolean
Warning: Cannot modify header information - headers already sent by

J'ai regardé sur internet, mais j'avouerais que je ne comprends pas forcement, donc une explication spéciale "débutant" ne serait pas de refus !
Merci encore :)

Eléphant du PHP | 113 Messages

10 sept. 2014, 16:39

tu l'as bien placé avant ton header ?

ynx
Mammouth du PHP | 586 Messages

10 sept. 2014, 17:05

Salut,

Le message d'erreur indique que le paramètre transmis à la fonction mysqli_free_result n'a pas le bon type. Le paramètre attendu doit être une ressource de type mysqli_result, or tu lui fournis un booléen.
mysqli_free_result($query); // $query correspond ici à FALSE
Ta variable $query est égale à FALSE car ta requête sql ne s'est pas exécutée correctement (surement une erreur de syntaxe).
Doc de mysqli_query : Retourne FALSE en cas d'échec (http://php.net/manual/fr/mysqli.query.php)

Il faut donc toujours vérifier si nos requêtes sont bien exécutées :
$result = mysqli_query($bdd, "ma requete sql");

if (!$result) {
    echo "Erreur SQL : " . mysqli_error($bdd);
} else {
    // la requête s'est bien exécutée
}
Enfin, ton erreur sql doit venir de l'utilisation des guillemets doubles, il me semble que MySQL n'accepte que l'utilisation des guillemets simples (il te suffit d'inverser les guillemets de ta requête).

PS : attention aux injections sql, il faudrait utiliser mysqli_real_escape_string pour protéger tes données.
PS2 : mysqli_free_result n'est pas forcément nécessaire si tu n'effectue qu'une seule requête sur ta page puisque la mémoire sera de toute façon libérée à la fin de ton script

Bonne journée

Eléphant du PHP | 113 Messages

10 sept. 2014, 17:15

les " sont acceptés par MySQL, donc je vois pas ou est le problème :/

Petit nouveau ! | 9 Messages

10 sept. 2014, 20:09

Merci pour toutes vos réponses.
Pour vous répondre à mon tour, oui j'ai bien placé mon fameux mysqli_free_result avant le header et si je dis pas de betise cette ligne doit vérifier que ma requête s'execute :
if (!$query)
die ('Erreur sql: '.mysqli_error($bdd));
else

_______


Voici le code en question :
<?php
session_start();
require("inc/connexion.php");
//require("inc/auth.php");
// Si Auth n'est pas validé on revoie vers l'Acceuil
//if(!Auth::isLogged())
//header('Location: index.php');
  
// on teste si les variables du formulaire sont déclarées

if (isset($_POST['disponible']) && isset($_POST['enfants']))
{
    $disponible = mysqli_real_escape_string($bdd, $_POST['disponible']);
    $enfants = mysqli_real_escape_string($bdd, $_POST['enfants']);
    $nb_enfants = mysqli_real_escape_string($bdd, $_POST['nb_enfants']);
 
    // lancement de la requête
    $query = mysqli_query($bdd, 'UPDATE Mariage SET disponible = "'.$disponible.'", enfants = "'.$enfants.'", nb_enfants = "'.$nb_enfants.'" WHERE id = "'.$_SESSION['Auth']['id'].'"');
    if (!$query)
        die ('Erreur sql: '.mysqli_error($bdd));
    else
    {
        mysqli_free_result($query);
        // Redirection
        header('Location: confirmation.php');
    }
}
else
    echo 'Les variables du formulaire ne sont pas déclarées';
?>	

Mammouth du PHP | 2278 Messages

11 sept. 2014, 11:40

// lancement de la requête
$query = mysqli_query($bdd, 'UPDATE Mariage SET disponible = "'.$disponible.'", enfants = "'.$enfants.'", nb_enfants = "'.$nb_enfants.'" WHERE id = "'.$_SESSION['Auth']['id'].'"');
// lancement de la requête
$id = $_SESSION['Auth']['id'];
$requete = "'UPDATE Mariage SET disponible ='disponible' , enfants = '$enfants', nb_enfants = '$nb_enfants' WHERE id = '$id' ";
//permet
print "<br>$requete"; qu'on peut visualiser et copier coller dans phpmyadmin si besoin
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Petit nouveau ! | 9 Messages

11 sept. 2014, 13:46

Merci de ta réponse Sirakawa.
J'ai donc suivi tes conseils et modifié mon code, je me permets de le partager à nouveau a cas où il y ait des erreurs :
session_start();
require("inc/connexion.php");
require("inc/auth.php");
// Si Auth n'est pas validé on revoie vers l'Acceuil
if(!Auth::isLogged())
header('Location: index.php');
  
// on teste si les variables du formulaire sont déclarées

if (isset($_POST['disponible']) && isset($_POST['enfants']))
{
    $disponible = mysqli_real_escape_string($bdd, $_POST['disponible']);
    $enfants = mysqli_real_escape_string($bdd, $_POST['enfants']);
    $nb_enfants = mysqli_real_escape_string($bdd, $_POST['nb_enfants']);
 
// lancement de la requête
$id = $_SESSION['Auth']['id'];
$requete = "'UPDATE Mariage SET disponible ='$disponible' , enfants = '$enfants', nb_enfants = '$nb_enfants' WHERE id = '$id' ";
//permet
print "<br>$requete"; 
    if (!$requete)
        die ('Erreur sql: '.mysqli_error($bdd));
    else
    {
        mysqli_free_result($requete);
        // Redirection en Javascript
        //echo '<script language="Javascript">
			//	document.location.replace("$confirmation.php");
				//</script>)';
    }
}
Et donc les print"$requete" mais retourne :
'UPDATE Mariage SET disponible ='oui' , enfants = 'oui', nb_enfants = '3' WHERE id = '2'

Accompagné de ce même message d'erreur :
Warning: mysqli_free_result() expects parameter 1 to be mysqli_result, string given in /homepages/19/d344013182/htdocs/Inovea/mariage/reservation.php on line 26

Mammouth du PHP | 2278 Messages

11 sept. 2014, 13:58

$requete = "'UPDATE Mariage SET disponible ='$disponible' , enfants = '$enfants', nb_enfants = '$nb_enfants' WHERE id = '$id' ";
//permet
print "<br>$requete"; 
$resultat = $mysqli->query($requete);; //me semblait evident.....
     if (!$resultat) // et remplacer on $requete par $resultat
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Petit nouveau ! | 9 Messages

11 sept. 2014, 14:48

Merci encore une fois de ton aide, on avance je pense, mais je t'avoue ne pas tout saisir.
J'ai procédé à tes modifications, voilà le code d'ailleurs :
// Identification des variables
$id = $_SESSION['Auth']['id'];
$requete = "'UPDATE Mariage SET disponible ='$disponible' , enfants = '$enfants', nb_enfants = '$nb_enfants' WHERE id = '$id' ";
print "<br>$requete";
// Requete
$resultat = $mysqli->query($requete); //me semblait evident.....
     if (!$resultat) // et remplacer on $requete par $resultat
        die ('Erreur sql: '.mysqli_error($bdd));
    else
    {
        mysqli_free_result($requete);
    }
}
Et j'ai deux retours d'erreur :
Notice: Undefined variable: mysqli in /homepages/19/d344013182/htdocs/Inovea/mariage/reservation.php on line 22

Fatal error: Call to a member function query() on a non-object in /homepages/19/d344013182/htdocs/Inovea/mariage/reservation.php on line 22
La ligne 22 correspond à -> $resultat = $mysqli->query($requete);

ynx
Mammouth du PHP | 586 Messages

11 sept. 2014, 16:51

sirakawa te présente la syntaxe objet, puisque tu utilises la syntaxe procédurale il faut simplement remplacé par :
$resultat = mysqli_query($bdd, $requete);
mais l'idée était surtout d’exécuter ta requête :)

Tu as bien erreur de syntaxe sql dans ta requête : supprime le premier guillemet simple devant UPDATE.
Requête corrigée :
UPDATE Mariage SET disponible = 'oui', enfants = 'oui', nb_enfants = '3' WHERE id = '2'

Petit nouveau ! | 9 Messages

11 sept. 2014, 17:29

En effet après avoir supprimé le guillemet, je n'ai plus d'erreur SQL, ça ne tient parfois à pas grand chose! Merci à toi :)
Cependant j'ai toujours cette erreur qui persiste :
Warning: mysqli_free_result() expects parameter 1

Le nombre d'enfants présents s'enregistre bien dans ma base de données, mais qu'on choisisse "disponible" ou " non disponible" la valeur reste égale à 0.
$id = $_SESSION['Auth']['id'];
$requete = "UPDATE Mariage SET disponible ='$disponible' , enfants = '$enfants', nb_enfants = '$nb_enfants' WHERE id = '$id' ";
print "<br>$requete";
// Requete
$resultat = mysqli_query($bdd, $requete);
     if (!$resultat) // et remplacer on $requete par $resultat
        die ('Erreur sql: '.mysqli_error($bdd));
    else
    {
        mysqli_free_result($requete);
    }
}

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

12 sept. 2014, 14:16

salut,


le message d'erreur complet c'est mieux pour s'y retrouver :)

en clair le tiens te dit mysqli_free_result prend en paramètre une ressource (issu de mysqli_query par exemple) alors que tu lui fournit une chaîne de caractère.

par contre la donc ne connait pas mysqli_free_result mais mysqli_result_free :s

quoi qu'il y en soit c'est la variable $resultat qu'il faut que tu utilise et non pas la chaîne de caractère qui contient la requête SQL ($requete) :)


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

ynx
Mammouth du PHP | 586 Messages

12 sept. 2014, 14:34

Il s'agit bien de la fonction myqsli_free_result() qui correspond à la syntaxe procédurale.
En syntaxe objet l'équivalent est effectivement mysqli_result::free() (la méthode free() de la classe mysqli_result).

C'est un bon réflexe de toujours libérer la mémoire si un script effectue plusieurs requête à la suite, mais c'est facultatif pour ce code puisque la mémoire sera de toute façon libérée à la fin du script (c-a-d juste après avoir exécuté l'unique requête).

Bonne journée