Blog

CakePHP2.1 : solution au conflit entre HttpSocket et le package pecl_http

Depuis sa version 2.0 un conflit de nom existe entre la classe HttpSocket du coeur de CakePHP (Network/Http) et la classe du même nom dans le package pecl_http. Ce bug est connu et reporté sur le bug tracker du projet (voir #2765), mais pour des raisons de rétro-compatibilité il n’est pas sûr que le bug soit corrigé dans la prochaine version stable (2.2) du framework.

[EDITION du 12 Novembre 2012] Le « bug » vient d’être corrigé et devrait être inclus dans la version 2.3 du framework : https://github.com/cakephp/cakephp/commit/3e3af1f99831b71abe41f7da7f54d6b9b9378d2e[/EDITION]

Une astuce pour corriger temporairement ce problème au sein de votre application est de créer une classe personnalisée avec un nom différent, et de l’injecter dans votre instance HttpSocket. Plus de détails ci-dessous …

Reproduire le problème

Voici un bout de code permettant de mettre en avant le problème :

[cce_php]
App::uses(‘HttpSocket’, ‘Network/Http’);
$HttpSocket = new HttpSocket();

$results = $HttpSocket->get(
‘http://api.twitter.com/1/statuses/user_timeline.json’,
array(‘screen_name’ => ‘twitter’)
);
echo $results;
[/cce_php]

Si vous avez installé pecl_http vous aurez droit à une belle erreur :

Ceci est dû au fait que l’instance de HttpResponse créée est une instance de la classe déclarée dans le package pecl et non celle de Cake.

Une résolution possible

Une résolution possible de manière simple et rapide est la duplication de la classe HttpResponse du coeur de CakePHP dans votre application sous un autre nom. Nous utiliserons « HttpResponsePeclFix ».

  1. Dupliquer le fichier /Cake/Network/Http/HttpResponse.php dans le dossier /Lib/Network/Http/HttpResponsePeclFix.php de votre application
  2. Renommer le nom de la classe en « HttpResponsePeclFix »
  3. Modifier le code posant problème afin d’ajouter l’instruction « $HttpSocket->responseClass = ‘HttpResponsePeclFix' »

Par exemple le code précédent deviendrait :
[cce_php]
App::uses(‘HttpSocket’, ‘Network/Http’);
$HttpSocket = new HttpSocket();
$HttpSocket->responseClass = ‘HttpResponsePeclFix’;

$results = $HttpSocket->get(
‘http://api.twitter.com/1/statuses/user_timeline.json’,
array(‘screen_name’ => ‘twitter’)
);
echo $results;
[/cce_php]

Le seul inconvénient de cette méthode est bien sûr la duplication de code … il faudra donc penser à mettre à jour le contenu de la classe lors de futures mise à jour de votre version de CakePHP !