db = parent::getInstance(); // connexion } // setters (plusieurs en même temps) public function hydrate(array $data) // $data = tableau associatif en entrée: nom_du_champ => valeur { foreach($data as $key => $value) { // nom d'un setter, forme "setMachin()" $setterName = 'set' . ucfirst($key); // ucfirst met la première lettre en majuscule // détection if(method_exists($this, $setterName)) // on trouve aussi la méthode is_callable() { // on renseigne les propriétés des l'instance $this->$setterName($value); // nom d'une méthode dans une variable } } return($this); } // exécuter le SQL // les attributs correspondent aux ? dans les requêtes préparées // ne pas surcharger la méthode PDO::query() qui n'est pas compatible protected function execQuery(string $sql, array $attributes = null) { $this->db = parent::getInstance(); // connexion if($attributes !== null) // requête préparée { $query = $this->db->prepare($sql); $query->execute($attributes); return $query; } else // requête simple { return $this->db->query($sql); } } // méthodes CRUD // create INSERT public function create() // = write { $fields = []; $question_marks = []; // ? $values = []; foreach($this as $field => $value) { // champs non renseignées et variables de l'objet qui ne sont pas des champs // note: avec le !== (au lieu de !=) une valeur 0 passe le filtre if($value !== null && $field != 'db' && $field != 'table') { $fields[] = $field; // push $question_marks[] = '?'; $values[] = $value; } } $field_list = implode(', ', $fields); $question_mark_list = implode(', ', $question_marks); // INSERT INTO annonces (titre, description, actif) VALUES (?, ?, ?) return($this->execQuery('INSERT INTO ' . $this->table . ' (' . $field_list . ') VALUES (' . $question_mark_list . ')', $values)); } // read SELECT public function readAll() // obtenir une table { $query = $this->execQuery('SELECT * FROM ' . $this->table . ';'); // fonctionne aussi sans le point virgule dans le SQL!! return($query->fetchAll()); } public function findById(int $id) // obtenir une entrée avec son ID { return($this->execQuery('SELECT * FROM ' . $this->table . ' WHERE id = ' . $id)->fetch()); } public function find(array $criteria) // obtenir une entrée avec un tableau associatif 'champ' => 'valeur' { $fields = []; $values = []; // change "'ID' => 2" en "'ID' = ?" et "2" foreach($criteria as $field => $value) { $fields[] = "$field = ?"; // même chose que: $field . " = ?" $values[] = $value; } $field_list = implode(' AND ', $fields); // créer une chaîne reliant les morceaux avec le morceau AND en paramètre: 'adresse = ? AND ID = ?' // SELECT * FROM annonces WHERE actif = 1; return($this->execQuery('SELECT * FROM ' . $this->table . ' WHERE ' . $field_list, $values)->fetchAll()); } // update UPDATE public function update(int $id) { $fields = []; $values = []; foreach($this as $field => $value) { if($value !== null && $field != 'db' && $field != 'table') // champs non renseignées et variables de l'objet qui ne sont pas des champs { $fields[] = $field . ' = ?'; $values[] = $value; } } $values[] = $id; $field_list = implode(', ', $fields); // UPDATE annonces SET titre = ?, description = ?, actif = ? WHERE id= ? return($this->execQuery('UPDATE ' . $this->table . ' SET ' . $field_list . ' WHERE id = ?', $values)); } // delete DELETE public function delete(int $id) { return($this->execQuery("DELETE FROM {$this->table} WHERE id = ?", [$id])); // double quotes "" pour insertion de variable, paramètre [$id] parce qu'on veut un tableau } // fonction appelée une seule fois pour chaque table // le tableau nécessaire n'est pas copié en mémoire à l'instanciation (pas de fuite de mémoire), mais uniquement à l'appel de cette fonction statique, à la fin de la fonction la mémoire est libérée // DBStructure::${self::$tableStructure} permet de nommer une variable statique de classe static public function createTables() { foreach(StructTablesDB::$structureOfTables as $tableName => $oneTable) { //var_dump(StructTablesDB::${self::$tableStructure}); => propriété statique de classe dans une variable $fields_and_types = []; $query = 'CREATE TABLE IF NOT EXISTS ' . $tableName . ' ('; foreach($oneTable as $key => $value) { $fields_and_types[] = $key . ' ' . $value; } $query .= implode(', ', $fields_and_types); // implode() convertit un tableau en une chaîne avec un séparateur entre chaque élément $query .= ', PRIMARY KEY(ID AUTOINCREMENT));'; //echo($query . "\n\n"); parent::getInstance()->exec($query); // merci singleton! } } }