Erreur sur foreach(...)

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 : Erreur sur foreach(...)

par aandre2937 » 23 juin 2007, 08:48

Quand ça bug je recommence avec le plus basique. Pour mysql, avec la méthode classique ci-dessous (en remplaçant les variables de la première ligne par tes valeurs), obtiens-tu le résultat escompté?
Je rappelle ce que j'ai spécifié dans mon message initial: je n'utilise pas (pour le moment) MySQL mais SQLite qui s'affranchit d'avoir à spécifier l'hôte, un utilisateur et un mot de passe. On n'y spécifie que la base de données à laquelle on désire se connecter. (cf. The Definitive Guide to SQLite - Michael Owens - Apress Berkeley CA 2006 ).

Je vais essayer d'y adapter tes suggestions. Merci et à bientôt.
(je ne me borne pas à poser des questions. Quand une suggestion me permet de progresser je le mentionne

Edité le 29 juin 2007

Voici le code que j'ai suivi, scanné de PHP 5 avancé:
<?php 


// définition des variables de connexion

$user = 'cyril'; 
$pass = 'motdepasse'; 
$dsn = 'mysql :host=localhost;dbname=publication'; 
// connexion à la base de données
try { 
$dbh = new PDO($dsn, $user, $pass);
}
catch (PDOException $e) { 
die( "Erreur! : " . $e->getMessage();
} 

// insertion d'un enregistrement 

$sql = "INSERT INTO auteur (login) VALUES ('roms')";
$dbh->exec($sql); 

// lecture d'enregistrements 

$sql = "SELECT login FROM auteur";
$resultat = $dbh->query($sql);
while ($row = $resultat->fetch())
print_r($row); 

// fermeture de la connexion

$dbh = NULL; 
?> 
Voici la citation introductive du code précédent:
Dans notre exemple, nous utilisons deux méthodes pour exécuter des requêtes SQL : execO et queryO. La première sert pour les requêtes ne renvoyant pas de résultat (INSERT, UPDATE et DELETE), la seconde renvoie une instance de la classe PDOStatement contenant le jeu de résultat correspondant à la requête (utile notamment pour les requêtes SELECT).

Avec ces quelques lignes d'exemple vous serez capable de réaliser la majorité des actions, mais vous pouvez améliorer vos accès à la base de données avec les nombreuses options proposées par PDO. Consultez notamment les requêtes préparées pour protéger vos requêtes des injections SQL (cf. chapitre 27 sur la sécurité).
Les lignes en gras me paraissent indiquer clairement que le jeu de résultat est bien un tableau.

Si cet exemple est erroné, que penser du reste de l'ouvrage, et s'il est correct, pourquoi ma connection et ma requête ne fonctionnent-elles pas? Que pourraient me conseiller les auteurs, Eric DASPET et Cyril Pierre de GEYER, ainsi que Damien SEGUY s'ils lisaient ceci?

Se gausser de moi a l'air aisé, mais me guider vers une solution, autrement plus difficile.

Merci toutefois pour vos conseils, lorsqu'ils m'aident à progresser.

par Cyrano » 21 juin 2007, 06:37

...De plus, j'insite sur mon var_dump() pour savoir ce que retourne cette méthode query()....
As-tu essayé ceci :
$sth = $dbh->query($sql); 
echo("<pre>\n");
var_dump($sth);
echo("</pre>\n");
:?:

par AB » 21 juin 2007, 02:24

Quand ça bug je recommence avec le plus basique. Pour mysql, avec la méthode classique ci-dessous (en remplaçant les variables de la première ligne par tes valeurs), obtiens-tu le résultat escompté?
mysql_connect("$host", "$login", "$password");
mysql_select_db("mescontacts.db");

$sql = "SELECT * FROM contacts ORDER BY nom, prenoms"; 
$res = mysql_query($sql);

while($res_row = mysql_fetch_assoc($res))
{echo $res_row['prenoms'].'&nbsp'.$res_row['nom'].'<br />';}

Re: Connexion PHP à une base SQLite

par aandre2937 » 19 juin 2007, 13:22

La solution ne m'a malheureusement toujours pas sauté à la figure comme un bouchon de champagne, et j'apprécierais beaucoup que quelqu'un me mette sur la voie.

Merci d'avance

Re: Connexion PHP à une base SQLite

par zeus » 19 juin 2007, 12:47

A ce stade, la connection à la base mescontacts.db est réussie.

Warning: PDO::query() [function.PDO-query]: SQLSTATE[HY000]: General error: 1 no such table: contacts in C:\www\dbtutor\sqlite_contacts.php on line 23

Résultat de var_dump($sth);.......bool(false)
...
Quand je lit ça, je me dit que c'est l'appel à la méthode query() qui est fausse puisque le var_dump() retourne "false" et que tu as un message d'erreur très explicite.

J'aurais envie de te demander de vraiment re-vérifier si tu te connectes bien sur la bonne base avec les bons droits :-k
Est-ce que tu arrives à passer d'autres requêtes avec cette méthode ?

Connexion PHP à une base SQLite

par aandre2937 » 19 juin 2007, 11:08

$sth est le retour de l'exécution de la méthode query() de l'objet $dbh ;)
De plus, j'insite sur mon var_dump() pour savoir ce que retourne cette méthode query().
Bonjour,
J'ai passé ma soirée à relire mes bouquins:
PHP5 Avancé (Eyrolles)
Je me lance en PHP et MySQL (MicroApp)
Definitive Guide to SQLite (Apress)
MySQL - Guide de l'Administrateur et Guide officiel (MySQL ab)
ainsi que l'aide en ligne

Je me suis livré également à différents essais dont voici le résultat:

SQLite
Code
<?php

	// Connexion à la base de données
try {
	$dbh = new PDO("sqlite:mescontacts.db");
	$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
	}
catch (PDOException $e){
	die ("Erreur ! " . $e->getMessage());
}
echo '<p>A ce stade, la connection à la base <strong>mescontacts.db</strong> est réussie.</p>';
	// Lecture d'enregistrements
$sql = 'SELECT * FROM contacts ORDER BY nom, prenoms';
$sth = $dbh->query($sql);
if($dbh->query($sql)===FALSE) {
	echo '<p>La requête SQL est erronée</p>';
	echo $sql;
	exit();
}
//  $res = $sth->fetch(PDO::FETCH_BOTH);
var_dump($sth);
foreach($sth as $row) {
	print_r($row);
	echo '<br/>';
}

	// Fermeture de la connexion

$dbh = NULL;
?>
Résultat:
A ce stade, la connection à la base mescontacts.db est réussie.

Warning: PDO::query() [function.PDO-query]: SQLSTATE[HY000]: General error: 1 no such table: contacts in C:\www\dbtutor\sqlite_contacts.php on line 23

Warning: PDO::query() [function.PDO-query]: SQLSTATE[HY000]: General error: 1 no such table: contacts in C:\www\dbtutor\sqlite_contacts.php on line 24

La requête SQL est erronée
SELECT * FROM contacts ORDER BY nom, prenoms
Il va de soi que la base mescontacts.db contient une table contacts de sept champs, accessible par SQL Manager ou en ligne de commande, et que j'y ai placé quelques données tests.

Je précise que lorsque j'active la ligne
$res = $sth->fetch(PDO::FETCH_BOTH);
, sans la détection d'erreur PDO::query() j'obtiens une autre erreur:
Attempt to apply function fetch() on a non-member item
Autre tentative: J'ai aussi déplacé l'appel à la fonction var_dump($sth); pour qu'elle suive immédiatement l'affectation de $sth. Voici le nouvel output d'erreurs:
A ce stade, la connection à la base mescontacts.db est réussie.

Warning: PDO::query() [function.PDO-query]: SQLSTATE[HY000]: General error: 1 no such table: contacts in C:\www\dbtutor\sqlite_contacts.php on line 23

Résultat de var_dump($sth);.......bool(false)

Warning: PDO::query() [function.PDO-query]: SQLSTATE[HY000]: General error: 1 no such table: contacts in C:\www\dbtutor\sqlite_contacts.php on line 27

La requête SQL est erronée
SELECT * FROM contacts ORDER BY nom, prenoms
Dans aucun des bouquins dont je dispose il n'est question de déclarer la structure des données dans une classe, ni d'y développer des méthodes particulières. C'est pourquoi je suis complètement perdu.

MySQL

Je dispose des droits de superU et d'utilisateur lambda, ainsi que les mots de passe appropriés. J'accède à mes tables MySQL par phpmyAdmin ou en ligne de commande.
J'ai exporté cette table mescontacts.db dans MySQL par phpmyAdmin.
J'ai recopié le script ci-dessus dans un second fichier PHP appelé MySQL_contact.php, et j'ai spécifié l'utilisateur et son mot de passe (qui fonctionne avec phpmyAdmin). Cette fois je reçois une erreur de connexion:
Erreur ! SQLSTATE[28000] [1045] Access denied for user 'ODBC'@'localhost' (using password: NO)
Qu'en pensez-vous?

par zeus » 18 juin 2007, 22:42

$sth est le retour de l'exécution de la méthode query() de l'objet $dbh ;)

