Variable n'acceptant pas fetch()

Nouveau WRInaute
Bonjour,

Voici mon problème :
Sur une page html, je dois générer automatiquement des lignes provenant de ma base de données. Ainsi, je fais le code suivant pour pouvoir les récupérer :

include ("classes/MProduit.class.php");
$produit = new MProduit();
$List_Presta = $produit->Get_MP_info();
//$List_Presta = $produit->fetch();
$nb = sizeof($List_Presta
Code:
);

Comme vous le voyez, j'appelle la fonction Get_MP-info contenu dans MPrduit.class.php. Cette fonction ressemble à ça: 

public function Get_MP_info ()
	{
		define ('SERVEUR', 'localhost');
		define ('USER', 'root@localhost');
		define ('Paswd', '');
		define ('db', 'test');
		
		$cnx = mysql_connect(SERVEUR, USER,Paswd, db) ;
		$DB  = mysql_select_db(db) ;
		
		$sql = "SELECT ID_PRESTA, CODE, LIBELLE, PVHT, TVA, PVTTC
				FROM PRESTATION";
				
		$res = mysql_query($sql, $cnx) or die (mysql_error());
		echo $res;
		$VAL = $res->fetch();
		return $VAL;
         }

Pourtant mysql me renvoie cette erreur : 

Fatal error: Call to a member function fetch() on a non-object

J'ai suivi un tuto, car travaillant habituellement sur oracle, mysql n'est pas mon fort. Si vous avez une idée de pourquoi cela ne fonctionne pas ou une méthode plus simple ( je tiens à garder la fonction en dehors du fichier contenant la page) je suis preneur. 

Merci de l'attention que vous portez à mon problème. Cordialement
 
Nouveau WRInaute
J'ai modifier le code de cette façons : fin de la fonction Get_MP_info() :

$res = mysql_query($sql, $cnx) or die (mysql_error());
$VAL = mysql_fetch_array($res) or die (mysql_error());
return $VAL;
}

et là plus d'erreur de fetch(). Par contre, je n'arrive pas à récupérer le contenu et mysql me sort ces erreurs :

Notice: Use of undefined constant CODE - assumed 'CODE' pour cette ligne : $nb = sizeof($List_Presta
Code:
)

Fatal error: Cannot use object of type MProduit as array pour cette ligne : echo ($produit['ID_PRESTA']);

Si quelqu'un peut m'aider :/
 
WRInaute accro
L'erreur est pourtant claire, il n'y a pas de constante CODE, tu dois surement le mettre entre quotes: $List_Presta['CODE']
 
Nouveau WRInaute
Merci spout ( toujours présent pour aider :))
Humm, sur oracle je faisait comme cela et ça fonctionnait bien :/ Si je ne veux pas utiliser PDO ( car apparemment le tuto utilisait celui-ci ) et que je veux arrivé à mes fin je fais comment ?

erreur corrigé pour CODE. En effet oublie des quotes de ma part.
 
WRInaute accro
Autant utiliser PDO direct pour plus de flexibilité / pérennité.
Mais ton code me semble bizarre, le mysql_connect() dans la fonction Get_MP_info() ...
De plus si tu l'appelles plusieurs fois, tu vas avoir une erreur de type already defined.
 
WRInaute discret
Bonjour,

la fonction mysql_query() ne retourne pas un objet à proprement dit.
Il s'agit d'un pointeur sur un ResultSet que l'on parcourt avec les fonctions mysql_fetch_*
$rs = mysql_query ($_SQL, $this->DBLink);
while($row=mysql_fetch_assoc($rs)) {

}
Si ton script utilise plusieurs type de bases, je te conseille vivement d'utiliser une interface pour accéder aux bases de données, par exemple la classe PDO.

Edit: Spout a été plus rapide :D
 
Nouveau WRInaute
Pour le moment je travaille en test local donc je prend pas encore le fait que je dois mettre les instruction de connexion hors de chaque fonctions. Le get_MP_info n'est appelé qu'une seul fois et sert à généré une liste de produit qui seront "implémentable" dans un panier virtuel. Le problème est que je n'arrive pas à les afficher donc de m'occuper réellement du panier.
 
Nouveau WRInaute
Bon effectivement le PDO est plus approprié pour ce que j'ai besoin. J'ai donc modifier ma fonction comme ceci :
public function Get_MP_info ()
{
define ('USER', 'root@localhost');
define ('Paswd', '');

$dbh = new PDO('mysql:host=localhost;dbname=test', USER, Paswd);
//$DB = mysql_select_db(db) ;

$sql = "SELECT ID_PRESTA, CODE, LIBELLE, PVHT, TVA, PVTTC
FROM PRESTATION";

$res = $dbh->query($sql) or die (mysql_error());
$VAL = $res->fetch();
return $VAL;
}
autant pour moi je me corrige tous seul xD Fonction fonctionnel ( ouf ) maintenant j'ai d'autre erreur :
Cannot use object of type MProduit as array pour cette ligne : echo ($produit['ID_PRESTA']);
 
