Gérer les sessions PHP avec Memcached et MySQL
Utiliser Memcached et MySQL pour gérer les sessions PHP est la clef pour la réalisation d'environnement de haute-disponibilité. Cette configuration permet de partager les données de session entre plusieurs serveurs PHP situés derrière un répartiteur de charge. Dans un environnement plus simple, cela permet d'éviter le stockage des sessions sur le système de fichiers. Ce guide décrit la mise en place d'un gestionnaire personnalisé de sessions PHP basés sur une configuration hybride Memcached / MySQL.
Ce guide est testé sur:
- Debian 6.0 Squeeze
- Debian 7.0 Wheezy
Prérequis
Ce guide nécessite:
- une installation fonctionnelle de PHP, telle que décrite par Installer PHP-FPM sur Debian.
- un serveur Memcached, comme décrit par Installer Memcached sur Debian.
- un serveur MySQL, comme décrit par Installer et configurer MySQL sur Debian.
- mysql-tools, l'outil d'administration simplifiée de MySQL sur l'hôte local (et l'hôte du serveur MySQL, si différent).
Paramètres
Renseignez le nom d'hôte du serveur configuré (utilisé pour nommer la base de donnée et la table):
DOMAIN="$(command hostname --fqdn)"
Renseignez le nom d'hôte de votre serveur MySQL (si vous ne savez pas de quoi il s'agit, ne modifiez pas cette valeur):
MYSQL_HOST="localhost"
Si votre serveur MySQL n'est pas local, ce guide effectuera une connexion SSH pour y créer la base de données.
Renseignez le nom d'hôte du serveur Memcached:
MEMCACHED_HOST="localhost"
Installation
Préparation de l'environnement
Installez les logiciels et modules PHP nécessaires à l'installation et au bon fonctionnement de l'application:
command apt-get install php5-mysql php5-memcached apg
Générez des préfixes de table et de champ aléatoires afin d'augmenter la sécurité contre les attaques par injection SQL:
TABLE_PREFIX="$(command apg -q -a 0 -n 1 -M NCL)_"
FIELD_PREFIX="$(command apg -q -a 0 -n 1 -M NCL)_"
Création de la base de données
Créez la base de données :
MYSQL_PARAMS="$(command mysql-tools --server="${MYSQL_HOST}" --with-ssh \
--auto-hosts --db-prefix="php-session" --create "${DOMAIN}")"
Récupérez les paramètres de la nouvelle base de données:
MYSQL_DB="$(echo "${MYSQL_PARAMS}" | command grep -e "^MYSQL_DB" \ | cut --delimiter="=" --fields="2-")" MYSQL_USER="$(echo "${MYSQL_PARAMS}" | command grep -e "^MYSQL_USER" \ | cut --delimiter="=" --fields="2-")" MYSQL_PASSWORD="$(echo "${MYSQL_PARAMS}" | command grep -e "^MYSQL_PASSWORD" \ | cut --delimiter="=" --fields="2-")" echo "${MYSQL_PARAMS}"
Créez la table destinée à contenir les sessions:
command wget 'https://raw.github.com/biapy/howto.biapy.com/master/php5/mysql-memcached-sessionhandler/memcached_mysql_sessionhandler.sql' \
--quiet --no-check-certificate --output-document=- \
| command sed \
-e "s/php_/${TABLE_PREFIX}php_/" \
-e "s/session_/${FIELD_PREFIX}session_/" \
| command mysql --user="${MYSQL_USER}" --password="${MYSQL_PASSWORD}" \ --host="${MYSQL_HOST}" "${MYSQL_DB}"
Configuration de PHP
Détectez le chemin des fichiers de configuration des extensions PHP:
MODS_CONF_PATH='/etc/php5/conf.d'
test -d '/etc/php5/mods-available' \
&& MODS_CONF_PATH='/etc/php5/mods-available'
Créez le dossier destiné à contenir le code de gestion des sessions:
command mkdir --parents '/etc/php5/session-management'
Créez le fichier de configuration de la gestion des sessions:
echo "<?php
/**
* Memcached + MySQL session storage for ${DOMAIN}.
*
* MySQL connection configuration file
*/
abstract class Memcached_MySQL_SessionHandler_Config
{
const MYSQL_HOST = '${MYSQL_HOST}';
const MYSQL_DB = '${MYSQL_DB}';
const MYSQL_USER = '${MYSQL_USER}';
const MYSQL_PASSWORD = '${MYSQL_PASSWORD}';
const TABLE_PREFIX = '${TABLE_PREFIX}';
const FIELD_PREFIX = '${FIELD_PREFIX}';
const MEMCACHED_ID = '${TABLE_PREFIX}';
// Memcached servers list.
// To add multiple Memcached servers use:
// const MEMCACHED_SERVERS='xx.xx.xx.ip:port:weight,xx.xx.xx.ip:port:weight,...'
const MEMCACHED_SERVERS = '${MEMCACHED_HOST}:11211';
}" \
> '/etc/php5/session-management/memcached_mysql_sessionhandler_config.class.php'
Téléchargez le code de gestion des sessions:
command wget 'https://raw.github.com/biapy/howto.biapy.com/master/php5/mysql-memcached-sessionhandler/memcached_mysql_sessionhandler.class.php' \
--quiet --no-check-certificate --output-document='/etc/php5/session-management/memcached_mysql_sessionhandler.class.php'
Créez le fichier prepend.php s'il n'existe pas:
if [ ! -e '/etc/php5/prepend.php' ]; then
command echo '<?php
// This file is prepended at each PHP script.' \
> '/etc/php5/prepend.php'
fi
Ajoutez le chargement de la gestion des sessions avec MySQL et Memcached au fichier prepend.php (activation pour l'ensemble des sites présents sur le serveur):
echo "require('/etc/php5/session-management/memcached_mysql_sessionhandler.class.php');" >> '/etc/php5/prepend.php'
Configurez PHP pour charger le fichier prepend.php au début de chaque requête:
command echo "; Load PHP code at startup.
auto_prepend_file=/etc/php5/prepend.php" \
> "${MODS_CONF_PATH}/prepend-code.ini"
test -n "$(command -v php5enmod)" && command php5enmod 'prepend-code/50'
Si PHPMyAdmin est installé, ajoutez le dossier d'installation à l'option open_basedir:
command test -e '/etc/phpmyadmin/apache.conf' \
&& command sed -i \
-e 's|open_basedir.*|&:/etc/php5/session-management|' \
'/etc/phpmyadmin/apache.conf'
Rechargez la configuration:
test -x /etc/init.d/php5-fpm && /etc/init.d/php5-fpm restart
test -x /etc/init.d/apache2 && /etc/init.d/apache2 force-reload
test -x /etc/init.d/lighttpd && /etc/init.d/lighttpd force-reload
test -x /etc/init.d/nginx && /etc/init.d/nginx force-reload
Remerciements
- Merci à Keboola (en) pour PHP Sessions with Memcached and a Database (Sessions in the Cloud Done Right) (en).
- Merci à Adventures in PHP / DHTML / CSS and MySQL (en) pour Memcache & MySQL PHP Session Handler (en).
- Merci à GitHub (en) pour l'hébergement des sources de ce guide : Handle PHP sessions with Memcached and MySQL (en).