Comment monter un serveur d’archives PHP sans pleurer …

Mine de rien, concernant mon métier j’ai fait mes premiers pas en commençant mes études, ce qui commence à faire … un petit paquet d’années. Du coup en fait j’ai gardé (presque) toutes mes archives … ce qui n’est pas problématique quand on est en « full HTML » mais quand on passe en PHP, là c’est plus touchy. Parce que mes premiers sites sont en PHP4, en sachant qu’on se dirige vers la version 8, il y a eu pas mal de chemin depuis : renforcement de la rigueur, changements dans la conception objet, méthodes deprecated et j’en passe.

Essayez de faire marcher un site crée en 2003 sur un PHP 7 … ça m’étonnerait que vous puissiez faire quelque chose de concret. Du coup, pour faire comme moi, trouver des trucs de geek à faire en étant confiné (même si j’ai la chance de pouvoir continuer à travailler, il faut s’occuper le soir 😉 ) et faire tourner un serveur d’archives sur une Ubuntu récente, que faire ?

PHP 5.6 avec FPM

Il y a une solution pour les sites les plus récents : PHP-FPM, qui permet de faire tourner PHP en service indépendamment d’Apache (oui désolée je suis Apache-addict, question d’habitude), ce qui vous permet de pouvoir faire tourner un PHP5.6. C’est assez simple …

En premier lieu, on prépare le terrain, on se base déjà sur le fait que vous avec déjà Apache installé dans votre système.

Quelques librairies de base

Puis il vous faut ajouter le fameux repository d’Ondřej Surý, qui a fait un travail remarquable à ce sujet :

Et hop, magie !

N’oubliez pas d’ajouter les librairies MySQL au besoin. Une fois les installations bien terminées, faites un petit service status, histoire de bien vérifier que les services tournent :

Donc si vous avez un message de ce style, c’est que tout va bien 🙂

Donc là, vous pouvez faire tourner non seulement des sites tout neufs, mais également des sites que vous avez conçu il y a au moins trois-quatre ans. Il suffit après de configurer votre vhost comme suit pour switcher de version :

Vérifiez bien que les services suivants soient activés :
actions proxy_fcgi alias
Et les librairies suivantes installées pour PHP 5.6 au risque de voir une belle page blanche qui ne logge rien de pertinent :
php5.6-xml php5.6-gd php5.6-mcrypt php5.6-mysql php5.6-pdo

Et pour les versions antérieures à PHP 5.6 ?

Après, les choses se compliquent. Ne cherchez pas à installer ne serait-ce que PHP 5.2 à la mano, rien n’est compatible avec les versions actuelles d’OpenSSL et vous risquez de casser pas mal de trucs comme ça m’est arrivé. Et ainsi d’avoir à vous repalucher les installs d’Apache et OpenSSL, les joies de l’admin sys et de l’expérimentation, en somme 🙂 … – note : ce serveur n’est pas celui que j’utilise pour mes sites importants mais pour mon « bac à sable » 😉 …

Du coup j’ai opté pour un bel outil bien tendance qui a le vent en poupe chez les devOps, et qui est vraiment pratique, j’ai nommé : Docker ! J’ai finallement consenti à créer donc un conteneur qui ne servira qu’à mes plus anciens sites, et la bonne nouvelle, c’est qu’il n’y a pas tant de différences entre les dernières versions de PHP 4 et PHP 5.2 (au niveau du fait de pouvoir faire fonctionner un site en PHP 4 sur un serveur PHP 5.2, l’inverse ne sera pas forcément possible – et même fortement impossible), ce qui signifie que mes plus vieux sites tournent avec sans souci, et que je n’ai donc pas à créer de conteneurs supplémentaires (du moins, pour ma part ! ) !

Comme je suis une nana sympa, j’ai mis sur GitHub l’image que j’utilise, que vous pouvez déployer avec docker-compose, vous pouvez même définir un répertoire mysqldump pour alimenter la base directement en ligne de commande. Il y a également un PhpMyAdmin pour se simplifier la vie. Il faut juste modifier les vhosts pour que ça pointe sur vos sites à vous, qui seront accessible par défaut sur le port 8052 (80 port par défaut d’Apache et 52 comme PHP 5.2 😉 )

