Matt Biscay: développeur WordPress et WooCommerce pour SkyMinds
PHP : résoudre l'erreur

PHP : résoudre l’erreur Apache “child pid xxxx exit signal Segmentation fault (11)”

php-logo

J’ai découvert dernièrement qu’après une mise à jour du module php-apc, mes logs Apache étaient emplis de message d’erreur comme ceux-ci :

[Sun Nov 02 09:15:11 2014] [notice] child pid 5937 exit signal Segmentation fault (11)
[Sun Nov 02 09:17:36 2014] [notice] child pid 5586 exit signal Segmentation fault (11)
[Sun Nov 02 09:21:50 2014] [notice] child pid 6230 exit signal Segmentation fault (11)
[Sun Nov 02 09:21:51 2014] [notice] child pid 6388 exit signal Segmentation fault (11)
[Sun Nov 02 09:21:52 2014] [notice] child pid 6228 exit signal Segmentation fault (11)
[Sun Nov 02 09:21:53 2014] [notice] child pid 6235 exit signal Segmentation fault (11)
[Sun Nov 02 09:21:54 2014] [notice] child pid 6392 exit signal Segmentation fault (11)
[Sun Nov 02 09:21:55 2014] [notice] child pid 6385 exit signal Segmentation fault (11)

Cela en fait des erreurs !

Augmenter la taille de la limite de mémoire PHP

Sur le serveur, APC est configuré pour utiliser un unique segment de 128 Mo. Le problème, c’est que la directive memory_limit de PHP est elle aussi à 128 Mo. Par conséquent, il convient d’augmenter cette dernière :

1. On édite notre fichier de configuration PHP :

nano /etc/php5/apache2/php.ini

2. On recherche (Ctrl + w) le mot clé memory_limit et on remplace:

; Maximum amount of memory a script may consume (128MB)
; http://php.net/manual/en/ini.core.php#ini.memory-limit
memory_limit = -1

par

; Maximum amount of memory a script may consume (128MB)
; http://php.net/manual/en/ini.core.php#ini.memory-limit
; memory_limit = -1
memory_limit = 256M

3. On enregistre la nouvelle configuration et on relance Apache :

service apache2 restart

Vérifiez maintenant les logs Apache. Cela peut ne pas être suffisant.

Désinstaller APC

Dans mon cas, avec PHP 5.4.x, APC semble générer ces erreurs de manière aléatoire. J’ai donc désactivé APC avec :

apt-get remove php5-apc

Après relance du serveur Apache et analyse des logs, la situation est revenue à la normale :

Apache PHP/5.4.34 configured -- resuming normal operations

Le problème viendrait donc d’APC et de PHP 5.4 – il est important de noter que PHP 5.5 contient déjà un optimiseur de code intégré (Zend) donc à la prochaine mise à jour majeure de PHP, il sera inutile d’installer APC.

PHP: résoudre l'erreur

PHP : résoudre l’erreur “it is not safe to rely on the system’s timezone settings”

php-logo

Voici le message d’erreur PHP qui est apparu récemment dans mes logs Apache :

PHP Warning: strtotime(): It is not safe to rely on the system’s timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone ‘UTC’ for now, but please set date.timezone to select your timezone.

Ajout de la directive date.timezone dans php.ini

On commence par trouver le fichier php.ini qui est actuellement utilisé par le serveur. Il en existe plusieurs, suivant les modules activés donc on commence par repérer le bon avec :

php -i | grep 'Configuration File'

Résultat :

Configuration File (php.ini) Path => /etc/php5/cli
Loaded Configuration File => /etc/php5/cli/php.ini
PHP Warning:  Unknown: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in Unknown on line 0

Effectivement, l’erreur est répétée même dans un simple phpinfo(). On édite donc notre fichier :

nano /etc/php5/cli/php.ini

La page de manuel des timezones nous indique toute la liste des fuseaux horaires disponibles. Nous choisissons celle qui correspond à l’emplacement de notre serveur : ‘Europe/Paris’.

On recherche la bonne directive avec Ctrl + W et en tapant :

date.

On trouve alors :

[Date]
; Defines the default timezone used by the date functions
; http://php.net/manual/en/datetime.configuration.php#ini.date.timezone
;date.timezone =