WRInaute discret
la syntaxe avec PDO:

$pdo=new PDO(....);
$stmt = $pdo->prepare($SQL);
$stmt->execute();
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
 
Nouveau WRInaute
Merci Fobec, voici ma fonction avec les normes PDO :
define ('USER', 'root@localhost');
define ('Paswd', '');

$pdo = new PDO('mysql:host=localhost;dbname=test', USER, Paswd);
//$DB = mysql_select_db(db) ;

$sql = "SELECT ID_PRESTA, CODE, LIBELLE, PVHT, TVA, PVTTC
FROM PRESTATION";

$stmt = $pdo->prepare($sql);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $rs;
$stmt->closeCursor();
}

Maintenant j'ai ces problèmes sur ma page où je dois générer les tuples :
Pour $nb = sizeof($List_Presta['CODE']); mysql me renvoi :
Undefined index: CODE
Pour echo ($produit['ID_PRESTA']); mysql me renvoi :
Cannot use object of type MProduit as array

Pourtant la première erreur était résolue tout à l'heure :/ J'ai fait quelque chose qui ne fallait pas ?

( rappel :
include ("classes/MProduit.class.php");
$produit = new MProduit();
$List_Presta = $produit->Get_MP_info();
$nb = sizeof($List_Presta['CODE']);
echo ($produit['ID_PRESTA']);
) Encore merci de votre aides qui m'est énormément précieuse.
 
WRInaute discret
a priori, il s'agit d'erreur d'index dans les array,
utilise print_r($rs) ou var_dump($rs) pour visualiser le contenu des array et adapter l'accès aux variables CODE, ID, ...

place le return en fin de fonction
$stmt = $pdo->prepare($sql);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
return $rs;
 
Nouveau WRInaute
fobec a dit:
a priori, il s'agit d'erreur d'index dans les array,
utilise print_r($rs) ou var_dump($rs) pour visualiser le contenu des array et adapter l'accès aux variables CODE, ID, ...

place le return en fin de fonction
$stmt = $pdo->prepare($sql);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
return $rs;

modification apporté.
résultat du print_r($rs) :
array()
résultat du var_dump($rs) :
array
empty
-_-
Pourtant, la base de données contient 21 tuples contenant CODE et ma requête fonctionne sur mysql o_O
 
WRInaute discret
si je comprend bien :
public function Get_MP_info () {
$pdo = new PDO('mysql:host=localhost;dbname=test', USER, Paswd);
$sql = "SELECT ID_PRESTA, CODE, LIBELLE, PVHT, TVA, PVTTC FROM PRESTATION";
$stmt = $pdo->prepare($sql);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
------
print_r($rs);
return un tableau vide ?
-----
return $rs;
}
 
Nouveau WRInaute
En effet. La requête fonctionne quand je la met sur mysql pourtant. Voici le code utilisé :
public function Get_MP_info ()
{
define ('USER', 'root@localhost');
define ('Paswd', '');

$pdo = new PDO('mysql:host=localhost;dbname=test', USER, Paswd);
//$DB = mysql_select_db(db) ;

$sql = "SELECT ID_PRESTA, CODE, LIBELLE, PVHT, TVA, PVTTC
FROM PRESTATION";

$stmt = $pdo->prepare($sql);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($rs);
--------------
array empty
--------------
print_r($rs);
---------
array()
-----------
$stmt->closeCursor();
return $rs;

}

Je pensais que c'était la requête qui faisait planté mais, comme je l'ai dit plus haut : quand je la fait sur mysql, elle s'exécute et me sort 21 tuples. Troll BD ? ( Au cas ou : l’extension php_pdo_mysql est bien coché)
 