N’oubliez pas de préciser au besoin comme dans mon exemple, si vos extensions sont .php3, je sais ça fait super bizarre de retrouver ce genre d’extension …

Pour le plaisir, je vous montre une petite capture d’écran de ma page de garde, où je peux naviguer de site en site … c’est amusant de replonger dans le passé, comme ça :

Après, c’est un projet qui donne plein d’idées : par exemple vous voyez les petits screenshots ? Ils sont en réalité bien moches quand on passe en responsive, car dimensionnés assez petits (je pensais qu’à l’époque, ça suffisait). Bien là j’ai mis en place un process sous Puppeteer qui permet de faire des captures d’écran automatiquement ! Je pense que je vais pas mal trouver d’idées inspirantes que je vous partagerai par la suite 😉

Mon projet de refacto BioPHP – Partie 2 (du design pattern)

Le souci de la librairie d’origine de BioPHP, c’est son absence de design pattern. Le code d’origine prévoyait d’inclure deux systèmes de bases de données (Genbank et Swissprot en l’occurence) voire d’autres, car j’ai vu une dizaine d’autres formats.

Or le but du jeu c’est d’avoir une structure assez carrée pour pouvoir ensuite manipuler les données.

Tout se joue dans le fichier d’origine seqdb.php, je vous laisse regarder la tambouille. Dans ce cas-là, il faut surtout comprendre la logique, la garder et tout casser en même temps. A coups de massue.

La première des choses que j’ai faite, c’est compartimenter une classe par fichier, et un fichier par classe : donc on a trois fichiers, SeqDB, et des fonctions parse_swissprot et parse_id que je ramène dans une classe chacune, et que je renomme au passage car sinon on n’y comprend pas grand-chose. Je passe l’étape de « nettoyage », remplacement des fonctionnalités obsolètes, découpage du code en méthodes privées, simple, basique.

Deuxièmement, c’est d’utiliser un Iterator pour le flux des fichiers car le script réinvente la roue avec les next() et les prev().

Ensuite j’ai refactorisé en gardant l’ancienne structure de seq.php, pour arriver à comprendre petit à petit la logique, à quoi correspond chaque champ du fichier qui est envoyé. Avant le grand coup d’envoi, puisque les structures qui correspondent aux séquences vont être factorisées à leur tour, pour cela je me suis inspirée du modèle de données qui avait été proposé par l’équipe, en y mettant deux trois ajustements :

Rien de bien sorcier, c’est du MVC et du Doctrine de base.

Une fois que c’est établi, que ça marche et parse, il faut intégrer ce système au parsing des fichiers tout en permettant à l’utilisateur de lui simplifier un maximum le travail.

Il fera appel à une interface. Une seule. Et la librairie se chargera du reste. Voici comment (le travail n’est pas terminé ce qui explique pourquoi ParseSwissProt est vide mais c’est en cours) :

Diagramme réalisé avec le superbe outil PlantUML

Utiliser l’interface DatabaseInterface fera appel via l’injection de dépendances à DatabaseManager qui se charge de vérifier si le fichier existe en base, ou d’aller chercher de la donnée. Suivant le cas de figure, ce sont des factory qui seront appelées et qui joueront les aiguilleurs en appelant les services correspondants. Ces services « final class » ont une notion d’héritage sur un autre service, abstrait, ParseDbAbstractManager, qui contient l’architecture de la donnée qui sera renvoyée dans le controller de l’utilisateur.

Ce qui permet dans tous les cas de renvoyer une donnée, qui, quel que soit le schéma de départ, sera uniforme. Et ce grâce à deux design pattern : Factory et Abstract.

Du coup, si on veut ajouter une autre structure de fichier, il suffira de modifier les factory et d’ajouter un service qui sera chargé uniquement de parser la donnée. Ceci dit, je pense qu’il est même possible de passer outre la modification des factory, je dois réfléchir sur ce point.

Je crois que cette partie est la plus complexe de mon projet, car je ne suis pas familiarisée avec les bases de données textuelles propres à la bioinformatique, et le script de départ contenait pas mal de bugs. Du coup si des biologistes chevronnés constatent des bugs à l’utilisation, ils peuvent me contacter, ce sera volontiers que je procèderai aux ajustements.