Lorsqu’on est un développeur PHP avancé, passer à Go est souvent plus tentant que passer à Node.JS. Mais dans un premier temps, tant de fonctions de la bibliothèque PHP font défaut. Comment migrer au plus vite ?
Le besoin: migrer de PHP
Démarrer avec Go lorsqu’on vient d’une expérience longue avec PHP ne demande pas seulement de repenser l’organisation entière de ses programmes, mais fait aussi — souvent — réaliser que toutes sortes de choses que l’on tenait pour implicites par habitude dépendaient de fonctions qui ne sont pas identiques en Go, et dont il faut identifier les remplacements au fil des besoins, ralentissant les premiers travaux.
L’outil
Pour faciliter les premiers projets durant la transition, le module github.com/syyongx/php2go
,
disponible depuis Go 1.10 et
comporte plus de 140 fonctions équivalentes aux fonctions PHP du même nom.
Il inclut même une fonction Ternary
pour convertir les instructions ternaires
?:
que Go a choisi de ne pas inclure.
Voyons un mini-exemple:
|
|
Comme le montre l’exemple, il suffit d’importer - et éventuellement d’aliaser le paquet du module, qui ne contient que ce paquet, et d’utiliser les fonctions en modifiant la capitalisation, les identificateurs Go devant commencer par une majuscule pour être exportés par les paquets qui les définissent.
|
|
Limitations
Par la force des différences, certaines limitations sont à prendre en compte, mises en évidence même par ce petit exemple:
- La signature peut être un peu différente: dans cet exemple,
Getcwd()
respecte les particularités de son implémentation sous-jacente en Goos.Getwd()
en renvoyant un code d’erreur, au lieu d’avoir la même signature qu’en PHP, de sorte qu’il faut ignorer explicitement l’erreur (ou, mieux, la traiter !). - Du fait du passage par des types
interface{}
pour simuler le typage dynamique de PHP, le résultat de certaines fonctions commeTernary
n’est pas forcément prêt à l’emploi, nécessitant une assertionv.(<type>)
commen dans l’exemple; ou un commutateur de typeswitch v.(type)
pour des situations où le type du résultat n’est pas connu à l’avance.
En outre, le résultat est un code un peu plus verbeux et non idiomatique, qui ne sera pas familier à la majorité des développeurs Go. À titre de comparaison, le listing en Go natif pour le même minuscule exemple n’est pas vraiment moins simple, et sera familier à tout gopher.
|
|
Utilisation pratique
D’autres fonctions sont plus utiles, comme la panoplie des fonctions liées aux tableaux PHP, qui n’ont pas d’équivalent natif en Go et sont souvent la partie la plus difficile à convertir lors du passage de PHP à Go.
Le paquet inclut nombre d’entre elles, appliquées à des tranches []interface{}
:
PHP 7.4 | php2go v0.9.4 |
---|---|
array_change_case | |
array_chunk | ArrayChunk |
array_column | ArrayColumn |
array_combine | ArrayCombine |
array_count_values | ArrayFill |
array_diff_assoc | |
array_diff_key | |
array_diff_uassoc | |
array_diff_ukey | |
array_diff | |
array_fill_keys | |
array_fill | |
array_filter | |
array_flip | ArrayFlip |
array_intersect_assoc | |
array_intersect_key | |
array_intersect_uassoc | |
array_intersect_ukey | |
array_intersect | |
array_key_exists | ArrayKeyExists |
array_key_first | |
array_key_last | |
array_keys | ArrayKeys |
array_map | |
array_merge_recursive | |
array_merge | ArrayMerge |
array_multisort | |
array_pad | ArrayPad |
array_pop | ArrayPop |
array_product | |
array_push | ArrayPush |
array_rand | ArrayRand |
array_reduce | |
array_replace_recursive | |
array_replace | |
array_reverse | ArrayReverse |
array_search | |
array_shift | ArrayShift |
array_slice | ArraySlice |
array_splice | |
array_sum | ArrayUnshift |
array_udiff_assoc | |
array_udiff_uassoc | |
array_udiff | |
array_uintersect_assoc | |
array_uintersect_uassoc | |
array_uintersect | |
array_unique | |
array_unshift | |
array_values | ArrayValues |
array_walk_recursive | |
array_walk |
Conclusion
Ce module est un moyen utile pour parvenir à ses fins durant les premiers temps de l’apprentissage de Go, facilitant la migration aux yeux des gestionnaires en permettant de livrer en un temps record des versions converties.
Pour la plupart des besoins, toutefois, il illustre bien la difficulté qu’il y a à migrer d’un langage sans adapter aussi sa façon de travailler:
- PHP est pensé autour du typage dynamique et de ses tableaux à tout faire, qui sont à la fois des tableaux ordinaires et associatifs, et préservent l’ordre d’insertion, sans réel équivalent en Go.
- Go est fortement typé, et convertir un projet de PHP en Go nécessite en général de repenser la conception des données plutôt que de passer par une bibliothèque générique comme celle-ci.
Et un jour, il faut bien changer ses habitudes: autant le faire rapidement.