Commentaires
Tu connais les grands types d'opérations que l'on peut faire sur une base de données?

Arthur, l'apprenti développeurLe CRUD?

Oui, ça nous donne donc quatre opérations de base :

  • la lecture

  • L'écriture

  • La modification

  • La suppression


Et en SQL on retrouve ces quatre opération

Arthur, l'apprenti développeurOui ça je connais :

  • SELECT

  • INSERT

  • UPDATE

  • DELETE

J'ajouterai un petit détail, pour le SELECT, on va avoir deux cas :


  • Récupération de toute la table

  • Récupération d'un seul élément par son identifiant



Arthur, l'apprenti développeurOk donc il faut que je fasse 5 méthodes :

  • getById

  • getAll

  • Create

  • Update

  • Delete



C'est exactement ça, mais attention, il faut que ces méthodes soient générique, pour fonctionner quelque soit la table ! D'autre part, il serait idéal qu'elles puissent transformer un résultat de requête SELECT en objet ou tableau d'objet, et inversement, utiliser un objet pour l'intégrer dans une requête INSERT, UPDATE ou DELETE. Mais commence donc par écrire la classe, prévoit les propriétés qui te parraissent indispensable, et les méthodes vides, on va procéder étape par étape.

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseManager\n\t{\n\t\tprivate $_table;\n\t\tprivate $_object;\n\t\t\n\t\tpublic function __construct()\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function getById($id)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function getAll()\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function create($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function update($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function delete($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t}","filename":"BaseManager.php"}


C'est un bon début, on va d'abord s'occuper du constructeur. Il y a plusieurs éléments à prévoir, déjà pouvoir renseigner un nom de table et un nom d'objet quand on construit un manager. Mais il faudra aussi pouvoir récupérer une instance de notre classe BDD en lui passant la chaine de connexion, et conserver cette instance. Pense bien que cette instance pourra être très utile pour les manager qui héritent du BaseManager !

Arthur, l'apprenti développeurC'est clair pour moi ça!

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseManager\n\t{\n\t\tprivate $_table;\n\t\tprivate $_object;\n\t\tprotected $_bdd;\n\t\t\n\t\tpublic function __construct($table,$object,$datasource)\n\t\t{\n\t\t\t$this->_table = $table;\n\t\t\t$this->_object = $object;\n\t\t\t$this->_bdd = BDD::getInstance($datasource);\n\t\t}\n\t\t\n\t\tpublic function getById($id)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function getAll()\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function create($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function update($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function delete($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t}","filename":"BaseManager.php"}


Très bien, on va commencer par la requête la plus simple, getAll, il suffit de faire une requête SELECT sur la table prédéfinis.

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseManager\n\t{\n\t\tprivate $_table;\n\t\tprivate $_object;\n\t\tprotected $_bdd;\n\t\t\n\t\tpublic function __construct($table,$object,$datasource)\n\t\t{\n\t\t\t$this->_table = $table;\n\t\t\t$this->_object = $object;\n\t\t\t$this->_bdd = BDD::getInstance($datasource);\n\t\t}\n\t\t\n\t\tpublic function getById($id)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function getAll()\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table);\n\t\t\t$req->execute();\n\t\t\t$resultat = $req->fetchAll();\n\t\t}\n\t\t\n\t\tpublic function create($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function update($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function delete($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t}","filename":"BaseManager.php"}


parfait, par contre, on va retourner directement le fetchAll plutôt que de le stocker dans une variable, ce n'est pas grand chose, mais ça réduit la consomation mémoire du serveur.
Et d'autre part on va utiliser setFetchMode, qui permet de modifier la façon de parcourir les résultat. Si tu regarde bien la doc, tu verras que l'on peut utiliser FETCH_CLASS, pour qu'il transforme chaque ligne de résultat en un objet de notre choix. Il faudra aussi préciser FETCH_PROPS_LATE, ainsi le fetch va dans un premier temps appeler le constructeur de notre classe, puis dans un deuxième temps réecrire ses valeurs par les résultats de la requête.

Pour te donner un exemple, si on requête une table user et que l'on souhaite transformer le résultat de requête en objet User, il faudra préciser avant le fetchAll :
{"language":"application/x-httpd-php","content":"<?php\n$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,\"User\");","filename":"BaseManager.php"}


il faudra faire attention par la suite, que les noms de colonne correspondent exactement aux noms des propriétés de l'objet, sinon le fetch ne saura pas quelles propriétés assigner.

Arthur, l'apprenti développeurJe pense que j'ai tout compris, je vais modifier ça et faire le getById en même temps.

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseManager\n\t{\n\t\tprivate $_table;\n\t\tprivate $_object;\n\t\tprotected $_bdd;\n\t\t\n\t\tpublic function __construct($table,$object,$datasource)\n\t\t{\n\t\t\t$this->_table = $table;\n\t\t\t$this->_object = $object;\n\t\t\t$this->_bdd = BDD::getInstance($datasource);\n\t\t}\n\t\t\n\t\tpublic function getById($id)\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t$req->execute(array($id));\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetch();\n\t\t}\n\t\t\n\t\tpublic function getAll()\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table);\n\t\t\t$req->execute();\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetchAll();\n\t\t}\n\t\t\n\t\tpublic function create($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function update($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function delete($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t}","filename":"BaseManager.php"}


C'est exactement ça ! Maintenant le delete.

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseManager\n\t{\n\t\tprivate $_table;\n\t\tprivate $_object;\n\t\tprotected $_bdd;\n\t\t\n\t\tpublic function __construct($table,$object,$datasource)\n\t\t{\n\t\t\t$this->_table = $table;\n\t\t\t$this->_object = $object;\n\t\t\t$this->_bdd = BDD::getInstance($datasource);\n\t\t}\n\t\t\n\t\tpublic function getById($id)\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t$req->execute(array($id));\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetch();\n\t\t}\n\t\t\n\t\tpublic function getAll()\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table);\n\t\t\t$req->execute();\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetchAll();\n\t\t}\n\t\t\n\t\tpublic function create($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function update($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function delete($obj)\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"DELETE FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\treturn $req->execute(array($obj->id));\n\t\t}\n\t}","filename":"BaseManager.php"}


Tu as bien compris le concept, par contre il faut faire attention, si jamais la propriété id n'existe pas dans l'objet, tu va avoir une erreur dans ton code, tu peux utiliser la fonction property-exists pour vérifier ça.

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseManager\n\t{\n\t\tprivate $_table;\n\t\tprivate $_object;\n\t\tprotected $_bdd;\n\t\t\n\t\tpublic function __construct($table,$object,$datasource)\n\t\t{\n\t\t\t$this->_table = $table;\n\t\t\t$this->_object = $object;\n\t\t\t$this->_bdd = BDD::getInstance($datasource);\n\t\t}\n\t\t\n\t\tpublic function getById($id)\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t$req->execute(array($id));\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetch();\n\t\t}\n\t\t\n\t\tpublic function getAll()\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table);\n\t\t\t$req->execute();\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetchAll();\n\t\t}\n\t\t\n\t\tpublic function create($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function update($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function delete($obj)\n\t\t{\n\t\t\tif(property_exists($obj,\"id\"))\n\t\t\t{\n\t\t\t\t$req = $_bdd->prepare(\"DELETE FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t\treturn $req->execute(array($obj->id));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new PropertyNotFoundException();\t\n\t\t\t}\n\t\t}\n\t}","filename":"baseManager.php"}


Très bon réflexe l'exception, je vois que tu prend les bonnes habitudes ! Je te propose même que l'on aille plus loin sur cette exception en précisant la classe testée et la propriété manquante dans notre exception, comme ça on pourra afficher un message d'erreur plus précis par la suite. Je te fournis la classe d'exception toute faite, et cette fois c'est à toi de trouver comment l'utiliser dans ton BaseManager.


{"language":"application/x-httpd-php","content":"<?php\n class PropertyNotFoundException extends Exception\n {\n private $_className;\n\t\tprivate $_property;\n\n public function __construct($className,$property,$message = \"Property missing\")\n {\n\t\t\t$this->_className = $className;\n $this->_property = $property;\n parent::__construct($message,'0040');\n }\n\n public function getMoreDetail()\n {\n return \"Property \" . $this->_property . \" does not exist in class \" . $this->_className;\n }\n }","filename":"PropertyNotFoundException .php"}


Arthur, l'apprenti développeurFacile !

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseManager\n\t{\n\t\tprivate $_table;\n\t\tprivate $_object;\n\t\tprotected $_bdd;\n\t\t\n\t\tpublic function __construct($table,$object,$datasource)\n\t\t{\n\t\t\t$this->_table = $table;\n\t\t\t$this->_object = $object;\n\t\t\t$this->_bdd = BDD::getInstance($datasource);\n\t\t}\n\t\t\n\t\tpublic function getById($id)\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t$req->execute(array($id));\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetch();\n\t\t}\n\t\t\n\t\tpublic function getAll()\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table);\n\t\t\t$req->execute();\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetchAll();\n\t\t}\n\t\t\n\t\tpublic function create($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function update($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function delete($obj)\n\t\t{\n\t\t\tif(property_exists($obj,\"id\"))\n\t\t\t{\n\t\t\t\t$req = $_bdd->prepare(\"DELETE FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t\treturn $req->execute(array($obj->id));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new PropertyNotFoundException($this->_object,\"id\");\t\n\t\t\t}\n\t\t}\n\t}","filename":"BaseManager.php"}


Parfait, il ne reste plus qu'à s'occuper des méthodes create et update, c'est un peu plus compliqué, mais ne t'inquiète pas on va y arriver. Pour ces deux méthodes, il faut bien penser qu'on ne peut pas utiliser le selecteur * comme on peut le faire dans une requête SELECT, il va donc falloir prévoir un paramètre en plus pour indiquer les champs que l'on souhaite mettre à jour.

Arthur, l'apprenti développeurJusque là je te suis.

Et il faudra ensuite décomposer ce tableau de champ, pour construire la requête et lui passer des paramètres. Pour rappel, voici un petit exemple de requête SQL pour INSERT et UPDATE.

{"language":"text/x-sql","content":"INSERT INTO myTable(col1,col2,col3) VALUES(?,?,?)\nUPDATE myTable SET col1=?, col2=?, col3=? WHERE id=?","filename":"exemple"}


Pour t'aider, tu peux te servir de la fonction implode qui rassemble les éléments d'un tableau avec un séparateur, de array_fill pour remplir un nouveau tableau avec une chaîne prédéfinie, et count pour connaitre le nombre d'éléments d'un tableau.

Arthur, l'apprenti développeurJe ne vois pas trop où tu veux en venir avec ces fonctions...

On va procéder étape par étape, en commençant juste par la fonction create, qui a deux paramètre, le premier est l'objet à mettre à jour en base, et le deuxième un tableau avec les colonne à mettre à jour. Pour rappel les propriétés de l'objet porteront exactement le même nom que les colonne en base.

Arthur, l'apprenti développeurJusque là je te suis.

Il va y avoir une partie de la requête qui est fixe, c'est INSERT INTO mytable, avec bien entendu le nom de la table comme tu l'as fait pour les requêtes SELECT.

Arthur, l'apprenti développeurOui

Une deuxième partie avec entre parenthèse, le nom des colonnes à mettre à jour, séparé par une virgule.

Arthur, l'apprenti développeurTout à fait

Et bien la fonction implode permet de prendre un tableau, et de concaténer les éléments du tableau les uns après les autres, en ajoutant un caractère de séparation.

Arthur, l'apprenti développeurAh là je vois, quelque chose comme ça :

{"language":"application/x-httpd-php","content":"<?php\n\t$param = array(\"col1\",\"col2\",\"col3\");\n\timplode($array,\", \");","filename":"exemple"}


C'est ça, et ensuite, il y a une dernière partie de la requête, dans laquelle il faut mettre un point d’interrogation pour chaque propriété du tableau de paramètre, et les séparer par une virgule.

Arthur, l'apprenti développeurJe te suis toujours

count va permettre de compter le nombre de paramètre qu'il y a dans ce tableau.
array_fill crée un nouveau tableau, avec x cases, x étant une variable que l'on peut préciser, avec le nombre retourner par count par exemple, et tu peux lui préciser un élément de ton choix pour remplir chaque case, ce sera le même à chaque fois, comme un point d'interrogation par exemple.

Arthur, l'apprenti développeurAh je crois que je viens de comprendre, et on réutilise implode sur ce tableau pour créer exactement le bon nombre de point d'interrogation !

Exactement

{"language":"application/x-httpd-php","content":"<?php\n\t$param = array(\"col1\",\"col2\",\"col3\");\n\t$paramNumber = count($param);\n\t$valueArray = array_fill(0,$param_number,\"?\");\n\t$valueString = implode($valueArray,\", \");","filename":"exemple"}


C'est presque ça, le soucis est que si tu as 5 éléments dans ta liste, le array_fill tel que tu l'as paramétrer va commencer à 0, et s'arrêter à 5 ce qui fait un total de 6 éléments => 0,1,2,3,4,5
Or nous n'en voulons dans ce cas que 5, donc il faut soit commencer le tableau à la case 1, soit l'arrêter à count-1;

Et sinon, concernant les variables renseigner à chaque instruction c'est un choix, si tu préfères comme ça, tu peux le laisser, mais personnellement, j'évite de créer une variable si je ne m'en sers qu'une seule fois à la ligne suivante, pour des raisons de performance. Donc le code serais plutôt :

{"language":"application/x-httpd-php","content":"<?php\n\t$param = array(\"col1\",\"col2\",\"col3\");\n\t$valueString = implode(array_fill(1,count($param),\"?\"),\", \");","filename":"exemple"}


Arthur, l'apprenti développeurWoh, mais c'est beaucoup plus difficile à lire comme ça !

Effectivement c'est un peu plus compliqué, après c'est une question d'habitude, mais je ne vais pas te forcer à faire de même, si le code est plus clair pour toi sur plisieurs ligne avec des variables, laisse le comme ça, tu verras plus tard avec plus d’expérience si tu souhaites le factoriser plus.

Arthur, l'apprenti développeurOui je t'avoue que je préfère le laisse sur plusieurs lignes c'est plus clair pour moi. Donc je vais essayer de faire le create du BaseManager avec tout ces éléments.

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseManager\n\t{\n\t\tprivate $_table;\n\t\tprivate $_object;\n\t\tprotected $_bdd;\n\t\t\n\t\tpublic function __construct($table,$object,$datasource)\n\t\t{\n\t\t\t$this->_table = $table;\n\t\t\t$this->_object = $object;\n\t\t\t$this->_bdd = BDD::getInstance($datasource);\n\t\t}\n\t\t\n\t\tpublic function getById($id)\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t$req->execute(array($id));\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetch();\n\t\t}\n\t\t\n\t\tpublic function getAll()\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table);\n\t\t\t$req->execute();\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetchAll();\n\t\t}\n\t\t\n\t\tpublic function create($obj,$param)\n\t\t{\n\t\t\t\n\t\t\t$paramNumber = count($param);\n\t\t\t$valueArray = array_fill(1,$param_number,\"?\");\n\t\t\t$valueString = implode($valueArray,\", \");\n\t\t\t$sql = \"INSERT INTO \" . $this->_table . \"(\" . implode($param,\", \") . \") VALUES(\" . $valueString . \")\";\n\t\t\t$req = $_bdd->prepare($sql);\n\t\t\t$req->execute($param);\n\t\t}\n\t\t\n\t\tpublic function update($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function delete($obj)\n\t\t{\n\t\t\tif(property_exists($obj,\"id\"))\n\t\t\t{\n\t\t\t\t$req = $_bdd->prepare(\"DELETE FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t\treturn $req->execute(array($obj->id));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new PropertyNotFoundException($this->_object,\"id\");\t\n\t\t\t}\n\t\t}\n\t}","filename":"BaseManager.php"}


C'est presque ça, le problème se situe au niveau de execute, tu lui a passé $param, sauf que je te rappelle que c'est le tableau qui contiens le nom des colonnes à mettre à jour et non pas les valeurs.

Arthur, l'apprenti développeurDonc il faut lui passer $obj?

Pas tout à fait, execute attend un tableau avec le nombre exact de paramètre prévu dans la requête et dans le bon ordre, alors que $obj est un objet qui contiens toutes les propriétés. Il va falloir créer un tableau à partir de param, en précisant les valeurs associés dans obj. L'astuce est d'utiliser un nom de propriété dynamique, par exemple pour accéder à la propriété title d'un objet tu peux faire :

{"language":"application/x-httpd-php","content":"<?php\n$propertyName = \"title\";\n$obj->$title;","filename":"exemple"}


Arthur, l'apprenti développeurAh je pense que je sais faire ça.

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseManager\n\t{\n\t\tprivate $_table;\n\t\tprivate $_object;\n\t\tprotected $_bdd;\n\t\t\n\t\tpublic function __construct($table,$object,$datasource)\n\t\t{\n\t\t\t$this->_table = $table;\n\t\t\t$this->_object = $object;\n\t\t\t$this->_bdd = BDD::getInstance($datasource);\n\t\t}\n\t\t\n\t\tpublic function getById($id)\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t$req->execute(array($id));\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetch();\n\t\t}\n\t\t\n\t\tpublic function getAll()\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table);\n\t\t\t$req->execute();\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetchAll();\n\t\t}\n\t\t\n\t\tpublic function create($obj,$param)\n\t\t{\n\t\t\t\n\t\t\t$paramNumber = count($param);\n\t\t\t$valueArray = array_fill(1,$param_number,\"?\");\n\t\t\t$valueString = implode($valueArray,\", \");\n\t\t\t$sql = \"INSERT INTO \" . $this->_table . \"(\" . implode($param,\", \") . \") VALUES(\" . $valueString . \")\";\n\t\t\t$req = $_bdd->prepare($sql);\n\t\t\t$boundParam = array();\n\t\t\tforeach($param as $paramName)\n\t\t\t{\n\t\t\t\t$boundParam[$paramName] = $obj->$paramName;\t\n\t\t\t}\n\t\t\t$req->execute($boundParam);\n\t\t}\n\t\t\n\t\tpublic function update($obj)\n\t\t{\n\t\t\t\n\t\t}\n\t\t\n\t\tpublic function delete($obj)\n\t\t{\n\t\t\tif(property_exists($obj,\"id\"))\n\t\t\t{\n\t\t\t\t$req = $_bdd->prepare(\"DELETE FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t\treturn $req->execute(array($obj->id));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new PropertyNotFoundException($this->_object,\"id\");\t\n\t\t\t}\n\t\t}\n\t}","filename":"BaseManager.php"}


Parfait, reste à faire l'update, on va réutiliser certaines fonction de l'include, je te laisse deviner. Le but étant que la requête généré ressemble à :

{"language":"text/x-sql","content":"UPDATE myTable SET col1 = ?, col2 = ?, col3= ? WHERE id = ?","filename":"exemple"}


Arthur, l'apprenti développeurJe doit pouvoir faire ça maintenant.

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseManager\n\t{\n\t\tprivate $_table;\n\t\tprivate $_object;\n\t\tprotected $_bdd;\n\t\t\n\t\tpublic function __construct($table,$object,$datasource)\n\t\t{\n\t\t\t$this->_table = $table;\n\t\t\t$this->_object = $object;\n\t\t\t$this->_bdd = BDD::getInstance($datasource);\n\t\t}\n\t\t\n\t\tpublic function getById($id)\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t$req->execute(array($id));\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetch();\n\t\t}\n\t\t\n\t\tpublic function getAll()\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table);\n\t\t\t$req->execute();\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetchAll();\n\t\t}\n\t\t\n\t\tpublic function create($obj,$param)\n\t\t{\n\t\t\t\n\t\t\t$paramNumber = count($param);\n\t\t\t$valueArray = array_fill(1,$param_number,\"?\");\n\t\t\t$valueString = implode($valueArray,\", \");\n\t\t\t$sql = \"INSERT INTO \" . $this->_table . \"(\" . implode($param,\", \") . \") VALUES(\" . $valueString . \")\";\n\t\t\t$req = $_bdd->prepare($sql);\n\t\t\t$boundParam = array();\n\t\t\tforeach($param as $paramName)\n\t\t\t{\n\t\t\t\t$boundParam[$paramName] = $obj->$paramName;\t\n\t\t\t}\n\t\t\t$req->execute($boundParam);\n\t\t}\n\t\t\n\t\tpublic function update($obj,$param)\n\t\t{\n\t\t\t$sql = \"UPDATE \" . $this->_table . \" SET \";\n\t\t\tforeach($param as $paramName)\n\t\t\t{\n\t\t\t\t$sql = $sql . $paramName . \" = ?, \";\n\t\t\t}\n\t\t\t$sql = $sql . \" WHERE id = ? \";\n\t\t\t$req = $_bdd->prepare($sql);\n\t\t\t\n\t\t\t$boundParam = array();\n\t\t\tforeach($param as $paramName)\n\t\t\t{\n\t\t\t\t$boundParam[$paramName] = $obj->$paramName;\t\n\t\t\t}\n\t\t\t\n\t\t\t$req->execute($boudParam);\n\t\t}\n\t\t\n\t\tpublic function delete($obj)\n\t\t{\n\t\t\tif(property_exists($obj,\"id\"))\n\t\t\t{\n\t\t\t\t$req = $_bdd->prepare(\"DELETE FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t\treturn $req->execute(array($obj->id));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new PropertyNotFoundException($this->_object,\"id\");\t\n\t\t\t}\n\t\t}\n\t}","filename":"BaseManager.php"}


C'est presque ça ! Il y a troisdétails à améliorer pour que ce soit parfait. D'abord, il y a un paramètre en plus dans cette requête, l'id précisé dans la clause WHERE, il faut penser à l'ajouter au $boundParam avant de le passer à execute.
Et sinon, sais tu qu'il y a un opérateur de concaténation avec = qui pourrait te faciliter le travail? Je te donne un exemple :

{"language":"application/x-httpd-php","content":"<?php\n\t$string = \"Hello\";\n\t$string = $string . \" World\";\n\t$string .= \" World\";","filename":"exemple"}


Dens cet exemple, la ligne 3 et la ligne 4 vont avoir un comportement strictement identique. En fait utiliser l'opérateur .= reviens à dire, concatène ça après ce qui est déjà dans ma variable.

Arthur, l'apprenti développeurAh c'est pratique ça !

Et enfin, tu n'as fait aucune vérification sur l'existence des paramètres ni dans le create ni dans l'update, il serait préférable de le faire comme pour delete.

Arthur, l'apprenti développeurOk je fait tout ça.

{"language":"application/x-httpd-php","content":"<?php\n\tclass BaseManager\n\t{\n\t\tprivate $_table;\n\t\tprivate $_object;\n\t\tprotected $_bdd;\n\t\t\n\t\tpublic function __construct($table,$object,$datasource)\n\t\t{\n\t\t\t$this->_table = $table;\n\t\t\t$this->_object = $object;\n\t\t\t$this->_bdd = BDD::getInstance($datasource);\n\t\t}\n\t\t\n\t\tpublic function getById($id)\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t$req->execute(array($id));\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetch();\n\t\t}\n\t\t\n\t\tpublic function getAll()\n\t\t{\n\t\t\t$req = $_bdd->prepare(\"SELECT * FROM \" . $this->_table);\n\t\t\t$req->execute();\n\t\t\t$req->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE,$this->_obj);\n\t\t\treturn $req->fetchAll();\n\t\t}\n\t\t\n\t\tpublic function create($obj,$param)\n\t\t{\n\t\t\t\n\t\t\t$paramNumber = count($param);\n\t\t\t$valueArray = array_fill(1,$param_number,\"?\");\n\t\t\t$valueString = implode($valueArray,\", \");\n\t\t\t$sql = \"INSERT INTO \" . $this->_table . \"(\" . implode($param,\", \") . \") VALUES(\" . $valueString . \")\";\n\t\t\t$req = $_bdd->prepare($sql);\n\t\t\t$boundParam = array();\n\t\t\tforeach($param as $paramName)\n\t\t\t{\n\t\t\t\tif(property_exists($obj,$paramName))\n\t\t\t\t{\n\t\t\t\t\t$boundParam[$paramName] = $obj->$paramName;\t\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new PropertyNotFoundException($this->_object,$paramName);\t\n\t\t\t\t}\n\t\t\t}\n\t\t\t$req->execute($boundParam);\n\t\t}\n\t\t\n\t\tpublic function update($obj,$param)\n\t\t{\n\t\t\t$sql = \"UPDATE \" . $this->_table . \" SET \";\n\t\t\tforeach($param as $paramName)\n\t\t\t{\n\t\t\t\t$sql = $sql . $paramName . \" = ?, \";\n\t\t\t}\n\t\t\t$sql = $sql . \" WHERE id = ? \";\n\t\t\t$req = $_bdd->prepare($sql);\n\t\t\t\n\t\t\t$param[] = 'id';\n\t\t\t$boundParam = array();\n\t\t\tforeach($param as $paramName)\n\t\t\t{\n\t\t\t\tif(property_exists($obj,$paramName))\n\t\t\t\t{\n\t\t\t\t\t$boundParam[$paramName] = $obj->$paramName;\t\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new PropertyNotFoundException($this->_object,$paramName);\t\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t$req->execute($boudParam);\n\t\t}\n\t\t\n\t\tpublic function delete($obj)\n\t\t{\n\t\t\tif(property_exists($obj,\"id\"))\n\t\t\t{\n\t\t\t\t$req = $_bdd->prepare(\"DELETE FROM \" . $this->_table . \" WHERE id=?\");\n\t\t\t\treturn $req->execute(array($obj->id));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new PropertyNotFoundException($obj,\"id\");\t\n\t\t\t}\n\t\t}\n\t}","filename":"BaseManager.php"}


Parfait, notre BaseManager est prêt ! On va commencer à s'en servir maintenant. J'ai terminé cette partie
Demander de l'assistance