Nouveau WRInaute
Ce pourrait pas être une erreur de connexion à la base ? ( je dit cela, car je viens d'y penser et même si ma réflexion peut paraitre stupide, je préfère vérifier. )
 
WRInaute accro
public function Get_MP_info (){
...
$res = mysql_query($sql, $cnx) or die (mysql_error());
...
$VAL = $res->fetch();
return $VAL;
}
tu retourne un recordset déjà "fetché" !?! donc un record simple qui ne peut être parcouru ... normal il ne contient pas toute la requête
 
Nouveau WRInaute
zeb a dit:
public function Get_MP_info (){
...
$res = mysql_query($sql, $cnx) or die (mysql_error());
...
$VAL = $res->fetch();
return $VAL;
}
tu retourne un recordset déjà "fetché" !?! donc un record simple qui ne peut être parcouru ... normal il ne contient pas toute la requête

j'ai modifier ma fonction de base en PDO sur les conseils de spout et de fobec. La fonction actuel que j'utilise est celle-ci :
public function Get_MP_info(){
define ('USER', 'root@localhost');
define ('Paswd', '');
$pdo = new PDO('mysql:host=localhost;dbname=test', USER, Paswd);
$sql = "SELECT ID_PRESTA, CODE, LIBELLE, PVHT, TVA, PVTTC FROM PRESTATION";
$stmt = $pdo->prepare($sql);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($rs);
print_r($rs);
$stmt->closeCursor();
return $rs;
}
le print_r renvoi juste "array()" et le var_dump renvoi "array empty"
 
WRInaute accro
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
Oui enfin le problème semble le même j'utilise pas PDO mais ta fonction semble itérer sur le résultat de la requête alors que c'est pas là qu'il faut le faire.
 
Nouveau WRInaute
je dois le faire où alors ? Car si tu as la solution à mon problème je t'en serrais grandement reconnaissant sur le fait que je galère dessus depuis 4h environ ...
 
WRInaute discret
c'est surement pas grand chose :D
monte d'un cran le niveau debug pour récupérer les erreurs sql (requete, connexion, ...), ça permet de valider de ce coté.

try {
$pdo_opt[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
$pdo = new PDO(..., $pdo_opt);
...
} catch (PDOException $err) {
$msg='DB -> '.$err->getMessage();
echo $msg;
}
 
Nouveau WRInaute
J'ai essayé avec ceci au cas ou :
$result = mysql_query($stmt) or die(mysql_error());
print_r($result);

à la place de :

$stmt = $pdo->prepare($sql);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);

Même résultat : empty -_-
 
Nouveau WRInaute
Aucune autre information n'est affiché ormis :
array
empty

Array ( )
( ! ) Notice: Undefined index: CODE
( ! ) Fatal error: Cannot use object of type MProduit as array in

Vas se jeter d'un pond ... xD
 
WRInaute discret
En fait, il n'y a pas tellement de cas de figure possible.
dans le script suivant,

try {
$pdo_opt[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
$pdo = new PDO(..., $pdo_opt);
$stmt = $pdo->prepare($sql);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($rs);
} catch (PDOException $err) {
$msg='DB -> '.$err->getMessage();
echo $msg;
}

1. si aucune erreur n'est retournée par pdo
-> la connexion à la DB est bonne et la syntaxe SQL est ok
2. si print_r($rs) retourne un array vide
-> la requete sql est mauvaise
 
Nouveau WRInaute
Bon voici ce que j'ai fais :
Sur mon fichier de base sur lequel je dois afficher les résultats de cette p******** de fonction, j'ai rajouter pour tester ceci :
try
{
// On se connecte à MySQL
$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
$bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '', $pdo_options);
$reponse = $bdd->query('SELECT ID_PRESTA, CODE, LIBELLE, PVHT, TVA, PVTTC FROM PRESTATION');
$donnees = $reponse->fetch();
print_r($donnees);
$reponse->closeCursor(); // Termine le traitement de la requête

}
catch(Exception $e)
{
// En cas d'erreur précédemment, on affiche un message et on arrête tout
die('Erreur : '.$e->getMessage());
}

et vous savez ce que le print_r affiche ? BAH NON PAS EMPTY o_O mais :
Array ( [ID_PRESTA] => 1 [0] => 1
Code:
 => 01A [1] => 01A [LIBELLE] => lebon [2] => lebon [PVHT] => 10.00 [3] => 10.00 [TVA] => 19.60 [4] => 19.60 [PVTTC] => 10.00 [5] => 10.00 ) 
( bien entendu j'ai changé les données compte tenu de la confidentialité de celles-ci. 
Alors maintenant ma question est : POURQUOI ça fonctionne là ? alors que ma fonction me dit joyeusement d’allée voir plus loin si j'y suis  ?
 
WRInaute discret
toujours rester zen, c'est les joies du debug :lol:

pour que $donnees retourne un Array avec 22 enregistrements, utilise fetchAll(); à la place de fetch();
Le dur est est fait, ça marche !
Reste plus qu'à suivre la transmission de la variable $donnees entre les scripts avec des print_r() pour trouver ou ça coince ...
 
Nouveau WRInaute
Donc en gros je fais un copié collé et je change ma fonction avec le code qui fonctionne, change le fetch() par fetchAll() et je vous tiens au courant. Enfin j'en vois la fin, commencement ?
 
Nouveau WRInaute
Trololololol
Gardons notre sang froid ....
$donnees est bien renvoyé et m'affiche bien tous les tuples :
Array ( [0] => Array ( [ID_PRESTA] => 1 [0] => 1
Code:
 => 01A [1] => 01A [LIBELLE] => Dépôt d'avenant au règlement de jeu auprès de notre étude d'huisiers de justice [2] => Dépôt d'avenant au règlement de jeu auprès de notre étude d'huisiers de justice [PVHT] => 80.00 [3] => 80.00 [TVA] => 19.60 [4] => 19.60 [PVTTC] => 95.68 [5] => 95.68 ) [1] => Array ( [ID_PRESTA] => 2............................
J'ai donc fais un print_r($List_Presta);  et il me double la liste des array ...
Pourtant, j'ai toujours les erreurs suivantes : 
( ! ) Notice: Undefined index: CODE  pour la ligne : $nb = sizeof($List_Presta['CODE']);
( ! ) Notice: Undefined index: ID_PRESTA  pour la ligne : echo ($List_Presta['ID_PRESTA']);

Le plus difficile est fait mais, je ne comprend pas pourquoi l'ancien code ne fonctionnait pas et surtout pourquoi il continue de me sortir ces erreurs ...
 
WRInaute discret
$List_Presta['CODE'] n'existe pas en fait :wink:
$List_Presta contient une liste de 22 lignes et non d'un seul enregistrement !

pour pointer en direct $List_Presta[0]['CODE']
ou parcourir toute la liste avec
foreach($List_Presta as $presta) {
echo $presta['CODE'];
}
 
Nouveau WRInaute
OK j'ai résolue un problème majeur : le ID_PRESTA. En effet, quand je fais : echo($List_Presta['1']['1']) il m'affiche ceci : 01E qui est celui de mon deuxième tuple donc valide. Alors pour faire ma boucle, sachant que je dois séparer les champs en plusieurs parties ( basic, en plus, etc ...) dois-je les noter à la main ou je peut automatiser la chose ?
je pensais le faire avec une double boucle imbriqué personnellement :
for (int i(0); i < 5; ++i)
{ for (int j(0); j < ??;++j
{blablabla}}
non ?

Zut pas assez rapide pour ma réponse xD hum, ta façons est très pratique mais, affiche par exemple pour : echo ($List_Presta['1']['ID_PRESTA']); : 2 alors que cela doit être 01E. Merci beaucoup ( énormément ) pour ton aide et bien entendu, tu est cité dans le header des créateur de la page pour m'avoir énormément aidé ( c'est le minimum que je puisse faire ).
Je reste tout de même curieux de comprendre pourquoi la fonction que j'avais faite avec ton aide ne fonctionnait pas.
A et petit problème : pour avoir la taille exacte de $donnees je l'ai dans le c*** non ?
 
WRInaute discret
faire une boucle soi-même avec for() ou utiliser l'iterator foreach() ?
bonne question :D foreach() est bien pratique pour ce genre de chose.

Effectivement sizeOf() ou count() ne marche pas terrible sur un tableau multi-dimensionel.
Par contre, dans Get_MP_info () $reponse ->rowCount() devrait retourner le nombre d'enregistrement avec MySQL.
 
Nouveau WRInaute
Non, il faut faire : $nb = $reponse->rowCount(); sinon il renvoi la requête SQL. Pour ce qui est de la boucle, je suis d'accord mais, le problème est que je dois les scinder dans plusieurs tableaux donc je trouvais l'idée des boucle for plus adapter. Par contre je retiens le foreach() qui me servira pour une autre page.
donc si je fais :
-----code html header----
<?php for(int i(0); i < 4 ; ++1) { for (int j(1); i <5 ; ++j) { ?>
--html du graph tableau -- <? echo($List_Prepa[j])?> -- suite html (etc ... )
<?php } ?>
---Html 2e tableau --- etc ....
Cela devrait fonctionner non ?
Certes c'est une façons de coder dégueulasse mais, compte tenue du code que je dois modifier c'est largement plus propre ;)

EDIT : effectivement, je suis en php et pas en C++, les boucles for sont pas écrite de cette façons mais, j'ai changé la syntaxe :)
 
Nouveau WRInaute
C'est fonctionnel !! Merci beaucoup à vous. Au final je dois incrémenter à la main mais, bon c'est toujours mieux que si cela ne fonctionnait pas xD. Sujet clos.
 
Discussions similaires
Haut