# « Call to undefined function curl_init() » : un hébergement incomplet

> Une extension distribuée plante chez un client précis avec une erreur curl_init(). Diagnostic d'une extension PHP absente et code défensif pour l'éviter.

- Auteur : WordPress Développement
- Publié le : 2020-03-12
- Mis à jour le : 2020-03-12
- Catégorie : Extensions
- URL : https://www.wpmoderne.fr/extensions/erreur-call-to-undefined-function-curl-init/

## L’essentiel

- L'extension curl n'est pas garantie sur tous les hébergements mutualisés
- extension_loaded() permet de vérifier sa présence avant usage
- Un message clair vaut mieux qu'un écran blanc pour l'utilisateur final

`Fatal error: Uncaught Error: Call to undefined function curl_init() in /home/client/public_html/wp-content/plugins/mon-extension/inc/class-api-client.php:42`. Ce message, retrouvé dans les logs PHP d'un hébergeur mutualisé low-cost, a fait planter tout l'admin d'un site après l'activation d'une extension pourtant testée en local sans le moindre souci.

Le code fautif appelait `curl_init()` directement, en partant du principe — raisonnable en apparence — que cURL est disponible partout en 2020. Ce n'est pas toujours le cas : certains hébergements mutualisés très bon marché livrent des configurations PHP minimalistes, sans l'extension `php-curl` activée, pour économiser des ressources ou limiter les usages jugés risqués.

## Symptôme : un écran blanc après activation

L'extension fonctionnait parfaitement en local (environnement Docker avec cURL installé par défaut) et sur la majorité des hébergements de test. Un seul client, sur un mutualisé d'entrée de gamme, a signalé un écran blanc complet à l'activation. Aucune notice, aucun message côté front ni back-office : juste une page blanche, le classique symptôme d'une erreur fatale PHP sans affichage activé (`display_errors` à `Off` en production, ce qui est la bonne pratique côté hébergeur, mais qui masque le diagnostic).

L'accès aux logs d'erreur du serveur, via le gestionnaire de fichiers de l'hébergement, a révélé la ligne exacte : un appel direct à `curl_init()` dans le constructeur d'une classe chargée systématiquement au démarrage de l'extension, avant même toute vérification de contexte.

## Diagnostic : une extension PHP non universelle

cURL est une extension PHP, pas une fonctionnalité du langage lui-même. Elle doit être compilée et activée dans la configuration du serveur. La documentation PHP le rappelle explicitement : l'extension doit être présente pour que les fonctions `curl_*` existent. Sur la majorité des hébergements WordPress professionnels, elle est activée par défaut — ce qui explique pourquoi tant d'extensions l'utilisent sans jamais vérifier sa disponibilité, jusqu'au jour où un hébergement atypique révèle le problème.

> L'essentiel à retenir : L'extension curl n'est pas garantie sur tous les hébergements mutualisés ; extension_loaded() permet de vérifier sa présence avant usage ; Un message clair vaut mieux qu'un écran blanc pour l'utilisateur final

## Correctif : vérifier avant d'utiliser

La première ligne de défense est une vérification explicite avant tout usage de cURL, avec un message d'erreur exploitable plutôt qu'un fatal error :

```
function monext_verifier_prerequis() {
    if ( ! function_exists( 'curl_init' ) ) {
        add_action( 'admin_notices', function () {
            echo '<div class="notice notice-error"><p>';
            echo 'Mon Extension nécessite l\'extension PHP cURL, absente sur cet hébergement. ';
            echo 'Contactez votre hébergeur pour l\'activer.';
            echo '</p></div>';
        } );
        return false;
    }
    return true;
}

add_action( 'plugins_loaded', function () {
    if ( ! monext_verifier_prerequis() ) {
        return; // On arrête l'initialisation des fonctionnalités dépendantes de cURL.
    }
    monext_initialiser_client_api();
} );
```

Une meilleure option encore, quand c'est possible : s'appuyer sur l'API HTTP de WordPress plutôt que sur cURL directement. `wp_remote_get()` et `wp_remote_post()` savent basculer entre plusieurs transports (cURL, sockets natifs) selon ce qui est disponible sur le serveur, ce qui évite ce type de dépendance rigide.

## Prévention : tester sur un environnement dégradé

Pour éviter que ce genre de régression ne resurgisse, quelques réflexes se sont ajoutés au processus de test avant chaque publication d'extension :

- Désactiver temporairement l'extension cURL dans un environnement Docker de test, pour vérifier que le plugin se dégrade proprement.
- Préférer systématiquement `wp_remote_get()`/`wp_remote_post()` à `curl_init()` quand le besoin ne dépasse pas ce que l'API HTTP de WordPress couvre.
- Ajouter un contrôle des prérequis techniques (PHP, extensions, version WordPress minimale) affiché clairement à l'activation, plutôt qu'en cours d'exécution.
- Documenter dans le fichier `readme.txt` les extensions PHP requises, à la manière d'un « Requires PHP » plus détaillé.

> Un fatal error à l'activation coûte un ticket de support ; un message clair explicitant le prérequis manquant coûte trente secondes de lecture au client.

## Ce qu'on retient

Le bug n'était ni exotique ni rare une fois compris : un hébergement mutualisé sans extension cURL activée reste minoritaire, mais pas inexistant, et une extension distribuée largement finira tôt ou tard par rencontrer cette configuration. La leçon dépasse le cas de cURL : toute dépendance à une extension PHP non garantie par le noyau (GD, mbstring, intl, curl) mérite une vérification explicite à l'activation, avec un message qui oriente vers une action concrète plutôt qu'un écran blanc silencieux.
