Page 1 sur 2

Passage au Mysqli

Posté : 10 sept. 2014, 13:55
par inovea
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');
			}
			}
			
?>

Re: Passage au Mysqli

Posté : 10 sept. 2014, 15:29
par toytoy
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

Re: Passage au Mysqli

Posté : 10 sept. 2014, 16:28
par inovea
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 :)

Re: Passage au Mysqli

Posté : 10 sept. 2014, 16:39
par toytoy
tu l'as bien placé avant ton header ?

Re: Passage au Mysqli

Posté : 10 sept. 2014, 17:05
par ynx
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

Re: Passage au Mysqli

Posté : 10 sept. 2014, 17:15
par toytoy
les " sont acceptés par MySQL, donc je vois pas ou est le problème :/

Re: Passage au Mysqli

Posté : 10 sept. 2014, 20:09
par inovea
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';
?>	

Re: Passage au Mysqli

Posté : 11 sept. 2014, 11:40
par sirakawa
// 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

Re: Passage au Mysqli

Posté : 11 sept. 2014, 13:46
par inovea
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

Re: Passage au Mysqli

Posté : 11 sept. 2014, 13:58
par sirakawa
$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

Re: Passage au Mysqli

Posté : 11 sept. 2014, 14:48
par inovea
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);

Re: Passage au Mysqli

Posté : 11 sept. 2014, 16:51
par ynx
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'

Re: Passage au Mysqli

Posté : 11 sept. 2014, 17:29
par inovea
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);
    }
}

Re: Passage au Mysqli

Posté : 12 sept. 2014, 14:16
par moogli
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) :)


@+

Re: Passage au Mysqli

Posté : 12 sept. 2014, 14:34
par ynx
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