Si t’as pas d’ami, prends un cURL !

C’est en toute confiance que j’ai migré récemment un serveur de PHP 5.6 à PHP 7.0, les cheveux au vent et les doigts dans le nez. Je teste vite fait mes applis, toutes fonctionnent, la vie est belle, le soleil brille et les oiseaux chantent. Puis vint le moment de lancer un script qui fait appel à cURL… et là, c’est le drame.

Excusez-moi pour le titre, je suis assez peu inspiré en ce moment, et ce slogan détourné est tout ce que j’ai trouvé pour faire un article qui parle d’un souci avec cURL.

Un petit rappel sur ma config :

  • Windows 7 x86 (et x64 sur une autre machine) – oui pour un serveur ça peut paraître bizarre mais je prends ce qu’on me donne, hein. Mais peu importe la version de Windows, vous aurez probablement le même souci avec autre chose.
  • Apache 2.4.23 VC14 (autrement dit compilé avec Visual C++ 2015)
  • PHP 7.x (7.0 et 7.1, même combat), VC14 et Thread-Safe (vu que PHP est exécuté comme un module Apache)
  • OpenSSL 1.0.2j (parce que je fais du https et même du HTTP/2 moi, madame)

Comme je suis partisan du moindre effort, j’ai repris le php.ini d’origine (de PHP5.6) et ai bêtement recopié les paramètres que j’avais mis. Parmi ceux-ci, j’avais pris soin de décommenter la ligne extension=php_curl.dll vu qu’une de mes applis s’en sert.

Au niveau du fichier de config d’Apache, httpd.conf, là aussi je ne me suis pas foulé : j’ai juste copié les lignes de PHP5.6 en changeant le chemin (PHP 5.6 est installé dans c:\php, et PHP 7 dans c:\php7). Et jusque là, tout allait bien. Enfin, c’est ce que je croyais…

Comme je le disais, une de mes applis utilise cURL pour récupérer des données depuis une page sur un autre serveur (sur lequel je ne peux hélas pas interroger la base de données directement). Ce n’est pas l’extension qu’elle utilise le plus, car en gros la seule page qui s’en sert est appelée une fois par mois, pour établir des stats mensuelles. Et le jour vint où je dus exécuter ce script et là…

 PHP Fatal error:  Call to undefined function curl_init() in lenomduscript.php

« Ah tiens, voilà qui est original, me dis-je. J’ai probablement oublié de décommenter la ligne extension=php_curl.dll dans le php.ini ! »

Je file donc vérifier mon php.ini : diantre, la ligne en question est bien décommentée ! Que se passe-t-il ? Je vérifie à tout hasard que mon répertoire d’extension est correct (oui, les autres extensions ont l’air de se charger, notamment celles qui me servent à accéder à une base MySQL), que la DLL est bien dans le même répertoire… Je redémarre le service Apache des fois que… Hélas non, toujours pas.

Je bricole une page contenant ceci, et je l’appelle illico-presto :

<?php
   phpinfo();
?>

Aucune trace de cURL, si ce n’est le nom de son auteur… Le mystère est des plus mystérieux.

PHP n’ayant pas de log, je décide d’aller vérifier l’error.log d’Apache (dans C:\Apache24\logs). Et là, effectivement, j’ai encore une erreur cheloue :

PHP Warning: PHP Startup: Unable to load dynamic library ‘C:\\PHP7\\ext\\php_curl.dll’ – La proc\xef\xbf\xbddure sp\xef\xbf\xbdcifi\xef\xbf\xbde est introuvable.\r\n in Unknown on line 0

(il y a plein de cochonneries de contrôle à cause des accents : le message dit « La procédure spécifiée est introuvable »).

Bon ok, donc tu n’arrives pas à charger cURL mais sans me dire pourquoi. En tous cas, il tente de le faire, preuve que le php.ini est correct, et pas d’erreur comme quoi il ne trouve pas la DLL, c’est plutôt bon signe… mais ça ne m’avance guère.

Je vous passe toutes les aventures vécues avant de trouver la solution, entre revenir à PHP5.6 (ça marche), installer PHP 7.1 (c’est pas mieux), ou pointer vers le répertoire d’extensions de PHP 5.6 alors que PHP 7.x est utilisé par Apache (mauvaise idée, problème de mauvaise version d’API, rien ne se lance), vérifier que ma variable d’environnement PATH est correcte et contient bien le chemin vers PHP, et farfouiller un peu partout sur StackOverflow (et non, copier des DLL dans c:\Windows ou c:\Windows\System32 n’est pas une solution propre)…

La soluce

Elle est un peu bizarre mais elle marche du feu de moi dieu :

  • Copier c:\php71\libssh2.dll dans c:\apache24\bin
  • Modifier le httpd.conf comme ceci :
LoadFile "C:/php71/libeay32.dll"
LoadFile "C:/php71/ssleay32.dll"
LoadFile "C:/php71/php7ts.dll"
LoadModule php7_module "c:/php71/php7apache2_4.dll"
AddHandler application/x-httpd-php .php .php2 .php3 .php4 .php5 .inc
PHPIniDir "c:/php71"

Visiblement, malgré la variable PATH qui contient tous les chemins possibles pour PHP, Apache a du mal à retrouver ses petits, et sans les directives LoadFile, cURL ne se charge toujours pas. Évidemment, changez le chemin c:\php71 par le chemin correct sur votre serveur, le mien a trois versions différentes de PHP, et il faut bien que je m’y retrouve, hein…

Avec PHP 5.6, je n’avais que ça dans mon httpd.conf et ça fonctionnait très bien :

LoadModule php5_module "c:/php/php5apache2_4.dll"
AddHandler application/x-httpd-php .php .php2 .php3 .php4 .php5 .inc
PHPIniDir "c:/php"

Bref, encore une victoire de l’homme contre la machine. Non mais.

3 commentaires

  1. Erreur résolue sous Easy-PHP-Devserver-17 avec Apache 2.4.25 x86 – PHP 7.1.3 x86

    le fichier dll (libeay32.dll) contenu dans C:\Program Files (x86)\EasyPHP-Devserver-17\eds-binaries\httpserver\apache2425vc11x86x210919131834\bin
    ne correspond pas au fichier (libeay32.dll) contenu dans C:\Program Files (x86)\EasyPHP-Devserver-17\eds-binaries\php\php713vc14x86x210919131834

    Il faut renommer le fichier dll libeay32.dll du dossier apache en libeay32.dll.bak par exemple ensuite copier dans ce même dossier le fichier dll libeay32.dll qui provient cette fois du dossier php

    1. Le message d’erreur associé en provenance des logs serveurs:
      PHP Warning: PHP Startup: Unable to load dynamic library ‘C:\Program Files (x86)\EasyPHP-Devserver-17\eds-binaries\php\php713vc14x86x210919131834\ext\php_curl.dll’ – Le module sp\xef\xbf\xbdcifi\xef\xbf\xbd est introuvable.\r\n in Unknown on line 0

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.