De plus, j'insite sur mon var_dump() pour savoir ce que retourne cette méthode query().
Tant que nous n'aurons pas cette réponse, nous ne pourrons pas aider notre ami. Je ne sais pas pour vous mais j'aime savoir vers quoi j'emmène quelqu'un quand je lui donne un conseil ;)

par Cyrano » 18 juin 2007, 22:38

Ok, alors revenons un poil en arrière, tu as fais à un moment donné ceci :
$sth = $dbh->query($sql);
$res = $sth->fetch(PDO::FETCH_BOTH);
ça suppose deux choses :
-1- tu utilises un objets distincts, $dbh dans un premier temps, $sth ensuite.
-2- Ton code ne montre aucune des deux instanciations.

Ça implique un problème majeur : tu essayes de récupérer un résultat avec un objet alors que tu as exécuté la requête avec un autre objet...
Il faudrait qu'on voie tes classes d'accès aux données parce que j'avoue que j'ai du mal avec le fonctionnement qui ça sous-entend :-k

par aandre2937 » 18 juin 2007, 20:31

Ok, alors question subsidiaire : est-ce quelqu'un a déjà eu l'idée de t'expliquer ce qu'on appelle des propriétés et des méthodes de classe ? Parce que si ce sont pour toi des termes abstraits voire si tu as l'impression qu'on est des gourous psalmodiant des incantations absconses en regardant des lignes de commande sur des moniteurs en noir et blanc, on est peut-être passé un peu trop rapidement à un stade où tu es largué : en clair, tu as loupé une marche. Quand on descend un escalier, le plus dangereux, c'est de louper la première marche :gla:
Je crois avoir compris, tout au moins les principes fondateurs de la POO, les classes, leurs propriétés et leurs méthodes. J'ai procédé à plusieurs expérimentations intéressantes en suivant les exemples de deux livres : "PHP5 avancé - 3ème édition" et "Je me lance avec PHP et MySQL". C'est pourquoi la POO a récemment déclenché en moi des harmoniques, alors que mon effort de compréhension, avec C++ depuis 1989, puis plus récemment avec Java avait été obéré par des manuels trop théoriques.

Cependant, je n'ai pas encore trouvé dans les moyens tutoriaux à ma portée, en y incluant l'aide en ligne, comment déclarer cette variable qui recueille les données résultant de la lecture de ma table. Je continue à chercher, mais un coup de pouce ne serait pas de refus.

Soyons clair: je n'attends pas de solution toute faite, mais une méthode qui me permette de surmonter ces difficultés passagères et d'aller plus loin.

PS. Un commentaire supplémentaire. Je vais repartir bientôt pour une nouvelle mission de dix huit mois en brousse, avec des liaisons Internet de piètre qualité. Je devrai donc travailler sur place avec mes acquis et mes bouquins, et ne pourrai plus demander d'aide.

Merci d'avoir eu la patience de me lire.

par AB » 18 juin 2007, 20:15

Et sinon, l'erreur vient effectivement de là, mais c'est ce qu'il faut amener notre ami à découvrir par ses propres déductions logiques :-k
J'avais bien remarqué votre démarche mais je me suis permis de faire une suggestion plus directe car la dernière réponse de Zeus datait de presque 3/4 heure. Et je me suis dit qu'il s'était passé suffisamment de temps pour relancer le débat sans compromettre vos efforts didactiques :wink:

par Cyrano » 18 juin 2007, 19:42

Ok, alors question subsidiaire : est-ce quelqu'un a déjà eu l'idée de t'expliquer ce qu'on appelle des propriétés et des méthodes de classe ? Parce que si ce sont pour toi des termes abstraits voire si tu as l'impression qu'on est des gourous psalmodiant des incantations absconses en regardant des lignes de commande sur des moniteurs en noir et blanc, on est peut-être passé un peu trop rapidement à un stade où tu es largué : en clair, tu as loupé une marche. Quand on descend un escalier, le plus dangereux, c'est de louper la première marche :gla:

