J'essaie de faire une demande HTTP à partir de l'un de mes contrôleurs pour contacter une autre URL, l'objectif étant de contacter une autre URL et d'imprimer simplement la réponse HTML dans ma page. J'ai essayé :
$r = new Request();
$r->create('http://www.google.com', 'GET');
return $this->render(...mytemplate..., array('name' => $r->getContent());
Mon modèle imprime simplement la variable "nom".
Maintenant, quand je fais cela, rien n'est retourné. Il me semble que la demande n'est jamais envoyée, c'est pourquoi rien n'est retourné.
Ma question est: comment envoyer la demande et obtenir le contenu de la réponse?
Merci d'avance.
[~ # ~] modifier [~ # ~] : J'ai fait un GremoBuzzBundle pour le navigateur Buzz. C'est similaire à SensioBuzzBundle mais il a quelques options de configuration Nice.
Je suggère d'utiliser navigateur Buzz et l'injection de dépendances. Buzz est un wrapper autour de cURL ou file_get_contents. Modifiez votre fichier deps
en ajoutant ces lignes:
[Buzz]
git=https://github.com/kriswallsmith/Buzz.git
target=/buzz
Installez ensuite les fournisseurs pour télécharger la bibliothèque:
php bin/vendors install
Ajoutez ensuite deux services (src/YourCompany/YourBundle/Resources/config/services.yml
):
# cURL client for Buzz
buzz.client.curl:
class: Buzz\Client\Curl
public: false
calls:
- [setVerifyPeer, [false]]
# Buzz browser
buzz.browser:
class: Buzz\Browser
arguments: ['@buzz.client.curl']
Le premier service est le client (je préfère cURL à file_get_contents), le dernier est le navigateur lui-même. La dernière étape consiste à ajouter une ligne de code dans l'autochargeur (app/autoload.php
):
$loader->registerNamespaces(array(
'Buzz' => __DIR__.'/../vendor/buzz/lib',
));
Ensuite, vous pouvez obtenir le service et utiliser le navigateur dans votre code de contrôleur :
$browser = $this->get('buzz.browser');
$response = $browser->get('http://www.google.com');
Deux problèmes.
Tout d'abord, ce n'est pas la bonne utilisation de Symfony\Component\HttpFoundation\Request::create()
, qui est en quelque sorte un initialiseur/fabrique statique. Votre code devrait ressembler à ceci
$r = Request::create( 'http://www.google.com', 'GET' );
Vous disposez maintenant d'un objet Request approprié. Cependant, ce n'est pas pertinent, c'est votre deuxième problème: ce n'est pas ainsi que l'objet de demande de Symfony est conçu pour fonctionner. Son objectif n'est pas de exécuter les requêtes HTTP, mais de les représenter comme objets dans le cadre.
Pour faire court, vous ne pouvez pas le faire de cette façon. Peut-être que vous pouvez tilisez cURL pour gratter la page vous voulez?
Je vous recommanderais d'utiliser GuzzleHttp Client - le meilleur client que je connaisse: http://docs.guzzlephp.org/en/latest/
Il existe déjà un bundle Nice qui l'intègre dans le projet Symfony2: https://github.com/8p/GuzzleBundle
Ensuite, depuis votre contrôleur, vous pouvez appeler:
$client = $this->get('guzzle.client');
// GET request with parameters
$response = $client->get('http://httpbin.org/get', [
'headers' => ['X-Foo-Header' => 'value'],
'query' => ['foo' => 'bar']
]);
$code = $response->getStatusCode();
$body = $response->getBody();
Plus d'informations peuvent être trouvées sur: http://docs.guzzlephp.org/en/latest/index.html
Pourquoi ne pas utiliser curl? De manuel PHP
$ch = curl_init("http://www.example.com/");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
result = curl_exec($ch);
curl_close($ch);
https://github.com/CircleOfNice/CiRestClientBundle
Belle API pour une utilisation facile de la bibliothèque curl et elle renvoie une réponse symfony au lieu d'un résultat de chaîne
$restClient = $this->container->get('ci.restclient');
$restClient->get('http://www.someUrl.com');
$restClient->post('http://www.someUrl.com', 'somePayload');
$restClient->put('http://www.someUrl.com', 'somePayload');
$restClient->delete('http://www.someUrl.com');
$restClient->patch('http://www.someUrl.com', 'somePayload');
$restClient->head('http://www.someUrl.com');
$restClient->options('http://www.someUrl.com', 'somePayload');
$restClient->trace('http://www.someUrl.com');
$restClient->connect('http://www.someUrl.com');
Apparemment, vous pouvez utiliser le client HTTP intégré de Symfony. Voir: http://api.symfony.com/2.0/Symfony/Component/HttpKernel.html
Ce qui suit est une base de code très grossière, utilisant Silex (construit sur Symfony). Il instancie simplement un nouveau client HTTP.
<?php
require_once __DIR__ . '/silex/vendor/autoload.php';
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\Client;
//use Symfony\Component\HttpFoundation\Response;
$dispatcher = new EventDispatcher();
$resolver = new ControllerResolver();
$kernel = new HttpKernel( $dispatcher, $resolver );
$client = new Client( $kernel );
var_dump( $client );
?>
Vous avez également un exemple détaillé d'un client HTTP pour Symfony2 dans le cadre de la documentation de test unitaire. Voir: http://symfony.com/doc/current/book/testing.html
MAIS (modifier) ces clients sont locaux à votre application. Les concepts illustrés ici sont mieux implémentés avec le composant BrowserKit de Symfony2. Un navigateur sans tête dans Symfony.
Mieux encore, utilisez Goutte pour les demandes de sites Web externes. Voir https://github.com/FriendsOfPHP/Goutte pour plus de détails.