vendredi 25 septembre 2026

À propos

Contact

Extensions

WP_Filesystem plutôt que file_put_contents dans une extension

Un plugin qui écrit un fichier de configuration avec les fonctions PHP natives fonctionne partout, jusqu'au jour où il tombe sur un hébergeur qui exige FTP ou SSH pour toute écriture disque.

Par Clément Hadrot • 20 septembre 2022 • 5 min de lecture • Aucun commentaire
WP_Filesystem plutôt que file_put_contents dans une extension

Une extension de génération de flux de produits pour comparateurs de prix écrit un fichier XML statique dans le dossier uploads du site, régénéré chaque nuit via une tâche planifiée. Le code initial, écrit avec la simplicité des fonctions PHP natives, utilise directement file_put_contents(). Tout fonctionne sans accroc pendant des mois, jusqu’à ce qu’un nouveau client migre son site chez un hébergeur mutualisé dont la configuration serveur impose que le processus PHP tourne avec un utilisateur système différent du propriétaire des fichiers, une configuration de sécurité assez répandue chez certains hébergeurs qui cherchent à isoler strictement chaque site hébergé.

Sur cet hébergement précis, file_put_contents() échoue silencieusement, ou plus exactement retourne false sans lever d’exception, faute des permissions nécessaires pour écrire directement dans le dossier concerné avec l’utilisateur système du processus PHP. Le flux XML ne se régénère plus, le comparateur de prix affiche des données obsolètes pendant plusieurs jours avant que quelqu’un ne remarque le problème.

Ce que WordPress propose pour ce cas précis

WordPress fournit depuis longtemps une abstraction dédiée à l’écriture sur le système de fichiers, WP_Filesystem, précisément pour gérer cette hétérogénéité entre hébergeurs. Cette abstraction sait s’adapter à trois grandes familles de méthodes d’accès : l’accès direct quand les permissions le permettent, l’accès via FTP quand le processus PHP n’a pas les droits suffisants et qu’un compte FTP est configuré, ou l’accès via SSH2 sur les configurations qui le supportent.

Utiliser l’abstraction correctement

L'essentiel à retenir : WP_Filesystem abstrait trois méthodes d'accès, direct, FTP, SSH ; Ignorer cette abstraction casse silencieusement l'écriture chez certains hébergeurs ; Le formulaire d'identifiants FTP apparaît automatiquement si nécessaire
function ecrire_flux_produits_xml( string $chemin, string $contenu ): bool {
    global $wp_filesystem;

    if ( empty( $wp_filesystem ) ) {
        require_once ABSPATH . 'wp-admin/includes/file.php';
        WP_Filesystem();
    }

    if ( ! $wp_filesystem ) {
        error_log( 'Impossible d\'initialiser WP_Filesystem pour l\'écriture du flux produits.' );
        return false;
    }

    return $wp_filesystem->put_contents( $chemin, $contenu, FS_CHMOD_FILE );
}

Cette version fonctionne de façon identique sur un hébergement qui permet l’écriture directe et sur un hébergement qui l’interdit. Sur ce dernier cas, si aucune méthode d’accès n’a été préalablement configurée par l’administrateur du site via les constantes FTP_HOST, FTP_USER et FTP_PASS dans wp-config.php, WordPress affiche automatiquement, lors d’une action déclenchée depuis l’administration, un formulaire de saisie des identifiants FTP nécessaires, le même que celui utilisé nativement pour les mises à jour de plugin ou de thème.

Un point important pour les tâches automatisées

Ce formulaire de saisie d’identifiants ne peut évidemment pas s’afficher dans le contexte d’une tâche cron exécutée sans interaction humaine, comme dans l’exemple de notre flux XML nocturne. Pour ce cas précis, la constante FTP_HOST et les identifiants associés doivent être définis une bonne fois dans wp-config.php pour que WP_Filesystem() puisse s’initialiser sans intervention, sans quoi le traitement automatisé échouera de la même façon qu’avec file_put_contents(), mais cette fois avec un message d’erreur explicite dans les journaux plutôt qu’un échec silencieux.

// Dans wp-config.php, sur les hébergements qui l'exigent :
define( 'FTP_HOST', 'ftp.hebergeur-exemple.fr' );
define( 'FTP_USER', 'compte_ftp' );
define( 'FTP_PASS', 'mot-de-passe-en-lieu-sur' );
define( 'FS_METHOD', 'ftpext' );

Ce qu’il ne faut jamais faire malgré tout

  • Ne jamais forcer FS_METHOD à direct par défaut dans le code d’une extension distribuée : ce choix relève de l’administrateur du site ou de son hébergeur, pas de l’extension elle-même.
  • Ne pas ignorer la valeur de retour de put_contents(), qui peut échouer aussi bien que file_put_contents(), pour des raisons différentes cette fois liées à des permissions FTP mal configurées.
  • Éviter de stocker les identifiants FTP en dur dans le code d’une extension distribuée : ils doivent toujours provenir de wp-config.php ou d’un réglage saisi par l’administrateur, jamais codés en clair dans un fichier de plugin partagé publiquement.

Quand file_put_contents reste acceptable

Il existe des cas où l’usage direct des fonctions PHP natives reste défendable : l’écriture dans un fichier de log temporaire propre à l’exécution en cours, situé dans un dossier dont on maîtrise entièrement les permissions dès l’installation, ou un contexte purement interne à une agence qui contrôle la totalité de son parc d’hébergement et sait par avance que l’accès direct fonctionnera toujours. Pour une extension distribuée à un public plus large, dont l’environnement d’hébergement est par nature inconnu, l’abstraction reste le choix le plus prudent.

Une écriture disque qui fonctionne sur son propre serveur de développement ne prouve rien sur son comportement chez un hébergeur qu’on n’a jamais testé.

En résumé

WP_Filesystem existe précisément pour absorber l’hétérogénéité des configurations d’hébergement rencontrées dans l’écosystème WordPress, entre accès direct, FTP et SSH. Une extension distribuée qui écrit sur le disque sans passer par cette abstraction fonctionnera très bien chez la majorité des hébergeurs, jusqu’au jour où elle rencontrera celui qui l’oblige à passer par un autre chemin, et ce jour-là, l’échec sera silencieux si l’abstraction n’a pas été anticipée dès le départ.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi