Le plugin YAML v2

Depuis sa création, le plugin YAML a subi peu de mises à jour. Sa stabilité est une preuve de robustesse, néanmoins le petit toilettage et les quelques évolutions de la branche v2 apportent plus de souplesse dans l’utilisation et simplifieront la maintenance.

Versions et compatibilité

Cette branche v2 du plugin est dédiée à SPIP 3. La compatibilité avec SPIP 2 a été abandonnée (suppression du plugin.xml) et en conséquence le PHP 4 n’est plus supporté. La borne inférieure de compatibilité SPIP a été fixée à 3.0.0, néanmoins, il est nécessaire de posséder une version PHP supérieure ou égale à 5.3.3 pour être assuré du fonctionnement correct du plugin.

Par défaut, sans rien modifier de la configuration, le plugin utilise la même librairie YAML que la branche v1, si ce n’est que celle-ci a été rafraichie comme précisé dans un chapitre ci-après.

Même si le prototype des fonctions d’API a changé (voir le chapitre suivant), le code d’appel des fonctions v1 est toujours valable et donnera les mêmes résultats. Néanmoins, il est conseillé de migrer progressivement vers une utilisation type v2 (voir le chapitre concerné).

L’API du plugin

L’API du plugin YAML (fichier inc/yaml.php) est composée de 3 fonctions principales déjà présentes en v1 et d’une fonction dépréciée conservée par souci de compatibilité avec la branche v1. Les 3 fonctions principales sont donc :

  • yaml_encode($structure, $options = array()), qui encode une structure de données PHP en une chaîne YAML ;
  • yaml_decode($input, $options = array()), qui décode une chaine YAML en une structure de données PHP, souvent un tableau ;
  • yaml_decode_file($file, $options = array()), qui décode un fichier YAML en une structure de données PHP. Cette fonction fait appel à yaml_decode() après avoir extrait le contenu du fichier.

Par rapport à l’API v1, le prototype des fonctions a été modifié avec l’ajout systématique de l’argument optionnel $options qui agrège l’ensemble des options possibles dans un tableau associatif. Son utilisation exhaustive est précisée dans le chapitre décrivant l’utilisation avancée du plugin.

Ces fonctions sont indépendantes de la librairie YAML utilisée. En fonction du contexte - constante _LIB_YAML et index ’library’ de l’argument $options - chaque fonction de nom $fonction détermine la librairie à utiliser $library et fait appel à la fonction « homonyme », $library_$fonction().

La fonction yaml_charger_inclusions() peut être considérée comme dépréciée dans cette nouvelle branche. Même si il est toujours possible de l’utiliser pour intégrer récursivement le YAML décodé des inclusions référencées dans le fichier YAML initial, il est recommandé d’utiliser uniquement la fonction yaml_decode_file() en précisant dans les options le chargement des inclusions.

En outre, le filtre decoder_yaml() qui encapsule yaml_decode_file() et yaml_to_array() pour les itérateurs ont été conservés. Le filtre decoder_yaml() peut bénéficier pleinement de l’argument optionnel $options mais pas yaml_to_array() qui structurellement ne peut recevoir que la chaine YAML en argument.

Les librairies YAML

Le plugin propose toujours les librairies de la branche v1, à savoir, Spyc et Symfony/yaml v1 mais permet aussi d’utiliser le composant YAML de la dernière version de Symfony v4 et l’extension PECL qui encapsule la librairie C libYAML.

Les versions de Spyc et Symfony/yaml v1 ont été mises à jour et les améliorations apportées par SPIP sur Symfony/yaml v1, reportées.

Chaque librairie requiert une version de PHP minimale et implémente un sous-ensemble propre des spécifications YAML 1.0, 1.1 ou 1.2. Le tableau suivant résume ces différentes contraintes et fournit la version actuelle - qui sera amenée à évoluer - de chaque librairie incluse dans le plugin YAML (version initiale 2.0.0).

LibrairieAlias*VersionPHP miniYAMLCommentaires
Spyc spyc 0.6.2 5.3.1 1.0 dépôt GitHub
Symfony/yaml v1 sfyaml 1.0.6 5.2.4 1.2 dépôt GitHub, archivé
Symfony/yaml v4 symfony 4.2 7.1.3 1.2 dépôt GitHub
libYAML libyaml 1.3.1 5.3.3 1.1 page PECL et dépôt GitHub libYAML
2.0.2 7.0.0

