Installer PECL:UploadProgress et memcache avec macports

  • warning: array_map(): Argument #2 should be an array in /var/www/titouille.ch/www/modules/system/system.module on line 1050.
  • warning: array_keys() expects parameter 1 to be array, null given in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
  • warning: Invalid argument supplied for foreach() in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
Portrait de titouille

MacPorts est vraiment un outil génial lorsqu'on sait l'utiliser.

Depuis pas mal de temps, j'installe des sites sur mon ordinateur en local pour pouvoir travailler tranquillement avant de passer le tout sur un quelconque serveur distant.

Avec Drupal, si je vais sur la page de rapport du statut d'un site (admin/reports/status) j'ai toujours le même avertissement dans la section "Upload Progress" qui m'indique que si j'installe PECL::uploadprogress, les phases de téléchargement de fichiers pourront être affichées à l'utilisateur. Typiquement, lorsque je rajoute une image à un contenu via imagefield, une barre de progression m'indiquera l'état d'avancement du téléchargement. Même si ce n'est pas primordial lorsque je travaille en local, j'aime bien faire les choses proprement. C'est pourquoi je me suis penché sur ce petit problème.

Après avoir fait des recherches sur le net, je suis d'abord tombé sur un thread expliquant comment installer uploadprogress en téléchargeant les sources, puis en les compilant directement à partir du terminal pour installer le fichier .so tant convoité.