qu’il faut modifier en :

[Date]
; Defines the default timezone used by the date functions
; http://php.net/manual/en/datetime.configuration.php#ini.date.timezone
date.timezone = 'Europe/Paris'

On relance Apache pour prendre en compte la nouvelle configuration :

service apache2 restart

Lire la suite

PHP : résoudre l'erreur

OVH : activer PHP-FPM sur les offres mutualisées

php-logoOVH est en pleine implémentation du module PHP-FPM sur ses offres, (et ici dans leur guide), ce qui permettrait selon la team OVH “d’accélérer les temps de réponses de PHP et d’obtenir des performances jusque 7 fois plus rapides dans nos labos par rapport au moteur actuel”.

Activation de PHP-FPM

Pour activer ce mode sur votre offre, il suffit de créer un fichier .ovhconfig à la racine de l’arborescence FTP, dans le dossier parent du répertoire /www.

Si vous souhaitez activez PHP 7, voici ce que doit contenir votre .ovhconfig:

app.engine=php
app.engine.version=7.0
http.firewall=none
environment=production

Si vous souhaitez activez PHP 5.6, voici ce que doit contenir votre .ovhconfig:

app.engine=php
app.engine.version=5.6
http.firewall=none
environment=production

Explication des variables du fichier

; ovhconfig
;
; this file must be placed in $DOCUMENT_ROOT/.ovhconfig
; see examples on our guide: //TODO//

; __app.engine__
;
; values: php (php engine + opcache accelerator)
; notice: if php, a phpcgi engine will be activated as fallback (if previous engine crash)
;
;   php:
;       IMPORTANT: register_globals and magic_quotes_gpc are off for security
;       php optiones .htaccess (like php version) are ignored
;   phpcgi:
;       IMPORTANT this is a fallback or previous system
;       in this case __app.engine.version__ will be considerated as AUTO and php version will be old system
;       (meaning depending .htaccess or .phpX extension)
;
app.engine=php

; __app.engine.version__ specify version of your engine
;
; for php:
;   default: 5.4
; for phpcgi:
;   this options is ignored (= fallback in AUTO)
;
app.engine.version=7.0

; __http.firewall__ used to add application firewall  (filter http requests)
;
; values: none | security
; default: none
;
http.firewall=none

; __environment__
;
; values: production | development
;
;   production:
;       apache will maximise local cache
;       mod_expires will grow up TTL of js, css, pdf, images, video, audio
;       you can override it changing expiration explicitly or in your .htaccess
;       feel free to look on our guide.
;   development:
;       no expiration is added, files are not locally in cache,
;       will speed up tests but decrease performances
;
; choosen environment will also be available in your variable ENVIRONMENT unix env
;
; default: production
;
environment=production

La version actuelle du moteur PHP-PFM est la 5.4 par défaut mais mieux vaut installer la 5.6 pour bénéficier des mises à jour et optimisations. Notez qu’avec ce mode et pour des raisons de sécurité, les options suivantes sont désactivées (options dépréciées par php):

  • register_globals
  • magic_quotes_gpc

Testé et approuvé sur plusieurs pack mutualisés. PHP7 apporte un véritable gain de performance dans le traitement et le rendu des pages.

WordPress : récupérer la liste emails des membres et commentateurs photo

WordPress : afficher la date en français dans le thème (sans utiliser le pack de langue ou setlocale())

Wordpress icon

Cela fait des années que j’utilise le même thème graphique pour mon site et je n’ai jamais vraiment pris le temps de traduire la date de publication ou de mise à jour des articles en français.

Le tutoriel qui suit ne s’adresse qu’à un cercle réduit de développeurs : il est évidemment bien plus aisé d’installer WordPress en français (avec le langage pack qui convient) ou d’utiliser la fonction PHP setlocale() comme je l’avais fait précédemment avec WP-Date FR.

Dans mon cas bien précis, je n’ai pas accès aux locales étant donné que le serveur est installé en anglais.

Je ne souhaite pas non plus installer la locale française, qui serait alors ajoutée à tous mes paquets Debian.

Et je ne souhaite pas non plus utiliser la traduction française de WordPress. It’s coding time !