(*) : L’alias sert à désigner la librairie pour les API : valeur de $options['library'] ou de la constante _LIB_YAML.

Coté performance, on peut relever :

  • la librairie C libYAML est de loin la plus performante avec des benchmarks 6 à 15 fois plus rapides que les autres librairies ;
  • les librairies Symfony/yaml v1 et Spyc ont des performances comparables plutôt correctes ;
  • la librairie Symfony/yaml v4 est 2 fois plus lente environ que la version v1.

En outre, le sous-ensemble des spécifications YAML proposé par chacune des libraires varie beaucoup. Pour les besoins de SPIP qui concernent principalement des paramètres de configuration, toutes les librairies se valent quelque soit la version de spécifications YAML supportée. Pour se donner une vision des différences d’implémentation, une série de fichiers de tests (demo/$library.yaml) est fourni avec le plugin. Ces fichiers sont issus du fichier de tests natif de la librairie Spyc. Pour les autres librairies, il a été adapté en mettant en commentaire les cas non supportés.

Il faut noter que deux features YAML importantes ne sont pas implémentées par le plugin car pas disponibles pour toutes les librairies :

  • les 3 tirets de début et les 3 points de fin de document YAML,
  • et par conséquence, le multi-documents au sein d’un même fichier YAML : un fichier YAML doit toujours contenir qu’un seul document YAML.

Par défaut, pour assurer la compatibilité avec la branche v1, le plugin YAML utilise la librairie Symfony/yaml v1 (alias sfyaml), ce qui reste un bon choix.

Maintenance du plugin

Outre les corrections de bugs, la maintenance du plugin coïncide avec celle de ses librairies.

La librairie par défaut, Symfony/yaml v1 n’est plus maintenue. Elle n’évoluera donc pas mais elle fonctionne toujours très bien avec les spécifications et les utilisations actuelles du YAML. Elle est composée de 4 fichiers installés dans le répertoire sfyaml/ du plugin.

La librairie libYAML est distribuée en extension PECL. Elle s’installe donc sur le serveur Apache, rien n’est à faire au niveau du plugin. Elle est clairement à privilégier si l’installation est possible.

Les deux autres librairies, Spyc et Symfony/yaml v4, sont intégrées dans le plugin via Composer. On les retrouve sous le répertoire vendor/. Il est possible simplement de les mettre à jour voire de revenir à une version précédente en utilisant le fichier composer.json présent à la racine du plugin et en activant la commande composer update.

Utilisation avancée de l’API

Comprendre les options

L’utilisation basique des fonctions d’API n’a pas été modifiée. Par contre, l’ajout de l’argument $options en second paramètre de chaque fonction d’API permet une utilisation plus flexible et plus précise du plugin. Les options proposées sont résumées par fonction dans le tableau ci-dessous et un « x » précise si l’option est disponible pour une librairie donnée.

OptionExplicationsfyamlsymfonyspyclibyaml
Toute fonction
library Précise la librairie à utiliser indépendamment de la constante _LIB_YAML x x x x
yaml_decode() et yaml_decode_file()
include Traite les inclusions de fichiers YAML (true) ou pas (false, par défaut) x x x x
show_error Affiche les erreurs (true) ou pas (false, par défaut) x x
flags Combinaison des flags bitwise PARSE_* supportés par la librairie, 0 par défaut x
yaml_encode()
indent Nombre d’espaces pour chaque niveau d’indentation, 2 par défaut x x x x
inline Niveau à partir duquel la présentation du YAML devient inline, 3 par défaut x x
flags Combinaison des flags bitwise DUMP_* supportés par la librairie, 0 par défaut x

Décoder les inclusions

Le plugin YAML permet, depuis sa version v1, de faire des inclusions dans un fichier YAML sous la forme :

- 'inclure:dossier_relatif/fichier.yaml'

