Comment j'ai décidé d'écrire ORM en php à partir de zéro sur un site de travail, et ce qui en est arrivé

Comme beaucoup de programmeurs, j'ai une attitude plutôt négative à l'égard de la création de bicyclettes et de l'invention des roues, et cela est plus que justifié au moins par le coût de développement de l'entreprise. Mais comme mon expérience l'a montré, il faut parfois s'écarter de cette règle et même en profiter. Je veux dire non seulement l'intérêt et le plaisir du développement, mais aussi des goodies pour le projet dans son ensemble. Vous pouvez lire quelques mots sur l'une de mes expériences similaires sous la coupe.







introduction



La façon dont nous créons des applications Web est maintenant très différente du code qui nous est venu pour le support des temps anciens, lorsque Star Factory était montré à la télévision, il était à la mode de marcher avec une coquille , et PHP commençait tout juste à acquérir les signes d'un langage orienté objet. La programmation dans les années 2000 me semble être une excellente illustration des idées de Darwin: à cette époque, presque tous les développeurs ont créé leurs propres solutions, certaines d'entre elles ont capturé l'esprit de plus d'une personne, et après être passées par la sélection naturelle accélérée, les frameworks et les CMS sont devenus les exemples de titre des méthodes de développement les meilleures et les plus populaires. ... Dans certains cas, néanmoins, seulement populaire, sans le mot «bon» ou plus encore «le meilleur».





Mais contrairement aux dinosaures et aux mammouths, toutes les solutions alternatives ne sont pas tombées dans l'oubli, en particulier sur le backend, et je le sais de première main. J'ai eu la chance de travailler, je ne dirai pas avec un héritage important, mais assez solide, en php. Certains d'entre eux étaient tout simplement horribles et certains sites et même le CMS étaient assez intéressants. Parfois, j'aime me plonger dans ce qui est né dans l'esprit des pionniers. Il n'y avait pas une telle standardisation à l'époque, et bien que la plupart du temps, ce soit un excellent matériau pour apprendre les anti-modèles, mais ce code m'amuse, rend le travail similaire à l'archéologie informatique.



Bien-aimé héritage



Personnellement, j'aime travailler avec des sites de travail sur l'héritage - pour faire une modification, supprimer une béquille sauvage, réduire le niveau de chaos et en même temps ne pas casser tout le système. Dans de tels moments, je me sens comme une personne qui a rendu ce monde un peu meilleur, et c'est cool.



print " <button onClick='domultimove();' class=controlbutton><img src=syspix/ico32_move.gif border=0><br></button>";
print "<b>" . $ITEM->Description . "</b>:<br>";
$browsebgcolor = "#D9D9D9";
$sql = "select i.ID, m.Name, i.perm, i.descr from item4 i inner join main m on i.ID=m.ElementID";
echo "<script language='JavaScript'> document.location='" . $_SERVER['PHP_SELF']";


Une caractéristique commune de l'héritage est un désordre de code écrit dans différents langages, bien que dans le développement moderne, bien sûr, nous puissions ajouter, par exemple, du code en SQL aux classes PHP. Mais je parle d'autre chose, dans l'héritage il y a souvent un flux de pensée universelle du développeur - quoi et dans quelle langue il pensait, il a écrit dans un flux. Je veux parler d'une situation similaire avec une solution CMS méga-old-school avec laquelle je travaille depuis un certain temps. Tout y était si "merveilleux" que je suis juste très heureux d'avoir pu réparer quelque chose et faire fonctionner le site beaucoup plus correctement et plus rapidement.



Donc, j'ai eu un site Web pour une grande entreprise, écrit dans la première moitié des années 2000. Dans ce projet, tout était basé sur des classes avec une seule méthode, dans laquelle tout se passait: travailler avec la logique, afficher l'interface (vue) et accéder à la base de données, de plus, sql était juste là entre les commandes
print "<table>";
... Modifier un site fonctionnant avec un tel code, d'ailleurs, avec un bon trafic et une composante commerciale, n'était pas l'événement le plus agréable, mais très amusant.





Il n'est pas difficile de deviner que j'ai grandement facilité la vie des développeurs backend en intégrant d'abord la sortie de mise en page dans des modèles. Pour cela, j'ai utilisé le moteur de modèles de brindilles prêt à l'emploi et plutôt populaire. C'était facile et rapide, donc je n'ai même pas passé beaucoup de temps à le refactoriser. La prochaine étape, à mon avis, était de faire quelque chose avec des requêtes dans la base de données, après tout, MVC n'est pas en vain si populaire sur notre site Web.





