# WP_Filesystem contre les appels directs : l’écart mesuré sur un import massif

> Traiter douze mille fichiers avec l'API du système de fichiers de WordPress ou avec les fonctions PHP natives ne prend pas le même temps. Voici la mesure.

- Auteur : WordPress Développement
- Publié le : 2023-07-24
- Mis à jour le : 2023-07-24
- Catégorie : Performance
- URL : https://www.wpmoderne.fr/performance/wp-filesystem-vs-appels-directs-import/

## L’essentiel

- WP_Filesystem ajoute une couche d'abstraction FTP/SSH
- Les appels PHP natifs sont plus rapides mais moins portables
- Le choix dépend du contexte d'exécution

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.

> L'essentiel à retenir : WP_Filesystem ajoute une couche d'abstraction FTP/SSH ; Les appels PHP natifs sont plus rapides mais moins portables ; Le choix dépend du contexte d'exécution

## 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_Filesystem` fonctionnera 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.