La manipulation est simple (voir ici l'explication complète) :

# prepares the PHP extension for compiling
$ phpize
 
$ ./configure
$ make
$ sudo make install

Simple, oui... Malheureusement, comme l'explique l'auteur du message, il est nécessaire ensuite de modifier le chemin de la variable extension_dir dans le fichier php.ini.
Le problème, c'est que j'ai installé apache, mysql et php avec macports, et les extensions php se trouvent dans /opt/local/lib/php/extensions/no-debug-non-zts-20090626. Ne connaissant pas tout des rouages internes de macports, j'imagine qu'il a fait en sorte qu'apache / php pointe vers ce répertoire pour aller chercher les extensions, sans avoir besoin de le spécifier explicitement dans le php.ini.

Ne voulant pas modifier la variable extension_dir pour la faire pointer vers /usr/lib/php/extensions/no-debug-non-zts-20060613 (là où l'extension a été compilée manuellement avec les commandes citées ci-dessus) je me suis demandé si par hasard macports ne pourrait pas faire le job à ma place. Comme j'ai tout installé avec macports, si uploadprogress est installable également, il me le placera certainement dans le même répertoire que les autres extensions (sous /opt/local/lib/php/...)

C'est donc parti pour un petit test :

cd /opt/local/bin
sudo ./port search upload

me retourne la liste suivante :

commons-fileupload @1.2.1 (java)
    Jakarta Commons-FileUpload
 
gpsbabel @1.3.6 (textproc, comms)
    GPSBabel converts/uploads GPS waypoints, tracks, and routes
 
p5-flickr-upload @1.22 (perl)
    Upload images to flickr.com
 
php5-uploadprogress @1.0.1 (php, www, devel)
    An extension to track progress of a file upload.
 
subdownloader @2.0.9.3 (multimedia)
    Automatically download and upload subtitles for videos
 
usbprog @0.1.8 (cross)
    Tool for uploading and downloading firmwares to the usbprog device
 
wput @0.6.2 (net)
    wput is like wget but is for uploading files to ftp-servers
 
Found 7 ports.

Yes, php5-uploadprogress s'y trouve, que du bonheur. Je n'ai plus qu'à lancer la commande

sudo ./port install php5-uploadprogress

et la librairie uploadprogress est installée comme par magie dans le répertoire correct, avec les autres extensions installées par macports.
Je n'ai même pas eu besoin de modifier le php.ini pour y rajouter la ligne extension=uploadprogress.so. Comme cité plus haut, macports à du configurer apache pour qu'il aille automatiquement charger toutes les extensions qui sont dans le répertoire des extensions. Je n'ai plus qu'à redémarrer apache avec

sudo /opt/local/apache2/bin/apachectl restart

et Drupal ne bronche plus concernant cette lib.

Dans le même ordre d'idée, j'avais besoin d'installer la librairie memcached car un site sur lequel je dois travailler nécessite un bon système de mise en cache.

Après quelques recherches je suis tombé sur un thread explicatif, et plus précisément sur un commentaire à propos de cette librairie installée avec macports.

En suivant l'explication, j'ai pu installer PORT::memcached et PECL::memcache de manière très simple. Seul problème, encore une fois, la librairie a été installée sur /usr/lib/php/extensions/no-debug-non-zts-20060613/ alors que j'aurais aimé l'avoir sous /opt/local/lib/php/extensions/...

En faisant encore quelques tests, je me suis rendu compte que je pouvais installer memcached ET php5-memcache avec macports, ce que je me suis empressé de faire :

cd /opt/local/bin
sudo ./port install memcached
 
# optionnel : activation automatique au démarrage
sudo launchctl load -w /Library/LaunchDaemons/org.macports.memcached.plist
 
sudo ./port install php5-memcache

Finalement, redémarrage de l'ordinateur et tout me semble ok. Encore quelques messages d'erreur dans Drupal qui m'indique que memcache n'arrive pas à se connecter sur les ports autres que celui par défaut (11211).
Il est nécessaire de démarrer des instances de memcache sur les différents ports qui sont utilisés dans la configuration, dans mon cas les ports 11212, 11213 et 11214.

Je balance donc les lignes suivantes dans mon terminal :

cd /opt/local/bin
./memcached -m 24 -p 11212 -d
./memcached -m 24 -p 11213 -d
./memcached -m 24 -p 11214 -d

Et finalement les messages d'erreur disparaissent, yes ! Malheureusement, executer cette action ne rend pas les instances permanentes. Après chaque redémarrage, il est nécessaire de re-exécuter cette manip. Ce qui n'est pas très "user-friendly".

Après m'être un peu cassé les dents sur le problème, j'ai fini par trouver la solution. Memcached possède un "démon" qui est lancé en arrière-plan à chaque démarrage (souvenez-vous de la ligne "optionnelle"

# optionnel : activation automatique au démarrage
sudo launchctl load -w /Library/LaunchDaemons/org.macports.memcached.plist

lors de l'installation de memcached).

Via le Finder, je suis allé rechercher ce fichier, qui n'est en réalité qu'un alias. Click-droit et "Afficher l'original" me ramène dans le répertoire /opt/local/etc/LaunchDaemons/org.macports.memcached/ qui contient 2 fichiers. C'est memcached.wrapper qui m'intéresse. Je l'affiche avec mon éditeur de texte pour voir son contenu. Ce dernier ressemble à ceci :

#!/bin/sh
# MacPorts generated daemondo support script
 
# Init
prefix=/opt/local
 
# Start
Start()
{
	/opt/local/bin/memcached -u nobody -m 64 -c 10240 -p 11211 -d
}
 
# Stop
Stop()
{
	/usr/bin/killall memcached
}
 
# Restart
Restart()
{
	Stop
	Start
}
 
# Run
Run()
{
case $1 in
  start  ) Start   ;;
  stop   ) Stop    ;;
  restart) Restart ;;
  *      ) echo "$0: unknown argument: $1";;
esac
}
 
# Run a phase based on the selector
Run $1

vous l'aurez surement compris. La partie "Start()" contient une ligne qui ressemble étrangement aux lignes que j'avais exécutées dans mon terminal pour activer les instances sur les différents ports. J'ai finalement simplement dupliqué cette ligne à 4 reprises et modifié ce qui était nécessaire pour activer les instances sur 4 ports au lieu d'un seul :

Start()
{
	/opt/local/bin/memcached -u nobody -m 64 -c 10240 -p 11211 -d
	/opt/local/bin/memcached -u nobody -m 64 -c 10240 -p 11212 -d
	/opt/local/bin/memcached -u nobody -m 64 -c 10240 -p 11213 -d
	/opt/local/bin/memcached -u nobody -m 64 -c 10240 -p 11214 -d
}

Restera encore à voir si les arguments passés pour chaque lignes sont cohérents avec mes besoins, mais cette fois, ça roule. Je redémarre mon mac, les instances existent toujours sur les différents ports. Cette fois c'est la bonne Smile