par aandre2937 » 18 juin 2007, 19:33

As-tu testé ta requête directement avec phpMyAdmin par exemple afin de vérifier la validité de cette requête et sinon voir les messages d'erreur retournés par MySQL ?


Incidemment, j'utilise SQLite pour m'affranchir temporairement des contraintes d'identification rencontrées sur MySQL, et a fortiori postgreSQL. En ligne de commande j'obtiens le résultat voulu, avec SQL Manager aussi. C'est vrai que la table est simplissime et la requête élémentaire.
inspecte ta méthode de classe : est-ce que tu n'as rien oublié quelque part ? Éventuellement, affiche-nous le code de cette méthode ...
Là je ne comprends plus ce qu'il faut faire. Il y a quelques jours, j'avais fait le même essai en programmation procédurale, et j'avais obtenu l'affichage (brut) de ma requête sans déclaration particulière. Comme j'ai progressé dans mon bouquin où l'on explique que la programmation d'avenir est la POO, je cherche à la comprendre, sinon la maîtriser. Je n'ai rien trouvé, dans les exemples que j'ai essayés, qui ressemble à une déclaration de classe et ses méthodes.

par Cyrano » 18 juin 2007, 19:08

On va enlever quelques cailloux de ton chemin ;)

Lorsque tu rencontres un bug dans le déroulement de l'exécution d'un code, il est logique de remonter jusqu'au point où le fonctionnement est normal et attendu : l'erreur se trouve entre ce point et le moment où le résultat ne correspond pas du tout à ce qui a été prévu.

Ta requête retourne false, ok : pourquoi ? As-tu testé ta requête directement avec phpMyAdmin par exemple afin de vérifier la validité de cette requête et sinon voir les messages d'erreur retournés par MySQL ? La requête étant basique, s'il n'y a pas d'erreur sur le nom de la table, alors à ce stade tout est normal et c'est entre l'appel de mysql_query et ton affichage qu'il y a une erreur : inspecte ta méthode de classe : est-ce que tu n'as rien oublié quelque part ?

Éventuellement, affiche-nous le code de cette méthode ...

par aandre2937 » 18 juin 2007, 19:00

Il y a un moment, j'avais essaye, en imitation d'un exemple de PHP5 avancé, de déclarer:
$sth = $dbh->query($sql);
$res = $sth->fetch(PDO::FETCH_BOTH);
Mais le résultat avait été:
Fatal error: Call to a member function fetch() on a non-object in C:\www\dbtutor\sqlite_contacts.php on line 22
Je ne vois vraiment pas comment m'y prendre.

En fait, auparavant, j'utilisais ACCESS. Mais ACCESS est un logiciel propriétaire, et dans les bleds africains où je travaille d'habitude, on n'a pas ACCESS, ou alors c'est qu'il est piraté. C'est pour proposer une alternative libre (et légale) que je passe autant de temps à étudier la mise en oeuvre de xhtml / php/ xxxSQL. Je suis ingénieur sanitaire, et pas informaticien, même si j'ai commencé à coder en 1972.

par Cyrano » 18 juin 2007, 19:00

mysql_fetch_assoc() ou mysql_fetch_row() ou mysql_fetch_array()
Pour quoi faire ? Il utilise une classe de connexion, rien ne nous indique que la méthode appelée ne retourne pas directement un tableau de données : si son code est logique, c'est précisément ce qui devrait se passer. Et sinon, l'erreur vient effectivement de là, mais c'est ce qu'il faut amener notre ami à découvrir par ses propres déductions logiques :-k