Cette fonctionnalité évite de répéter des listes de blocs identiques dans plusieurs fichiers YAML ce que la spécification YAML n’autorise pas nativement. Ce traitement des inclusions étant relativement couteux (parcours récursif de la structure de données issue du décodage), il n’est pas appliqué d’office lors du décodage du YAML mais demandé explicitement.

Avec la branche v1 du plugin, cette fonctionnalité est réalisée en appelant la fonction d’API yaml_charger_inclusions() sur le résultat du décodage d’un fichier ou d’une chaine YAML :

$configuration = yaml_charger_inclusions(yaml_decode_file($fichier));

La nouvelle branche v2 recommande une autre façon de réaliser ce traitement sans appeler la fonction yaml_charger_inclusions() qui se retrouve ainsi dépréciée, mais en utilisant une option de décodage comme illustré ci-dessous :

$configuration = yaml_decode_file($fichier, array('inclure' => true));

Forcer une librairie lors d’un appel

Si la librairie utilisée par défaut (constante _LIB_YAML) ne convient pas pour un appel précis, il est possible de forcer pour cet appel une autre librairie :

$configuration = yaml_decode_file($fichier, array('library' => 'libyaml'));

Visualiser les erreurs

Par défaut, pour la branche v2, les erreurs de décodage du YAML ne sont plus affichées. Pour forcer leur affichage il faut utiliser l’option ’show_error’ ainsi :

$configuration = yaml_decode_file($fichier, array('show_error' => true));

La suite...

  • réfléchir éventuellement à une logique de détermination plus évoluée pour choisir la librairie par défaut ?
  • déprécier certaines librairies pour ne garder que libYAML si installée ou l’une des librairies installées par composer ?

Discussion

2 discussions

  • 6

    Bonjour,
    j’utilise ce plugin sans problème avec la fonction yaml_decode_file sur un spip4.2 avec php 8.0
    Si je passe à une version 8.2 ou supérieure, la fonction n’arrive plus à décoder un fichier yaml.
    Mon hébergeur ne maintient la version 8.0 que jusqu’en décembre.
    Ce problème est-il connu ?
    Cordialement

    • tu aurais le fichier yaml, car chez moi ca marche :p

    • oui voici, merci pour l’aide !

    • le fichier n’est pas passé ?? oui le .txt n’est pas accepté. je tente de changer juste son extension, à transformer en txt après ?

    • Tu peux simplement copier-coller le contenu en l’encadre de balises code.

    • Voici (ça me permet de synchroniser une table entre mes bases locale et distante)

      -  
      id_activite : ’54’
      id_matiere : ’2’
      ref : exoT8-9
      date_modif : ’201804061600’
      type : exo
      id_chapitre : ’69’
      titre : ’Réaction nucléaire’
      difficulte : null
      pdf_enonce : exoT8-9-E-201804061600.pdf
      height_enonce : ’165’
      pdf_corrige : exoT8-9-C-58856.pdf
      height_corrige : ’255’
      statut : prop
      maj : ’2023-08-31 15:16:25’
      id_rubrique : ’15’
      id_secteur : null
      correction : null
      rang_activite : ’0’
      -  
      id_activite : ’55’
      id_matiere : ’2’
      ref : exoT8-31
      date_modif : ’201908281510’
      type : exo
      id_chapitre : ’69’
      titre : ’cuisson d’’un \oe uf dur’
      difficulte : null
      pdf_enonce : exoT8-31-E-201908281510.pdf
      height_enonce : ’125’
      pdf_corrige : exoT8-31-C-61695.pdf
      height_corrige : ’120’
      statut : prop
      maj : ’2023-08-31 15:16:33’
      id_rubrique : ’15’
      id_secteur : null
      correction : null
      rang_activite : ’0’
      -  

    • Le plus simple serait utiliser l’option show_error de la fonction pour vérifier si il n’y a pas une erreur dans le YAML.

      $configuration = yaml_decode_file($fichier, array('show_error' => true));

    Répondre à ce message

  • Testé sous Windows avec PHP 8.2 et PECL libyaml installée via https://www.apachelounge.com/viewtopic.php?t=6359 en version 2.2.3 (cf https://github.com/php/pecl-file_formats-yaml/issues/71#issuecomment-1463997670)

    Ça marche !

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom