Bonjour,
J'essaye de suivre et de réaliser se tutoriel : https://www.grafikart.fr/formations/programmation-objet-php/tp-backend
Mais je rencontre un problème lors de l'ajout de l'édition ou de la suppression d'un article..
Voici le message d'erreur :
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error' in C:\wamp\www\Blog\core\Database\MysqlDatabase.php on line 68
( ! ) PDOException: SQLSTATE[HY000]: General error in C:\wamp\www\Blog\core\Database\MysqlDatabase.php on line 68
Call Stack
Time Memory Function Location
1 0.0002 147448 {main}( ) ..\admin.php:0
2 0.0018 220816 require( 'C:\wamp\www\Blog\pages\admin\posts\edit.php' ) ..\admin.php:26
3 0.0021 246184 Core\Table\Table->update( ) ..\edit.php:9
4 0.0021 247336 Core\Table\Table->query( ) ..\Table.php:45
5 0.0022 247496 Core\Database\MysqlDatabase->prepare( ) ..\Table.php:85
6 0.0136 261952 fetch ( ) ..\MysqlDatabase.php:68
Si quelqu'un sait pour qu'elle raison cela me fait ça, car je n'arrive pas à trouver.. L'article se supprime bien, s'ajoute bien ou s'édite bien mais à chaque fois que je clique pour sauvegarder ou confirmer l'ajout d'un article ça me renvoi cette erreur.
Ensuite j'ai un deuxième problèmes qui peut surrement être plus simple à résoudre, je m'explique :
J'ai une base de donnée qui est encodé avec utf8_general_ci, si dans mon templates je met l'encodage
<meta charset="utf-8"> tout ce que je récupère sur la BDD est bugué (les accents) et si je ne met pas l'encodage dans mon templates tout va bien, sauf que si j'écris quelque chose avec un accent cela se retrouve bugué..
Merci.
C'est assez étrange qu'il exécute le code alors que la condition n'est pas validée
Penches toi là-dessus, effectivement ce n'est pas normal.
public function prepare($statement, $attributes, $class_name = null, $one = false){
echo 'STATEMENT : ' . $statement . '<br>';
...
if(
echo 'Je suis dans le IF<br>'; die();
strpos($statement, 'UPDATE') === 0 ||
strpos($statement, 'INSERT') === 0 ||
strpos($statement, 'DELETE') === 0
) {
return $res;
}
else {
echo 'Je suis dans le ELSE<br>'; die();
...
}
}
Si tu as un INSERT comme on l'a vu plus haut, c'est impossible qu'on passe dans le ELSE.
Vérifies que tu édite le bon fichier.
On a tous eu des erreurs incompréhensible qui venaient du fait qu'on était sur un fichier du même nom, mais dans un mauvais dossier.
Pour l'encodage, tu peux passer "set names utf8" lors de la connexion ou alors tu fais une query "set names utf8" juste après la connexion.
le mieux c'est ça
$strConnection = "mysql:host=$db_host;dbname=$db_base";
$arrExtraParam= array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8");
try {
$pdo = new PDO($strConnection, $db_user, $db_pwd, $arrExtraParam);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch( PDOException $e) {
$msg = 'ERREUR PDO dans ' . $e->getFile() . ' L.' . $e->getLine() . ' : ' . $e->getMessage();
}
public function prepare($statement, $attributes, $class_name = null, $one = false){
$req = $this->getPDO()->prepare($statement);
$res = $req->execute($attributes);
if(
strpos($statement, 'UPDATE') === 0 ||
strpos($statement, 'INSERT') === 0 ||
strpos($statement, 'DELETE') === 0
) {
return $res;
}
if($class_name === null){
$req->setFetchMode(PDO::FETCH_OBJ);
} else{
$req->setFetchMode(PDO::FETCH_CLASS, $class_name);
}
if($one){
$datas = $req->fetch();
} else{
$datas = $req->fetchAll();
}
return $datas;
}
La ligne 68 est celle-ci : $datas = $req->fetch();
Tu dis vouloir ajouter un enregistrement et tu fais un fetch ????
A trop vouloir encapsuler, on cache la complexité et on appelle une fonction "prepare" sans vraiment savoir ce quelle fait
@Carouge10 oui mais il dit vouloir faire un INSERT ou un DELETE
il faudrait faire un stripos plutot qu'un strpos pour intercepter le "insert" "INSERT" "delete "DELETE"
Salut,
la fonction "prepare" semble correcte (avec stripos peut-être)
On peut voir la requête SQL ?
Avec le reste tant qu'a faire.
public function prepare($statement, $attributes, $class_name = null, $one = false){
echo 'STATEMENT : ' . $statement . '<br>';
echo 'ATTRIBUTES : <br>';
echo '<pre>';
print_r($attributes);
echo '</pre>';
echo 'CLASSE_NAME : ';
var_dump($class_name);
echo 'ONE : ';
var_dump($one);
die();
...
}
J'ai mal compris ici, on dirait que tu te contredis :
L'article se supprime bien, s'ajoute bien ou s'édite bien
mais à chaque fois que je clique pour sauvegarder ou confirmer l'ajout d'un article ça me renvoi cette erreur.
Salut,
Tout d'abord merci pour vos réponses, ensuite je sais que c'est bizarre mais je vais essayer d'expliquer clairement le moment où je reçoi l'erreur :
Je suis sur ma page admin.php qui me redirige vers index.php. Dans la page index.php j'ai un tableau avec mes differents articles qui sont enregistrés sur la BDD Mysql et je vais les cherchers avec un foreach. Jusque la tout va bien. Ensuite pour chaques articles j'ai un bouton Editer et au dessus de mon tableau un bouton pour Ajouter un article. Les deux fonctionnent très bien et me redirige chacun surl a bonne page. Si par exemple je veux Ajouter un article, je met mon titre.. mon contenu et je choisi ma catégorie jusqu'ici tout va bien aussi.
Mais au moment où je clique sur le bouton pour valider l'article, donc, pour qu'il s'ajoute aux autres j'ai ce fameu message d'erreur que j'ai cité au dessus à la ligne 68 de mon MysqlDatabase.php et ça me fait exactement pareil pour mon bouton Editer au moment où je clique sur le bouton pour sauvegarder après avoir modifier le titre de l'article ou son contenu
N'empèche que les articles s'ajoutent bien ou se modifient bien si je réactualise la page...
@SLK
J'ai fait ce que tu m'as demandé pour l'ajout d'un article voici le résultat :
STATEMENT : INSERT INTO articles SET titre = ?, contenu = ?, category_id = ?
ATTRIBUTES :
Array
(
[0] => Titre de TEST
[1] => Contenu de TEST
[2] => 1
)
CLASSE_NAME :
string 'App\Entity\PostEntity' (length=21)
ONE :
boolean true
Merci.
Ah mais non en fait la fonction prepare n'était pas bonne. Je viens de m'en apercevoir...
Si la requête n'est PAS un SELECT, il ne faut PAS exécuter le code avec le setFetchMode() et le fetch() (ou fetchAll)
Il faut mettre un ELSE, de cette façon :
public function prepare($statement, $attributes, $class_name = null, $one = false){
$req = $this->getPDO()->prepare($statement);
$res = $req->execute($attributes);
// SI la requête n'est PAS un "SELECT"
if(
strpos($statement, 'UPDATE') === 0 ||
strpos($statement, 'INSERT') === 0 ||
strpos($statement, 'DELETE') === 0
) {
return $res;
}
else { // SINON on exécute le code suivant, qui ne doit s'exécuter QUE dans le cas d'un SELECT (d'où le ELSE)
if($class_name === null){
$req->setFetchMode(PDO::FETCH_OBJ);
} else{
$req->setFetchMode(PDO::FETCH_CLASS, $class_name);
}
if($one){
$datas = $req->fetch();
} else{
$datas = $req->fetchAll();
}
return $datas;
}
}
Malheureusement ça me fait exactement la même erreur, mais en mettant toute cette partie en commentaire ça marche...
// if($one){
// $datas = $req->fetch();
// } else{
// $datas = $req->fetchAll();
// }
//return $datas;
C'est assez étrange qu'il exécute le code alors que la condition n'est pas validée
EDIT :
J'ai un deuxième problème, celui par rapport à l'encodage :
Ma BDD est encodé en utf8_general_ci et le moteur mysam, quand je récupère le contenu des articles sur ma page et que j'ai la ligne de code : <meta charset="utf-8"> dans l'entête ça bug tous les caractères avec des accents, si j'enlève la ligne de code <meta charset="utf-8"> de l'entête tout remarche, sauf que c'est les accents qui sont sur le code html qui sont bugué... Si c'est mal expliqué j'expliquerai avec un screen :)
D'accord merci beaucoup !
Et du coup pour mon problème d'encodage quelqu'un sait pourquoi cela me fait ça ?
Merci beaucoup au moins l'encodage marche, je vais essayer de me débrouiller pour cette histoire de boucle..