Après avoir examiné Symphony et Laravel, j'ai décidé que l'approche ORM conviendrait parfaitement ici aussi. Cela aidera à effectuer des travaux avec la base de données et à laisser pour le moment les non-contrôleurs travailler uniquement avec les données déjà reçues. Il est logique et tout à fait correct d'utiliser les solutions existantes. Par conséquent, tout d'abord, je me suis précipité chez packagist pour voir quelles alternatives j'avais en plus de la doctrine, mais après avoir mûrement réfléchi, je suis arrivé à la conclusion décevante que ce n'est pas si important. Le fait est que ce projet avait une structure de données plutôt inhabituelle. Je n'ai vu une telle chose nulle part ailleurs, même si j'ai travaillé avec MODx :) J'ai rencontré un problème: utiliser les ORM open source populaires comme je le souhaite ne fonctionnera pas, eh bien, au moins ce sera une autre aventure. J'ai donc décidé de créer un vélo.



Un peu de ce que j'ai fait





Oui, j'ai décidé d'écrire un ORM en PHP à partir de zéro (non, eh bien, j'avais des idées et des concepts empruntés à la même Docktrine) spécifiquement pour ce projet, afin que cela fonctionne avec la structure de données. Après tout, c'est un site de travail, et personne n'était prêt à allouer les ressources des programmeurs pour la tâche de «tout réécrire à partir de zéro avec une structure de base de données normale». Les ancêtres qui ont fondé ce CMS ont créé 2 types d'objets, et l'un d'eux a également été divisé en "types de données" internes: les ressources qui ont des dates, des liens, différents types de texte, des images et un certain nombre d'autres types ont été stockés dans 2 tables, mais il y avait aussi des objets stockés dans une table, je pense qu'ils peuvent être appelés données système.





Je ne voulais pas avoir à penser aux jointures lors de l'application d'appels à des modèles, ou du moins essayer de réduire ces moments au minimum. Par conséquent, j'ai décidé que les modèles devraient être de deux types: pour les objets à table unique et pour les objets de base à deux tables. Puisque ces classes de modèle ont de nombreuses méthodes communes, le même ORDER BY ou LIMIT, par conséquent, chaque classe de base, sur la base de laquelle des modèles concrets seront créés, j'ai hérité de la classe abstraite générale.



ORM



Comme vous pouvez le voir dans l'arborescence, j'ai également ajouté la prise en charge de différents types de bases de données, ce qui est redondant dans ce cas. Mais à ce moment, je suis entré dans le "flux" et j'ai créé :). De plus, l'étape très correcte dans ce cas était que je l'ai fait sur la base de PDO, car le php-mysql utilisé dans le code ne permettait pas de traduire le site dans la septième version du langage, et je voulais corriger cela à la racine, comme on dit.



$element = (new Model())->getOne($id);


Du fait que j'avais une bonne compréhension de la logique de la structure de la base de données, j'ai pu rechercher et récupérer une ressource uniquement par son identifiant, sans même savoir de quel type de données internes la ressource avait, ce qui était nécessaire avec l'ancienne approche. Les objets réels fonctionnent avec des données, et nous oublions SQL dans le code.





Derniers paragraphes ...



Ce travail m'a apporté 2 virages inattendus. Tout d'abord, j'ai essayé de tout écrire à la fois sous forme de code, et rien n'a fonctionné. J'ai dû prendre un stylo, un cahier, sortir dans la nature et, au chant des moineaux et au bourdonnement des abeilles, dessiner d'abord ce que je veux obtenir, comment il sera connecté, de quelles classes j'ai besoin et comment cela sera appelé dans le code des «contrôleurs». À propos, la mise en œuvre ne différait que légèrement des croquis d'origine. Donc, si un programmeur ne code rien, cela ne veut pas dire qu'il ne fait rien d'utile.



Deuxièmement, je l'ai fait très rapidement, de nombreuses entreprises n'aiment pas que les programmeurs passent du temps sur toutes sortes de refactorisations incompréhensibles. J'ai mis en œuvre l'ensemble du projet en une semaine environ, tout en effectuant simultanément les tâches d'implémentation de nouvelles fonctionnalités.



Je noterai ces avantages que j'ai énoncés au début de l'article: la séquence et la gradualité du remplacement du code existant sur un projet de travail, ce qui signifie qu'il n'est pas nécessaire d'allouer plus de temps pour la transition, en refactorisant le code dans le cadre des tâches entrantes. Sur ce, je prends congé, merci d'avoir lu.



All Articles