Créer son framework PHP Objet
https://chierchia.fr/blog/2016/01/creer-son-framework-php-objetPour faire suite à un article que j’avais écrit il y a un peu plus de quatre ans maintenant sur la création d’un framework PHP, je vous propose de créer un framework PHP Objet en utilisant les principes MVC.
Lorsque je travaillais encore chez CBC Informatique, nous n’utilisions pas les principes de la programmation orientée Objet et nous préférions développer nous même les sites Web de nos clients plutôt que de s’appuyer sur des solutions toutes faites, afin de garder la maitrise de notre code. C’est dans cette optique que j’avais développé notre mini-framework/CMS.
Depuis presque 1 an maintenant, je travaille chez Ibakus Europe et à nouvelle équipe nouvelle façon de travailler. Pour concevoir les nouvelles applications Web IBAKUS, nous utilisons la programmation orientée Objet et les principes du MVC. Nos applications gérant des données plutôt sensibles, il a été décidé de développer notre propre framework PHP Objet, afin de garder au maximum la main sur le code et pouvoir le modifier plus facilement.
Les bases du framework PHP Objet
D’abord, nous avons écrit une classe maîtresse que l’on a appelée Container. Elle nous permet entre autre d’initialiser le framework avec un fichier de configuration, de définir les différentes routes et de charger les différents Modèles et Contrôleurs.
Une classe abstraite Model définit les méthodes utilisées pour agir sur la base de données puis chacun de nos modèles étendent cette classe afin de gérer les spécificités qui leur sont propres.
Mon but n’étant pas de publier le code source de notre framework, je m’intéresserai uniquement aux méthodes CRUD de notre classe abstraite Model.
Structure de la classe abstraite Model
La classe abstraite Model est définie par deux propriétés $db
et $table
et cinq méthodes : get()
, getDatas()
, set()
, delete()
et save()
.
La propriété $db
est une instance de la classe PDO établissant la connexion à notre base de données, $table
quand à elle contient le nom de la table sur laquelle les opérations des méthodes save()
et delete()
vont être faites. Voici la structure de notre classe :
abstract class Model {
protected $db;
protected $table;
public function __construct() {
$this -> db = Container::getDb();
$this -> table = $this;
}
/**
* Un echo de $this retournera le nom de la table associée au modèle.
* Par exemple 'pages' pour le modèle 'PagesModel'
*/
public function __toString() {
return strtolower(substr(get_class($this), 0, -5));
}
// GETTERS
public function get($attr) {
return $this -> $attr;
}
/**
* Retourne tous les attributs de l'objet
*/
public function getDatas() {
$datas = array();
foreach (get_object_vars($this) as $key => $value)
$datas[$key] = $value;
return $datas;
}
// SETTER
public function set($attr, $data) {
if (property_exists($this, $attr)
$this -> $attr = $data;
}
// METHODES
public function delete() {}
public function save() {}
}
La méthode save()
cette méthode permet d’enregistrer l’objet dans la base de données, que ce soit pour son insertion ou lors de sa modification. Pour définir si l’on va faire un INSERT
ou un UPDATE
, on testera la valeur de l’attribut id
de l’objet courant. Si elle n’est pas nulle on souhaite modifier l’objet, sinon on crée une nouvelle entrée dans la base.
public function save($type = null) {
if ($this -> get('id') == null) {
$query = 'INSERT INTO ' . $this -> get('table') . ' SET';
$nbDatas = count($this -> getDatas());
$i = 0;
foreach ($this -> getDatas() as $key => $value) {
$i++;
$query .= ' ' . $key . ' = :' . $key;
if ($i < $nbDatas)
$query .= ',';
else
$query .= ';';
}
} else {
$query = 'UPDATE ' . $this -> get('table') . ' SET';
$nbDatas = count($this -> getDatas());
$i = 0;
foreach ($this -> getDatas() as $key => $value) {
$i++;
if ($key != 'id') {
$query .= ' ' . $key . ' = :' . $key;
if ($i < $nbDatas)
$query .= ',';
}
} $query .= ' WHERE id = :id;';
}
$query = $this -> get('db') -> prepare($query);
foreach ($this -> getDatas() as $key => $value)
$query -> bindValue(':' . $key, $value);
$executed = $query -> execute();
if ($executed && $this -> get('id') == null)
$this -> set('id', $this -> get('db') -> lastInsertId());
return $executed;
}
La méthode delete()
Pour supprimer les données de l’objet enregistré, rien de vraiment compliqué, on execute simplement une requête préparée avec la classe PDO et on supprime l’enregistrement dont id
correspond à l’attribut id
de l’objet courant.
public function delete() {
$query = $this -> get('db') -> prepare('DELETE FROM ' . $this -> get('table') . ' WHERE id = :id;');
$query -> bindValue(':id', $this -> get('id'));
return $query -> execute();
}
Pour finir : construire un CMS
Construire un CMS sur base d’une classe abstraite comme celle-ci permet d’écrire très simplement les différents modules dont on aura besoin.
Si l’on souhaite gérer des pages de contenu, il suffira d’écrire un modèle héritant de la classe Model, par exemple pagesModel et d’y définir les attributs de l’objet en regard de la structure de la table pages de la base de données.
Cette classe héritant de la classe abstraite, nous n’auront pas besoin de réécrire nos méthodes save()
et delete()
et l’on pourra se concentrer sur des méthodes permettant par exemple, de retourner un menu de navigation, des méta-tags pour le référencement naturel, etc.
Bien sûr, il faudra écrire un contrôleur permettant de traiter les données à passer au modèle, qui se chargera ensuite de les enregistrer en base de données, mais ça se fait rapidement .
Là dessus, bonne semaine (et bonne année) !
0 Webmentions
No webmentions were found.
- {% for webmention in webmentions %}
- {{ webmention.content }} {% endfor %}
No bookmarks were found.
{% endif %}- {% for webmention in webmentions %}
- {% endfor %}
No likes were found.
{% endif %}- {% for webmention in webmentions %}
- {{ webmention.content }} {% endfor %}
No links were found.
{% endif %}- {% for webmention in webmentions %}
- {{ webmention.title }} {% endfor %}
No posts were found.
{% endif %}- {% for webmention in webmentions %}
- {{ webmention.content }} {% endfor %}
No replies were found.
{% endif %}- {% for webmention in webmentions %}
- {% endfor %}
No reposts were found.
{% endif %}- {% for webmention in webmentions %}
- {% endfor %}
No RSVPs were found.
{% endif %}- {% for webmention in webmentions %}
-
{% if webmention.author %} {% endif %}{% if webmention.content %} {{ webmention.content }} {% else %} {{ webmention.title }} {% endif %} {% endfor %}
No webmentions were found.
{% endif %}