BLOGS
PHP : Il peut le faire !
Depuis quelques billets, je m’attarde sur les nouvelles fonctionnalités majeures de 4D v12 (sortie en juin dernier). Aujourd’hui, passons un instant sur une nouvelle-fonctionnalité-majeure majeure : la commande PHP Executer, qui permet d’exécuter du code PHP.
Bon. Une fois écrit « PHP Executer permet d’exécuter du code PHP », je me rends compte que son nom même disait déjà clairement sa fonction. 4D devrait donner aux commandes des noms à énigme, ça m’éviterait d’écrire de telles évidences. Par exemple, « La commande Executer un script de type Preprocesseur Hyper texte permet d’exécuter du code PHP », là, clairement, on a le sentiment d’apprendre quelque chose.
Avant 4D v12, l’exécution de code PHP depuis une application 4D était possible depuis 2004 (et la version 4D de la même année) via un appel à LANCER PROCESS EXTERNE (petit nom : « LPE »). La comparaison s’arrête là, car PHP Executer est infiniment plus puissant. Voici les 10 raisons qui démontrent cette affirmation (en bleu ce qui est bien, en rouge ce qui l’est moins) :
|
|
|
PHP Executer |
LPE |
|
1 |
Nécessité d’installer PHP |
Non |
Oui1 |
|
2 |
Possibilité d’exécuter un script .php |
Oui |
Non2 |
|
3 |
Interpréteur relancé à chaque appel |
Non |
Oui |
|
4 |
Possibilité d’exécuter une fonction au sein d’un script |
Oui |
Non |
|
5 |
Possibilité de passer des paramètres à la fonction appelée |
Oui |
Non3 |
|
6 |
Possibilité de recevoir un résultat |
Oui |
Partiellement3 |
|
7 |
Possibilité d’exécuter une fonction PHP native (pas de fichier .php nécessaire) |
Oui |
Oui4 |
|
8 |
Peut envoyer des variables d’environnement à l’interpréteur PHP |
Oui |
Non5 |
|
9 |
Est plus puisant que LPE |
Oui |
Non |
|
10 |
Est une des nouvelles fonctionnalités majeures de 4D v12 |
Oui |
Non |
(1) Selon version voulue, oui sous Mac OS
(2) Sauf si PHP installé
(3) Ou laborieux, échange de blob, extraction des infos, …
(4) Mais pas si facilement. Alors je laisse en rouge
(5) Eventuellement via stdin
Trop fort !
Vainqueur par KO : PHP Executer, qui récolte tous les points bleus. Vous l’aurez cependant remarqué : certains traits on été exagérés, d’autres servent juste à mettre plus de bleu. Les deuxième et cinquième points, par exemple, n’ont de sens que si le précédent est acquis. Cependant, au-delà de ces petites blagues de potache, le fait est que PHP Executer, c’est « du lourd » :
- Interpréteur en mode FastCGI fourni (je vais revenir sur les avantages de la compilation en mode FastCGI) => pas besoin d’installer PHP.
- Fonctionne totalement indépendamment du serveur web. Je précise, parce que bien souvent on associe PHP avec le web. Ici, ce n’est pas le cas : la commande fonctionne très bien quand le serveur web de 4D n’est pas lancé. Elle marche tout aussi bien quand il est lancé, bien entendu.
- Possibilité d’appeler une fonction au sein d’un script .php, de lui passer des paramètres, de recevoir un résultat. Ca, c’est du super-lourd ! À ma connaissance, aucun autre outil au monde ne permet d’utiliser PHP avec une telle simplicité : on exécute des scripts entiers, on analyse le résultat renvoyé dans le flux stdout.
En fait, ce n’est pas tellement à ma connaissance. C’est surtout à celle d’Alexandre, mon collègue qui connait tout sur PHP. C’est d’ailleurs avec lui qu’a été développée la fonctionnalité.
- Flexibilité : les préférences et autres appels à FIXER PARAMETRE BASE/PHP FIXER OPTION permettent de modifier le comportement par défaut.
Le monde PHP est tout simplement immense, les possibilités quasi infinies. Avant 4D v12, quand j’avais besoin d’une fonctionnalité qui…
- Soit n’existait tout simplement pas dans 4D
- Soit aurait demandé énormément de temps de développement, de lignes de code, de méthodes, voir de hacks (et aurait alors été difficile à maintenir)
… je me lançais dans la recherche d’un plugin.
Alors que dorénavant, avant de chercher du côté des plugins, je regarderai vers PHP : il y a très fort à parier que je trouverai mon bonheur et que PHP puisse le faire ! Quelques exemples :
- Votre client souhaite une liaison avec LDAP ? PHP peut le faire ! Cf. note technique US « LDAP and v12 » et la documentation du module LDAP de PHP.
- Vous voulez compresser en zip ou analyser le contenu d’une archive ? PHP peut le faire !
- Vous souhaitez créer un hash ? Utiliser SSL avec le SMTP ? Manipuler des images sur disque ? Créer des graphiques incroyables ? Encrypter des données de cartes bancaires pour un site marchand ? Générer des pdf ? PHP peut le faire !
Si on ne connait pas PHP, on peut quand même s’en servir : on récupère le code (des fichiers texte, extension .php), on le place dans un endroit qui va bien (personnellement, c’est dans un dossier « php », à l’intérieur du dossier « Resources » de la base), et c’est tout. Reste à appeler le script qui fait ce dont on a besoin, et/ou la fonction à l’intérieur du script.
Bon, en fait, il faudra parfois regarder un peu les choses, voir écrire soi-même une petite fonction qui va bien, mais la quantité de code que l’on trouve suffit souvent. Je n’ai pas donné le l’exemple du zip par hasard : lorsque vous ouvrez la page de la documentation PHP, vous ne pouvez rater le chapitre « Exemples ». Le premier exemple explique comment créer une archive et lui ajouter des éléments. On repère rapidement ce qui semble important, en l’occurrence quatre routines :

À partir de cet exemple, j’ai écrit le script suivant, rapide, sans contrôle d’erreurs :
function DoZipFile($fileToZipPath, $archivePath)
{
$zip = new ZipArchive();
if ($zip->open($archivePath, ZIPARCHIVE::CREATE))
{
$zip->addFile($fileToZipPath);
$zip->close();
}
}
J’enregistre ce script dans {MaBase}/Resources/php, en le nommant « ZipTools.php » (pluriel : je compte bien ajouter des fonctions).
L’appel depuis 4D est alors simple :
$scriptPath:=Dossier 4D(Dossier Resources courant)+"php"+Séparateur dossier+"Zip_Tools.php"
$filePath:=Convertir chemin systeme vers POSIX(Dossier systeme(Bureau)+"TheTestFileToZip.txt")
$zipPath:=$filePath+".zip"
$ok:=PHP Executer($scriptPath;"DoZipFile";*;$filePath;$zipPath)
Notez au passage l’utilisation de la constante Separateur dossier et de Convertir chemin système vers POSIX. Cool, non ?
Je dois à La Vérité de dire que le code PHP copié-collé-simplifié depuis l’exemple n’a pas fonctionné du premier coup : d’abord, je me suis trompé en supprimant les conditions, j’avais du coup trop d’accolades ouvrantes ou pas assez de parenthèses fermantes. Mais grâce à PHP LIRE REPONSE COMPLETE, j’ai pu identifier chaque fois la ligne en cause. Enfin, avant de tester, n’oubliez pas de créer le fichier à compresser sur le bureau… Je dis ça, hein, c’est l’expérience qui parle, si vous voyez ce que je veux dire !
« Flash Your Charts With PHP »
Prenons un exemple plus évolué. Pendant le 4D Summit 2009, la session « Flash Your Charts With PHP » a fait super-fort. En mixant du code PHP et une Zone Web, voici un exemple de ce qu’il est possible de faire :
La base de démonstration est librement téléchargable ici.
Petite précision utile : un bug de la version 12.0 empêche PHP Execute de fonctionner si 4D a été installé dans le dossier « Program Files » et que l’on n’est pas administrateur de la machine. Le problème est réglé pour la 12.1 (et 12.0F1 pour si vous avez accès au programme des « Hot Fix »). Sinon, vous pouvez « Exécuter en tant qu’administrateur ». Plus d'explications (en anglais) ici : http://kb.4d.com/search/assetid=76116
FastCGI
L’implémentation dans 4D v12 utilise une compilation de PHP en mode « FastCGI ». C’est ce mode qui nous permet d’être bien plus rapide que LPE (la rapidité d’exécution n’étant pas le seul intérêt du FastCGI). En effet, en mode FastCGI, l’interpréteur PHP n’est chargé qu’une seule fois en mémoire, à la première exécution. Le gain de temps lors des prochaines exécutions est considérable, car charger un programme en mémoire, c’est long. Prenons l’exemple du hachage md5 d’un texte. Voici le code utilisant LPE :
1) Script PHP :
echo md5('coucou') ;
?
2) L'appel depuis 4D :
LAUNCH PROCESSE EXTERNE("php -f /Users/thibaud/Desktop/EchoMD5.php";$in;$out;$err)
Note en forme de truc et astuce. On peut obtenir le même résultat sans fichier .php (point 7 du tableau ci-dessus) :
LANCER PROCESS EXTERNE("php -r ‘$foo = md5(\"coucou\");var_dump($foo);";$in;$out;$err)
// Le résultat de var_dump est <string(32) "le md5"
// => il faut retirer le début, string(32) + espace + guillemets
$out:=Sous chaine($out;13;32)
Maintenant, le code faisant appel à PHP Executer :
C_BOOLEEN($ok)
$ok:=PHP EXECUTER("";"md5";$result; "coucou")
Vous voyez comme c’est simple, efficace élégant ? C’est quand même plus classe d’écrire juste "md5" puis $result au lieu du barbare "php -f /Users/thibaud/Desktop/EchoMD5.php", non ?
Quand je lance 100 fois chaque test, les résultats sur mon Mac sont éloquents : LPE prend 10 secondes pour les 100 itérations, PHP Executer ne consomme que 500 ms… Et encore, si je refais le test, le passage par PHP Executer se réduit à 100 ms, 100 fois plus rapide ! Cela est dû au fait qu’au premier appel, 4D lance l’interpréteur en mode fast-cgi. Ce qui prend du temps, comme expliqué plus haut, alors je ne vais pas redire que c’est à cause des initialisations, du chargement des librairies et ressources système, etc. Ah tiens si, je l’ai redit finalement. Tant pis. Continuons. Mais seul le premier appel est impacté, les suivants trouveront un interpréteur PHP/fastcgi déjà prêt.
D’un autre côté, à chaque appel de LPE, 4D charge le shell (nous sommes sur Mac) qui s’initialise, puis le shell charge l’exécutable PHP qui s’initialise, puis le script est exécuté, PHP est déchargé, le shell est déchargé. Et hop ! On recommence tout au prochain appel.
Notez que le même test lancé sur Windows montre que PHP Executer est « seulement » 20 fois plus rapide que LPE. C’est parce que Windows n’a pas de Shell – au sens unix du terme – à initialiser, et aussi parce que les initialisations et chargements des ressources système sont très optimisées. Mais 20 fois plus rapide, quand même, ça vous pose une comparaison.
La fin des plugins ?
Compte tenu de la richesse du monde PHP et de la facilité avec laquelle on peut trouver sur internet des bibliothèques de code (la plupart du temps gratuit et utilisable, mais il convient bien entendu de soigneusement vérifier que le code trouvé peut être librement ajouté à nos applications), on peut imaginer que certains besoins en plugins vont diminuer. D’autant plus que relire du code PHP quand on ne connait pas PHP, c’est plus facile que relire du code C++ quand on ne connait pas le C++.
L’intertitre sur « La fin des plugins » est toutefois surtout provocateur. Non seulement les plugins utilisés pour l’interface (4D Write, Canvas, ALP, hmCal, …) ne peuvent pas être remplacés par du PHP (encore que, finalement, je n’ai jamais essayé), mais aussi, PHP étant un langage de script, interprété, si la vitesse d’exécution est critique, il faudra alors peut-être s’appuyer encore sur un plugin. Ou sur du code 4D compilé. En reprenant l’exemple du hachage md5 vu plus haut, la boucle de 100 itérations est exécutée en 2 ms par un plugin (ici, MD5 Plugin de Pluggers Software, gratuit, http://www.pluggers.nl/) et 12 ms par du code 4D compilé (en interprété on reste loin derrière PHP : 2 500 ms). Si vous calculez un md5 ans un trigger, n’hésitez pas une seule seconde : utilisez un plugin !
Voilà, c’est tout pour ce blog. Il a été long… Je vais m’efforcer de faire plus court pour les prochains, mais là, j’ai deux excuses : d’une part, PHP Executer, c’est immense. Je n’ai fait qu’aborder quelques points. On pourrait tenir des pages et des pages avec ça. D’autre part, je file me reposer une semaine : siestes, jeux, piscine, repos, repas, Mojito, piscine, etc…
À dans deux ou trois semaines.














Poster un nouveau commentaire