La fonction sky_date_french()

Vous pouvez placer cette fonction dans le fichier functions.php de votre thème :

/*
|-----------------------------------------------------------------------
| Sky Date in French by Matt - www.skyminds.net
|-----------------------------------------------------------------------
|
| Returns or echoes the date in French format (dd/mm/YYYY) for WordPress themes.
|
*/
function sky_date_french($format, $timestamp = null, $echo = null) {
	$param_D = array('', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim');
	$param_l = array('', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche');
	$param_F = array('', 'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre');
	$param_M = array('', 'Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jun', 'Jul', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc');
	$return = '';
	if(is_null($timestamp)) { $timestamp = mktime(); }
	for($i = 0, $len = strlen($format); $i < $len; $i++) {
		switch($format[$i]) {
			case '\\' : // fix.slashes
				$i++;
				$return .= isset($format[$i]) ? $format[$i] : '';
				break;
			case 'D' :
				$return .= $param_D[date('N', $timestamp)];
				break;
			case 'l' :
				$return .= $param_l[date('N', $timestamp)];
				break;
			case 'F' :
				$return .= $param_F[date('n', $timestamp)];
				break;
			case 'M' :
				$return .= $param_M[date('n', $timestamp)];
				break;
			default :
				$return .= date($format[$i], $timestamp);
				break;
		}
	}
	if(is_null($echo)) { return $return;} else { echo $return;}
}

Lire la suite

WordPress : récupérer la liste emails des membres et commentateurs photo

WordPress : retourner et exécuter un shortcode dans une fonction

Wordpress icon

Pour les besoins du Centre de Kriya Yoga France, j’ai écrit une fonction qui doit afficher une vidéo automatiquement.

Or je voulais juste renvoyer un shortcode vidéo qui prendrait en charge toute la partie code du lecteur vidéo.

On ne peut pas juste renvoyer la valeur, il faut utiliser la fonction do_shortcode() de WordPress.

Cas 1 : exécuter un shortcode dans une fonction

La solution réside dans l’utilisation de la fonction do_shortcode(). Voici un petit exemple :

<?php
/*
|-----------------------------------------------------------------------
| Sky Show Video by Matt - www.skyminds.net
|-----------------------------------------------------------------------
|
| Returns shortcode to be executed in WordPress.
|
*/
function sky_show_video($content) {
   // do stuff
   // return video
   return do_shortcode("[video src='$vid_url' width='600' height='480' type='video/mp4' preload='true']");
}

Cet exemple exécute le shortcode [video].

Lire la suite

PHP : résoudre l'erreur

PHP : résoudre l’erreur “Creating default object from empty value”

php-logo

Suite à la mise à jour de PHP, mon fichier d’erreurs du site a commencé à afficher le message suivant :

PHP Warning: Creating default object from empty value in /wp-content/themes/skyminds/functions.php on line 1213

La ligne en question correspond à :

$posts[0]->comment_status = 'closed';

Le problème réside dans le fait que $posts n’est pas explicitement défini et comme les versions récentes de PHP tournent maintenant avec le mode E-STRICT par défaut, on obtient une erreur. Il existe deux solutions – soit mettre :

$posts = new stdClass();

s’il sagit d’un objet, soit mettre :

$posts = array();

s’il s’agit d’une associative array, juste avant la ligne de code incriminée. Dans mon cas, l’array() est la bonne solution.

Serveur dédié : installation d'Apache, PHP, MySQL et Webmin photo

Serveur dédié : des paquets LAMP à jour sous Debian

Problème : des paquets vieillots

Lorsque votre serveur tourne sous Debian, les paquets sont éprouvés mais souvent datés. Ils tournent bien mais on ne peut pas vraiment bénéficier des versions les plus actuelles pour Apache, MySQL ou PHP par exemple.

La solution : ajouter un nouveau dépôt pour LAMP

La solution est tout simple, il suffit d’ajouter un nouveau dépôt, Dotdeb, qui permet de mettre à jour les paquets libmemcached, mysql, nginx, percona-toolkit, php5, php5-pecl, pinba-engine, redis, ruby-passenger, zabbix.

On édite donc notre liste :

nano /etc/apt/sources.list

et on ajoute les dépôts de Dotdeb, qui sont maintenus à jour par Guillaume Plessis :

deb http://packages.dotdeb.org stable all
deb-src http://packages.dotdeb.org stable all

et enfin, on ajoute la clé GPG :

wget http://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | apt-key add -

La mise à jour se fait comme d’habitude :

apt update && apt upgrade

Lire la suite

Sommaire de la série Monter un serveur dédié de A à Z

  1. Serveur dédié : installation d’Apache, PHP, MySQL et Webmin
  2. Serveur dédié : créer la base de données MySQL et importer WordPress
  3. Serveur dédié : créer et activer un Virtual Host sous Apache
  4. Serveur dédié : changer les DNS du nom de domaine et le faire pointer vers le serveur
  5. Serveur dédié : sécurisation des services avec iptables et fail2ban
  6. Serveur dédié : sécurisation de la couche TCP/IP
  7. Serveur dédié : création d’un serveur mail Postfix (sécurisé avec Saslauthd et certificat SSL) et Courier (accès POP et IMAP) utilisant une base MySQL d’utilisateurs/domaines virtuels
  8. Serveur dédié : sécuriser Apache 2 avec ModSecurity
  9. Serveur dédié : CHMOD récursif sur des fichiers ou répertoires en ligne de commande
  10. Serveur dédié : installer APC comme système de cache et configurer Varnish comme reverse-proxy pour Apache pour améliorer les performances
  11. Serveur dédié : afficher la véritable IP derrière un reverse-proxy comme Varnish
  12. Serveur dédié : intégrer SSH à WordPress pour mettre à jour le core, les plugins et les thèmes
  13. Serveur dédié : installer la dernière version d’APC par SVN
  14. Serveur dédié : analyse des performances du serveur
  15. Serveur dédié : mettre à jour le noyau Debian de la Kimsufi
  16. Serveur dédié : sauvegarde automatique des fichiers avec Backup Manager sur le serveur de sauvegarde OVH
  17. Serveur dédié : configurer la limite mémoire pour PHP et Suhosin
  18. Bash : supprimer tous les fichiers et sous-répertoires d’un répertoire
  19. Serveur dédié : impossible de se connecter à un port distant
  20. Rsync: rapatrier les fichiers du serveur à la maison
  21. Bash : réparer les tables MySQL en cas de crash
  22. Serveur dédié : création d’une seedbox avec Transmission
  23. Serveur dédié : des paquets LAMP à jour sous Debian
  24. Serveur dédié : mise à jour vers Debian 7 Wheezy
  25. Serveur dédié : activer X11 forwarding pour SSH
  26. Serveur dédié : optimiser toutes les images JPG et PNG avec OptiPNG et JpegOptim
  27. Postfix : résoudre l’erreur “fatal: www-data(33): message file too big”
  28. Serveur dédié : mise en place de l’IPv6
  29. WordPress : accorder les bonnes permissions aux fichiers et dossiers avec chown et chmod
  30. WordPress : héberger les images sur un sous-domaine
  31. Serveur dédié : ajouter l’authentification SPF, Sender-ID et DKIM à Postfix et Bind9 avec opendkim
  32. Apache : lorsque le domaine seul (sans WWW) renvoie une erreur 403
  33. Serveur dédié : sécuriser Apache avec HTTPS (HTTP avec la couche TLS/SSL) en Perfect Forward Secrecy
  34. Serveur dédié : passer WordPress en HTTPS (TLS/SSL)
  35. Serveur dédié : configurer Webmin en TLS avec un certificat SSL
  36. Serveur dédié : configurer Transmission pour accéder au WebUI via TLS-SSL
  37. Serveur dédié : installer et configurer Varnish 4
  38. Serveur dédié : passage au mod FastCGI et PHP-FPM avec Apache MPM Worker
  39. Récupérer un serveur Kimsufi après un plantage de kernel avec le mode rescue OVH
  40. Serveur dédié : configurer Postfix et Courier pour utiliser TLS-SSL en Perfect Forward Secrecy
  41. Serveur dédié : retirer Varnish, devenu inutile avec HTTPS
  42. Serveur dédié : installer la dernière version d’OpenSSL sous Debian
  43. Serveur dédié : activer l’IP canonique du serveur sous Apache
  44. Serveur dédié : mise à jour vers PHP 5.6
  45. MySQL : convertir les tables MyISAM au format InnoDB
  46. Serveur dédié : optimiser toutes les images GIF avec GIFsicle
  47. Serveur dédié : migration de MySQL vers MariaDB
  48. BASH : lister, bloquer et débloquer des adresses IP avec iptables
  49. Serveur dédié : produire une meilleure réserve d’entropie avec haveged
  50. Serveur dédié : mettre en place DNSSEC pour sécuriser les DNS du domaine
  51. Serveur dédié : mise en place du protocole DANE
  52. 8 règles d’or pour bien déployer DNSSEC et DANE
  53. Serveur dédié : installer PHP7 FPM avec FastCGI sous Debian
  54. Serveur dédié : optimiser la couche TCP
  55. Fail2Ban: protéger Postfix contre les attaques DoS de types AUTH, UNKNOWN et EHLO
  56. Serveur dédié : mettre à jour Apache pour HTTP/2
  57. Serveur dédié : ajouter le domaine à la liste HSTS preload
  58. Serveur dédié : ajouter l’authentification DMARC à Postfix et BIND
  59. Serveur dédié : à la recherche de l’inode perdue ou comment résoudre le problème “no space left on device”
  60. Serveur dédié : installer NginX avec support HTTP2 et certificat SSL, PHP, MariaDB sous Debian
pagespeed-99-201301

Performance du site : PageSpeed à 99%

Ah, ce moment magique durant lequel tu constates que ta note PageSpeed monte à 99%, via GTmetrix :

pagespeed-99-201301

C’est beau, sachant qu’au niveau CSS, c’est la barre WordPress du haut qui génère l’overhead.

Prochaine étape : mettre les fichiers statiques sur un sous-domaine cookieless.

PHP : solution pour l'erreur

PHP : résoudre l’erreur “function eregi() is deprecated”

php logo

Il vous est peut-être déjà arrivé de tomber sur ce message d’avertissement :

Function eregi() is deprecated.

En fait, “deprecated” signifie que les versions récentes de PHP considèrent cette fonction comme obsolète, c’est un peu comme si la fonction ereg() n’existait plus.

Par conséquent, mieux vaut dorénavant utiliser la fonction preg_match qui a pris sa place.

La fonction ereg() ou eregi() est donc remplacée par la fonction preg_match() depuis PHP 5.3 :

$is_image = eregi( "jpg|gif",$file_type );

devient donc :

$is_image = preg_match( “~jpg|gif~i”,$file_type );

Voici la liste des fonctions devenues obsolètes sous PHP 5.3 :

call_user_method() (use call_user_func() instead)
call_user_method_array() (use call_user_func_array() instead)
define_syslog_variables()
dl()
ereg() (use preg_match() instead)
ereg_replace() (use preg_replace() instead)
eregi() (use preg_match() with the ‘i’ modifier instead)
eregi_replace() (use preg_replace() with the ‘i’ modifier instead)
set_magic_quotes_runtime() and its alias, magic_quotes_runtime()
session_register() (use the $_SESSION superglobal instead)
session_unregister() (use the $_SESSION superglobal instead)
session_is_registered() (use the $_SESSION superglobal instead)
set_socket_blocking() (use stream_set_blocking() instead)
split() (use preg_split() instead)
spliti() (use preg_split() with the ‘i’ modifier instead)
sql_regcase()
mysql_db_query() (use mysql_select_db() and mysql_query() instead)
mysql_escape_string() (use mysql_real_escape_string() instead)
Passing locale category names as strings is now deprecated. Use the LC_* family of constants instead.
The is_dst parameter to mktime(). Use the new timezone handling functions instead.
HTML5 : corriger l'erreur

WordPress : valider le code oEmbed Youtube en HTML5

Le problème : le code des vidéos n’est pas valide en HTML5

Voici ce que le code oEmbed de WordPress donne par défaut avec un lien Youtube :

<iframe src="https://www.youtube.com/embed/Gvh2Zo7UL6E?fs=1&feature=oembed" width="660" height="371" frameborder="0" allowfullscreen="allowfullscreen"></iframe>

Résultat:

YouTube

By loading the video, you agree to YouTube's privacy policy.
Learn more

Load video

PGlmcmFtZSBzdHlsZT0id2lkdGg6OTAwcHg7IGhlaWdodDo1MDZweDsgYm9yZGVyOm5vbmUiIGFsbG93ZnVsbHNjcmVlbiBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUtbm9jb29raWUuY29tL2VtYmVkL0d2aDJabzdVTDZFP2l2X2xvYWRfcG9saWN5PTM7bW9kZXN0YnJhbmRpbmc9MTtzaG93aW5mbz0wO2ZzPTEiPjwvaWZyYW1lPg==

Or le petit problème, c’est que tout cela n’est pas vraiment valide au niveau W3C et je commence à me lasser de voir ces erreurs de validation sur toutes les pages du site avec des vidéos :

Erreur 1 : Attribute allowfullscreen not allowed on element iframe at this point.
Erreur 2 : The frameborder attribute on the iframe element is obsolete. Use CSS instead.

La solution : filtrer le rendu oEmbed de WordPress pour purifier le code

HTML5 logo

Voici donc la solution que j’ai mise en place sur le site : je filtre le code oEmbed de WordPress de manière à retirer le tag allowfullscreen qui n’a rien à faire là et à supprimer l’attribut frameborder, que je remplace par un style="border: none".

Editez le fichier functions.php de votre thème et ajoutez-y cette fonction:

<?php
/*
|-----------------------------------------------------------------------
| Sky oEmbed Filter by Matt - www.skyminds.net
|-----------------------------------------------------------------------
|
| The sky_oembed_filter() function attempts to validate WordPress 
| video oEmbeds for HTML5.
| $return is the normal HTML that the oEmbed process would return. 
| $data is the data received from the oEmbed call, in an object format. 
| $url is the original URL being queried for oEmbed info. 
|
*/
add_filter('oembed_dataparse', 'sky_oembed_filter', 90, 3 );
function sky_oembed_filter( $return, $data, $url ) {
 	$return = str_replace('frameborder="0" allowfullscreen', 'style="border: none"', $return);
	return $return;
}

Notez que WordPress cache les résultats oEmbed dans la table postmeta donc après avoir installé ce code et si vous voulez vérifier que cela fonctionne, éditez un article pour que le postmeta se mette à jour.

Voilà, vos pages avec vidéos YouTube devraient maitenant être valides.

PHP: résoudre l'erreur

PHP : résoudre l’erreur “assigning the return value of new by reference is deprecated”

Si, lors d’une journée de débuggage PHP, vous tombez sur l’erreur suivante :

Deprecated: Assigning the return value of new by reference is deprecated in  on line 12 

pas de panique, c’est extrêmement simple à résoudre. Vous avez probablement une ligne dans ce goût-là :

$data =& new Structured_Info();

Or, depuis PHP5, le passage par réference est systématique sur new, donc il suffit d’enlever le ‘&’ et d’écrire :

$data = new Structured_Info();

Tout simplement.

PHP: résoudre l'erreur

PHP : les bons en-têtes pour permettre la mise en cache d’une page

Je me suis rendu compte qu’un des fichiers javascript d’un plugin WordPress est appelé sur chaque article du site et qu’il n’est pas mis en cache par défaut…

C’est très moyen au niveau opimisation étant donné que c’est typiquement le genre de fichier statique qui n’est pas prêt d’être modifié.

Voici donc les en-têtes (headers) qui vont nous permettre de mettre un fichier en cache en PHP :

<?php
/*
|--------------------------------------------------------------------------
| Enable Caching with PHP headers by Matt - www.skyminds.net
|--------------------------------------------------------------------------
|
| Let's set it to 90 days caching.
| seconds, minutes, hours, days 
|
*/
$expires = 60*60*24*90;

header('Pragma: public');
header('Cache-Control: maxage='.$expires);
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');

Et voilà, page mise en cache. Cela fait moins de requêtes sur le serveur puisque le navigateur n’a pas besoin de redemander la page à chaque visite.