L’API PHP de FileMaker est elle en fin de vie ? C’est une question que l’on pourrait se poser depuis qu’une nouvelle technologie est apparue dans FileMaker Server 16 pour nous permettre de partager les données d’une base FileMaker au travers d’un site web: l’API REST. Cependant, bien que cette nouvelle API (encore en version beta – [EDIT : en version finale avec FileMaker 17]) apporte un vrai vent de fraîcheur et offre de belles perspectives d’évolution, elle n’en demeure pas moins limitée pour l’instant et moins adaptée à une architecture web classique où le serveur web occupe un rôle central.
Aussi, la publication XML couplée à l’API PHP de FileMaker reste encore à ce jour le meilleur moyen pour partager et utiliser une solution directement sur le Web.
Elle souffre malgré tout de certaines lacunes : développée pour être compatible avec PHP 4 à sa sortie (une version encore répandue à l’époque), l’API PHP originale (téléchargement) n’a quasiment pas évolué depuis (à part quelques corrections mineures).
Tous ceux qui l’ont utilisée, se rappellent certainement des nombreuses alertes indiquant l’utilisation des méthodes dépréciées dès lors qu’elles étaient exécutées avec une version plus récente de PHP. Bien que ces erreurs aient été corrigées depuis, l’avènement de PHP 7 les a malheureusement remises au goût du jour.
Ce manque d’évolution a rendu son code vétuste, il n’est plus du tout en phase avec les nouvelles méthodes de développement qui ont émergé ces dernières années dans l’univers de PHP, et de fait ce retard d’actualisation rend son intégration compliquée dans tout projet utilisant un framework ou un CMS « moderne ».
Une mise à jour de cette bibliothèque était devenue de plus en plus nécessaire pour assurer sa pérennité. Seulement voilà, bien que PHP ait encore de beaux jours devant lui au vu de ses améliorations régulières et de sa grande popularité, FileMaker a décidé de faire les yeux doux aux technologies plus en vogue actuellement, telles que les frameworks JavaScript. Inutile dès lors d’espérer une quelconque évolution de ce côté-là (la publication XML n’est et ne sera a priori jamais disponible sur FileMaker Cloud par exemple).
Il ne restait donc qu’une seule solution : retrousser ses manches et mettre les mains dans le cambouis afin de prodiguer une petite cure de jouvence à notre chère API PHP !
Évidemment, avant de toucher à la moindre ligne de code, il fallait se plonger d’abord, tel un moine cistercien, dans une longue et approfondie étude du code source original, pour comprendre sa structure, son fonctionnement et ses particularités afin de bien saisir l’ampleur du chantier à venir.
Très vite, deux exigences se sont imposées : simplifier au mieux le code source (tout en essayant de l’optimiser), et le moderniser afin de le rendre conforme aux standards de développement actuels, notamment ceux recommandés par le groupe PHP-FIG, dans l’objectif d’assurer une meilleure interopérabilité avec la plupart des frameworks et CMS PHP modernes.
Côté simplification, les changements se sont portés principalement sur une nouvelle stratégie de gestion des erreurs et sur la réécriture d’une partie du code afin de respecter la norme PSR-2 (conventions d’écriture du code source).
La nouvelle gestion d’erreurs consiste à s’affranchir des tests conditionnels ponctuels au bénéfice d’une seule structure générale de test par exceptions, avec un bloc de type « try / catch » englobant les principales instructions de travail (voir un exemple de code plus bas). La méthode originale reste cependant toujours fonctionnelle afin d’assurer une compatibilité descendante.
Cette première étape terminée, il fallait maintenant consolider la compatibilité avec les versions les plus récentes de PHP et en tirer le meilleur parti pour moderniser au maximum le code.
Dès lors, concernant la modernisation du code source, l’ajout des espaces de noms, sur l’ensemble des classes de l’API, couplé à un système « d’auto-chargement », comme le préconise la spécification PSR-4, se sont imposés, assurant de facto la compatibilité avec les frameworks PHP les plus en vogue du moment.
Cette technique a entraîné un changement en profondeur de la structure des fichiers, sans pour autant modifier le fonctionnement d’origine de l’API, et ce, dans le but de garantir une parfaite compatibilité avec les projets basés sur l’API-PHP de FileMaker originale.
Nous y étions ! l’API PHP de FileMaker était enfin modernisé ! Ne restait plus alors qu’à l’ouvrir au reste du monde libre !
En effet, depuis quelques années maintenant, les projets PHP se sont structurés autour d’une multitude de bibliothèques tierces, à l’instar de beaucoup d’autres langages tel que java, javascript, …
Afin de simplifier la gestion de ces multiples codes source et d’assurer leur mise à jour sans effort (le code étant maintenu par d’autres développeur), un outil désormais très populaire a été créé : Composer. Celui-ci permet de gérer, à l’aide d’un simple fichier de configuration (json) l’ensemble des bibliothèques tierces d’un projet, en assurant l’installation et la mise à jour.
De toute évidence, notre API se devait de rejoindre la communauté pour achever sa mutation, ce qui nécessita quelques adaptations non sans conséquences : cela a conduit à abandonner le fichier de configuration original de l’API (dans le monde de Composer, une bibliothèque tierce ne doit jamais être modifiée pour garder le bénéfice des mises à jour). Cela implique qu’il est désormais livré avec une configuration « par défaut », qu’il vous appartient de modifier au moment de son instanciation.
Notre nouvelle API fin prête, il nous tardait de l’intégrer dans un projet d’ampleur pour en mesurer son potentiel, ce qui fut rapidement le cas ! Un projet nécessitant l’emploi d’un Framework (yii2) s’étant rapidement présenté.
Ce premier galop d’essai a permis de mettre en lumière certaines lacunes qui n’étaient pas forcément apparues lors de la réécriture, notamment le besoin de faciliter le débogage lors des développements et d’améliorer la communication avec des bibliothèques tierces.
Ainsi, un certain nombre de nouvelles fonctionnalités ont été implémentées au fil de l’eau, dont voici une liste non exhaustive (certaines développées spécifiquement, d’autres issues des fonctions déjà existantes dans l’API-XML de FileMaker, mais non implémentées dans l’API-PHP de FileMaker d’origine) :
$layout->table
, permettant une gestion plus simple des contextes d’exécution ;Voici, en quelques lignes, les principales étapes pour installer et mettre en service cette nouvelle API-PHP de FileMaker.
Il y a deux méthodes d’installation de cette API :
"airmoi/filemaker" : "*"
à votre fichier de configuration ;Pour le chargement et l’activation de l’API, c’est très simple, il suffit d’inclure le fichier « autoload.php » qui se trouve à la racine du projet (facultatif en cas d’installation via Composer):
require ('/path/to/API/autoload.php');
Vous devez ensuite déclarer la classe à utiliser à l’aide de son espace de nom (l’autoloader se chargeant de trouver automatiquement les fichiers à charger pour assurer le bon fonctionnement de l’API) :
use airmoi\FileMaker\FileMaker;
Le fichier de configuration ayant disparu, deux méthodes sont disponibles pour configurer votre projet :
setProperty('name', $value)
, qui peut servir pour configurer individuellement les différents paramètres du projet ;new FileMaker($db, $host, $user, $pass, ['dateFormat' => 'd/m/Y'])
Voici un code d’exemple illustrant tout ceci :
// Chargement de l'API require_once ('/path/to/API/autoload.php'); // Définition de l'espace de noms use airmoi\FileMaker\FileMaker; // Réglage des options de configuration $options = [ 'errorHandling' => 'default', 'locale' => 'fr', 'prevalidate' => true, 'dateFormat' => 'd/m/Y', ]; // Création de l'objet FileMaker avec le tableau de paramètres $fm = new FileMaker($db, $host, $user, $pass, $options); // Récupération de la liste de tous les modèles et leur affichage $layouts = $fm->listLayouts(); foreach ($layouts as $layout) { echo $layout . ' '; }
// Réglage des options de configuration $options = [ 'errorHandling' => 'default', ]; $fm = new FileMaker($db, $host, $user, $pass, $options); // Récupération d'un modèle et test sur une éventuelle erreur $layout = $fm->getLayout('sample'); if (FileMaker::isError($layout)) { echo "Error: " . $layout->getMessage(); exit; } // Execution de la requete $result= $fm->newFindAnyCommand('sample')->execute(); if (FileMaker::isError($record)) { echo "Error: " . $record->getMessage(); exit; } // Récupération d’un enregistrement $record = $result->getFirstRecord(); if (FileMaker::isError($record)) { echo "Error: " . $record->getMessage(); exit; } // Modification de l’enregistrement $record->setField('text_field', str_repeat('a', 51)); $record->commit(); if (FileMaker::isError($record)) { echo "Error: " . $record->getMessage(); exit; }
L’ancien système de gestion d’erreur s’obtient en réglant le paramètre « errorHandling » à la valeur « default ».
Comme on peut le constater, elle vous oblige à répéter vos contrôles pour pratiquement chaque instruction.
//Le mode de gestion par Exception est configuré par défaut //il n'est donc pas nécessaire de le préciser dans les options $fm = new FileMaker($db, $host, $user, $pass); try { // Récupération d'un modèle $layout = $fm->getLayout('sample'); // Récupération d’un enregistrement en 1 ligne $record = $fm->newFindAnyCommand('sample')->execute()->getFirstRecord(); // Modification de l'enregistrement $record->setField('text_field', str_repeat('a', 51)); $record->commit(); } catch (FileMakerException $e) { //Gestion des erreurs ayant pu survenir à n'importe quelle ligne printf ('Erreur %d : %s ', $e->getCode(), $e->getMessage()); }
Comme vous pouvez le constater, la gestion d’erreur par exception via le bloc try/catch permet de réduire de façon considérable le nombre de lignes de code.
Toute sa logique peut être centralisée, ce qui simplifie la lecture du code, améliore sa fiabilité et sa maintenance.
$fm = new FileMaker($db, $host, $user, $pass); $result = $fm->newPerformScriptCommand('sample', 'create sample data', 50) ->setRange(5, 20) ->execute(); echo $result->getFetchCount() . '/' . $result->getFoundSetCount();
Désormais, avec cette nouvelle API, on peut demander quel intervalle de données récupérer. Par exemple, on peut demander d’avoir les données correspondant aux enregistrements de 5 à 25. Cela permet d’obtenir une pagination sur un résultat de script, ce qui était impossible auparavant
$fm = new FileMaker($db, $host, $user, $pass); $result = $fm->newFindCommand('sample') ->setGlobal('global_field', date('m/d/Y')) ->addFindCriterion('test_field', 1) ->execute(); echo $result->getFetchCount() . " enregistrements trouvés.";
Fonctionnalité très pratique, car elle permet désormais de définir une globale au moment de l’exécution d’une requête, ce qui vous permettra par exemple de récupérer, dans vos résultats, des données liées au travers d’une globale.
Comme expliqué au début de l’article, l’API PHP de FileMaker avait bien besoin d’un sacré coup de jeune pour s’adapter à l’évolution des technologies les plus récentes, notamment concernant l’interaction avec les frameworks PHP modernes.
Cette réécriture a nécessité de nombreuses heures de travail et d’innombrables tests. Le résultat est plus qu’encourageant puisque cette nouvelle version est désormais utilisée quotidiennement en production sur plusieurs projets professionnels gérés par l’équipe de 1-more-thing.
Mais, bien qu’elle soit en l’état assez stable et aboutie pour être utilisée en production, cette réécriture n’est cependant pas encore terminée, bien d’autres améliorations sont en cours et d’autres à prévoir. Si vous souhaitez contribuer à son évolution, vous êtes évidemment les bienvenus : Dépot GitHub.
Un grand merci à tous ceux qui ont participé, directement ou indirectement, à la réalisation de ce projet, et un remerciement tout particulier à Matthias Kühne pour toutes ses contributions.