Douze mille fichiers CSV à convertir en pièces jointes de la médiathèque, un traitement par lot lancé via WP-CLI : c’est le contexte d’un import réalisé pour un catalogue de produits artisanaux. La première version du script utilisait systématiquement l’API WP_Filesystem pour chaque lecture et écriture, comme le recommandent souvent les guides de bonnes pratiques WordPress. Le traitement complet a pris un peu plus de vingt-deux minutes.
Une seconde version, utilisant les fonctions PHP natives file_get_contents() et file_put_contents() pour les mêmes opérations, a terminé en un peu plus de six minutes. Un écart de plus de trois fois, qui mérite d’être expliqué avant de généraliser trop vite dans un sens ou dans l’autre.
Ce que fait réellement WP_Filesystem
L’API WP_Filesystem, initialisée via la fonction globale WP_Filesystem(), existe pour une raison précise : permettre à WordPress d’écrire des fichiers même quand le processus PHP ne dispose pas des permissions directes sur le système de fichiers, en passant alors par FTP ou SSH avec des identifiants fournis par l’administrateur. Cette abstraction est indispensable pour l’installation d’extensions ou de mises à jour sur des hébergements mutualisés contraints.
Mais cette flexibilité a un prix : chaque appel à une méthode comme $wp_filesystem->put_contents() passe par une couche d’indirection supplémentaire, qui, même en mode direct (le plus rapide des transports disponibles, utilisé quand les permissions du système de fichiers le permettent), ajoute des vérifications et des appels de méthode que les fonctions natives n’ont pas à faire.
Le comparatif mesuré
| Méthode | Fichiers traités | Durée totale | Transport |
|---|---|---|---|
| WP_Filesystem | 12 000 | 22 min 40 s | direct |
| Fonctions PHP natives | 12 000 | 6 min 35 s | N/A |
| WP_Filesystem | 1 000 | 1 min 52 s | direct |
| Fonctions PHP natives | 1 000 | 0 min 33 s | N/A |
L’écart reste proportionnel au volume : sur mille fichiers, la différence est perceptible mais reste tolérable pour un traitement ponctuel. Sur douze mille fichiers, elle devient un vrai problème pour une tâche exécutée dans une fenêtre de maintenance limitée.

Pourquoi la recommandation par défaut reste WP_Filesystem
La documentation officielle de WordPress recommande WP_Filesystem pour toute écriture de fichier initiée par une extension ou un thème, car c’est la seule méthode qui fonctionne de façon garantie sur l’ensemble des configurations d’hébergement possibles, y compris celles où PHP ne peut pas écrire directement sur le disque. Ignorer cette API dans le code d’une extension distribuée publiquement expose à des échecs silencieux chez une partie des utilisateurs.
Le contexte change cependant pour un script d’import exécuté ponctuellement via WP-CLI, sur un serveur dont on connaît la configuration : dans ce cas précis, l’exécution se fait en ligne de commande, avec les permissions du système de fichiers déjà correctement définies pour l’utilisateur qui lance le script, rendant l’abstraction FTP/SSH superflue.
Un compromis raisonnable
if ( defined( 'WP_CLI' ) && WP_CLI ) {
// Contexte de script en ligne de commande : accès direct assumé.
file_put_contents( $chemin_destination, $contenu );
} else {
// Contexte d'exécution web classique : rester sur l'API WordPress.
global $wp_filesystem;
if ( empty( $wp_filesystem ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
WP_Filesystem();
}
$wp_filesystem->put_contents( $chemin_destination, $contenu );
}
Cette distinction conditionnelle permet de conserver la portabilité de WP_Filesystem pour les opérations déclenchées depuis l’interface d’administration, tout en profitant de la rapidité des fonctions natives pour les traitements par lot exécutés en ligne de commande.
Les limites à connaître
- Les fonctions PHP natives ne gèrent aucune des vérifications de permissions que fait
WP_Filesystem: une erreur d’écriture silencieuse est possible si le répertoire cible n’est pas accessible en écriture. - Le mode de transport de
WP_Filesystem(direct, FTP, SSH) est déterminé automatiquement par WordPress en fonction du contexte serveur ; un transport FTP ou SSH creuserait encore davantage l’écart mesuré ici. - Sur un hébergement mutualisé strict qui bloque l’accès direct au système de fichiers pour PHP, seule l’API
WP_Filesystemfonctionnera réellement, quel que soit le contexte d’exécution.
Notre verdict
Pour du code distribué publiquement destiné à s’exécuter dans le contexte web de WordPress, WP_Filesystem reste le choix par défaut et le plus sûr. Pour un script de traitement par lot exécuté en ligne de commande sur une infrastructure connue, les fonctions PHP natives offrent un gain de temps significatif sans compromettre la fiabilité, à condition d’accepter d’écrire un peu de code de vérification supplémentaire soi-même.