Posts tagged “c”.

Une version optimisée pour PHP de JSMin

Les Javascripts permettent de faire tout pleins de choses sur un site web, c’est cool. Mais à force d’empiler les librairies, les frameworks et autres fonctions, on peut vite se retrouver avec deux kilo-tonnes de script, ce qui n’est ni très agréable à charger et ni très léger pour la bande passante.

Heureusement, plusieurs librairies (plus ou mois efficaces) existent et permettent de compresser les scripts. JSMin est l’une d’entre elle.

More… »

Mon premier programme C/PHP

Comment embarquer PHP dans un programme C de la manière la plus basique possible.

Hello world

En guise d’”Hello World”, nous allons essayer d’executer la commande phpinfo().

Avant tout, il faut initialiser le module php embed. Tout ceci n’étant absolument pas documenté, je ne saurais dire à quoi correspondent les paramètres.

static char *argv[2] = {"monboprog", NULL};
if ( php_embed_init(1, argv PTSRMLS_CC) == FAILURE ) {
	puts ("Impossible d'initialiser PHP");
	return -1;
}

Maintenant on peut executer une commande. On utilise zend_eval_string qui prend comme premier paramètre la commande à executer. Je ne sais pas à quoi correspond le deuxième (je laisse NULL). Quant au dernier, apparement on peut mettre n’importe quoi… Allez comprendre !

Zend (le parseur php) fournis des macros imitant le try-catch du C++, permettant de recuperer les erreurs de php. Il n’y a donc qu’à les utiliser. Et voila ce que ça donne :

zend_first_try {
	if ( zend_eval_string("phpinfo();", NULL, "php embed roulez") == SUCCESS )
		puts("Commande executée avec succès");
	else
		puts("Impossible d'executer la commande");
} zend_catch {
	printf ("Exception %d", EG(exit_status));
}
zend_end_try();

Enfin, on arrette php avec la commande suivante :

php_embed_shutdown(TSRMLS_C);

Il ne manque plus qu’à inclure php_embed.h, et on peut essayer de le compiler. Le programme complet d’exemple est disponible par ici

Compilation

Ca c’est la partie la plus galère, surtout quand rien n’est documenté. Je tiens d’ailleurs à remercier kermit, une star du Makefile, sans qui je ne serais sans doute jamais arrivé à compiler cette saloperie de programme.

En fait, php_embed.h demande pleins d’autres fichiers d’entetes, situés un peu partout dans les sources de PHP. Il faut donc rajouter un paquet de paramètres d’inclusion à gcc. Dans un makefile, ça donne :

# chemin des sources de php
PHPPATH=/home/cgo2/documents/prog/php/php-5.0.2
PHPFLAGS=-I$(PHPPATH) -I$(PHPPATH)/Zend -I$(PHPPATH)/TSRM -I$(PHPPATH)/sapi/embed

Pour le linkage, il faut utiliser la lib que l’on a compilé :

LDFLAGS=-L$(PHPPATH)/libs LIBS=-lphp5

Le makefile pour ce programme d’exemple n’est pas encore parfait, puisque trop de paramètres sont hardcodés, mais bon…

Exécution

Premier test :

 $ ./monboprog ./monboprog: error while loading shared libraries: libphp5.so: cannot open shared object file: No such file or directory 

Pas grave, il suffit d’ajouter le chemin de la libs dans la variable d’environnement qui va bien :

 $ export LD_LIBRARY_PATH=~/documents/prog/php/php-5.0.2/libs/ 

Et voila :)

Conclusion

Il reste encore beaucoup à faire pour pouvoir embarquer facilement php : faciliter la compilation et le linkage (tout le monde n’a pas les sources de php sous la main), et également l’execution. Quant au code, dans un premier temps un découpage en fonctions permettant d’eviter de manipuler Zend directement s’impose. Il faut ensuite voir comment inclure des fichiers php, exporter des fonctions C pour les utiliser dans les scripts, etc… Mais au moins avec cet exemple vous pourrez dire : “moi aussi j’ai réussi à embarquer php” !

Quelques liens

  • LE programme sans lequel on aurait rien reussi : le module php-irssi qui permet de script irssi avec php. Malheureusement il n’y a aucun site officiel, et le projet semble mort. On peut encore recuprer les sources sur le CVS de php
  • Un PDF interressant par l’auteur de php-irssi