Le client

Aujourd’hui je me suis retrouvé face à un problème extrêmement intéressant! Un client m’a contacté car il rencontrait un problème étrange… “La sauvegarde des menus ne fonctionnent plus dans l’administration !” me dit-il sur un ton qui sous-entend que j’ai encore fait quelque chose que je n’aurais pas dû (non non, promis, c’est pas moi!).

Constatation du problème

Après investigation, j’ai constaté que la sauvegarde fonctionnait pour les entrées existantes du menu, mais que Wordpress refusait obstinément de sauvegarder les nouvelles entrées. Cela ressemble étrangement à une limite de Wordpress, genre “Wordpress a décidé que vous ne pouvez pas avoir plus de 70 entrées dans un menu”.

Un peu de théorie

Et bien en fait, non, rien à voir… Le problème ne vient pas de Wordpress, mais plutôt de la configuration de votre PHP! Mais commençons par le début…

Une entrée d’un menu possède un certain nombre de propriétés, parmis lesquelles son nom, son attribut html title, l’option target, la ou les classes css, et encore deux ou trois autres trucs. Au minimum, une entrée d’un menu aura 6 propriétés, sans compter les ID’s et autres propriétés propres à l’utilisation de Wordpress! Vous l’avez maintenant compris, pour un gros menu, on arrive facilement à un nombre conséquent de propriétés.

La responsable

Lorsque vous sauvegardez un menu dans l’administration de Wordpress, toutes ces propriétés vont être placées dans des tableaux PHP (array) pour ensuite être envoyées au serveur via une requête POST. Hors, il se trouve que depuis PHP 5.3.9, une nouvelle option a fait son apparition. Elle s’appelle max_input_vars et est probablement la responsable de la disparition de vos entrées!

max_input_vars est une option qui permet de limiter le nombre de tableaux envoyés dans une requête POST. Cette option est souvent limitée à 1000, ce aui semble suffisant pour une utilisation courante de PHP. Dans le cas de Wordpress, si votre menu possède au minimum 60-70 entrées, cette limite sera rapidement atteinte, et PHP ignorera tout ce qui se trouve après. PHP émet bien un Warning si la limite est atteinte, mais la plupart des sites en production n’affichent pas les warning et les stockent dans des fichiers logs. Et un utilisateur Wordpress, quand il sait ce qu’est un fichier log (ce qui n’est pas gagné…), ne pensera pas forcément à aller analyser le contenu de ses logs!

La solution

Nous savons donc maintenant comment fonctionne la sauvegarde des menus (plein de tableaux contenant les propriétés des menus et de leurs entrées dans une requête POST). Nous savons également que PHP, depuis sa version 5.3.9, possède une option qui limite le nombre de tableaux dans une requête POST. Bien! Maintenant il ne nous reste plus qu’à régler le problème…

Et régler le problème est extrêmement simple… ou pas:

  • Vous avez accès au fichier php.ini Dans ce cas, super simple! Il vous suffit d’ajouter cette ligne dans votre fichier php.ini (ou de modifier la ligne existante si elle s’y trouve déjà ):
1
max_input_vars = 3000
  • Vous n’avez pas accès au fichier php.ini Pas de panique, vous avez deux solutions:

    • Vous avez accès au fichier .htaccess Ajouter la ligne suivante dans votre fichier .htaccess:
1
php_value max_input_vars 3000

Attention: il semblerait que la modification du fichier .htaccess soit délicate… Je me suis retrouvé avec un site complet en erreur 500! J’ai donc préféré la méthode suivante:

  • Créez un fichier php.ini dans le répertoire wp-admin et ajoutez-y la ligne suivante:
1
max_input_vars = 3000
  • Ca ne marche toujours pas

Avant l’utilisation de l’option max_input_vars, de nombreux hébergeurs utilisaient un module de sécurité appelé Suhosin PHP Security. Tout ce qui a été dit précédemment reste d’actualité, mais le contenu des fichiers php.ini et/ou .htaccess sont différents:

  • php.ini
1
2
3
4
5
6
# nouvelle option à partir de php 5.3.9
max_input_vars = 3000

    # module Suhosin PHP Security
suhosin.post.max_vars = 3000
suhosin.request.max_vars = 3000
  • .htaccess
1
2
3
4
5
6
# nouvelle option à partir de php 5.3.9
php_value max_input_vars 3000

    # module Suhosin PHP Security
php_value suhosin.post.max_vars 3000
php_value suhosin.request.max_vars 3000

Quelques nouvelles

Bien…. Ca fait plus de 5 mois que je n’ai plus rien posté sur ce blog, la honte! Pourtant les idées se bousculent au portillon…## Ce qu …… Continuer la lecture