1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 21815 -->
4 <sect1 id="zend.http.client.adapters">
5 <title>Zend_Http_Client - Adaptateurs de connexion</title>
7 <sect2 id="zend.http.client.adapters.overview">
8 <title>Présentation globale</title>
11 <classname>Zend_Http_Client</classname> accepte des objets adaptateurs. Ces objets
12 ont la responsabilité de soutenir la connexion vers un serveur, à savoir écrire des
13 requêtes et lire des réponses L'adaptateur peut donc être changé, et même écrit ou
14 réécrit pour correspondre à vos besoins, sans avoir l'obligation de toucher à toute la
15 classe dite "client". Vous vous connectez et manipulez votre connexion toujours de la
16 même manière quelque soit l'adaptateur situé dessous.
20 Actuellement, la classe cliente <classname>Zend_Http_Client</classname> est
21 fournie avec quatre adaptateurs : <itemizedlist>
23 <para><classname>Zend_Http_Client_Adapter_Socket</classname> (défaut)</para>
27 <para><classname>Zend_Http_Client_Adapter_Proxy</classname></para>
31 <para><classname>Zend_Http_Client_Adapter_Curl</classname></para>
35 <para><classname>Zend_Http_Client_Adapter_Test</classname></para>
41 L'objet Zend_Http_Client se voit spécifié un adaptateur via son constructeur avec
42 le tableau d'options, à l'index 'adapter'. Fournissez alors une chaîne représentant la
43 classe d'adaptateur à utiliser (par exemple 'Zend_Http_Client_Adapter_Socket'), ou un
44 objet directement (par exemple <code> new Zend_Http_Client_Adapter_Test</code>). Vous
45 pouvez de même passer un adaptateur plus tard, avec la méthode
46 <classname>Zend_Http_Client->setConfig()</classname>.
50 <sect2 id="zend.http.client.adapters.socket">
51 <title>Adaptateur Socket</title>
54 L'adaptateur par défaut est Zend_Http_Client_Adapter_Socket. Il est basé sur les
55 fonctions <acronym>PHP</acronym> <methodname>fsockopen()</methodname> et soeurs. Il ne nécessite donc aucune extension
56 particulière ni option de compilation de <acronym>PHP</acronym>.
60 L'adaptateur Socket peut être configuré avec des options, passées par
61 <classname>Zend_Http_Client->setConfig()</classname> ou au constructeur du client.
62 <table id="zend.http.client.adapter.socket.configuration.table">
63 <title>Zend_Http_Client_Adapter_Socket configuration</title>
68 <entry>Paramètre</entry>
69 <entry>Description</entry>
70 <entry>Types attendus</entry>
71 <entry>Valeur par défaut</entry>
77 <entry>persistent</entry>
78 <entry>Utilise ou non les connexions <acronym>TCP</acronym> persistantes</entry>
79 <entry>booléen</entry>
84 <entry>ssltransport</entry>
85 <entry>Couche de transport <acronym>SSL</acronym> ('sslv2', 'tls')</entry>
91 <entry>sslcert</entry>
92 <entry>Chemin vers le certificat <acronym>SSL</acronym> encodé <acronym>PEM</acronym></entry>
98 <entry>sslpassphrase</entry>
99 <entry>Phrase de passe pour le fichier de certificat <acronym>SSL</acronym></entry>
100 <entry>chaîne</entry>
104 <entry>sslusecontext</entry>
106 Active l'utilisation de SSL aux niveaux des connexions proxiées
107 même si la connexion proxiée elle-même ne le fait pas.
109 <entry>boolean</entry>
110 <entry><constant>FALSE</constant></entry>
116 <title>Connexions <acronym>TCP</acronym> persistantes</title>
119 L'utilisation de connexions <acronym>TCP</acronym> persistantes peut potentiellement
120 accélérer vos requêtes <acronym>HTTP</acronym> mais n'a, dans la plupart des cas, qu'un petit effet
121 positif et peut surcharger le serveur <acronym>HTTP</acronym> auquel vous êtes connecté.
125 Il est recommandé d'utiliser les connexions <acronym>TCP</acronym> persistantes seulement si
126 vous vous connectez au même serveur très fréquemment, et que vous êtes sûr que
127 le serveur est capable de gérer un nombre élevé de connections concurrentes.
128 Dans tous les cas vous êtes encouragés à tester l'effet des connections
129 persistantes à la fois sur l'accélération du client et sur la charge du serveur
130 avant d'activer cette option.
134 De plus, quand vous utilisez des connexions persistantes, il est
135 recommandé d'activer l'option "Keep-Alive" décrite dans <xref
136 linkend="zend.http.client.configuration" />, sinon les connexions persistantes
137 n'auront que peu ou pas d'effet.
140 <title>HTTPS SSL Paramètres de flux</title>
143 <code>ssltransport, sslcert</code> and <code>sslpassphrase</code> sont
144 seulement appropriées lors de l'utilisation d'HTTPS.
148 Bien que les réglages par défaut du mode <acronym>SSL</acronym> fonctionneront pour la
149 plupart des applications, vous pourrez avoir besoin de les changer si le
150 serveur, auquel vous vous connectez, requière un paramétrage particulier du
151 client. Dans ce cas, vous devriez lire les sections sur la couche de transport
152 <acronym>SSL</acronym> et ses options à cette <ulink
153 url="http://www.php.net/manual/en/transports.php#transports.inet">adresse</ulink>.
158 <example id="zend.http.client.adapters.socket.example-1">
159 <title>Changer la couche de transport HTTPS</title>
161 <programlisting language="php"><![CDATA[
162 // Définit des paramètres de configuration
164 'adapter' => 'Zend_Http_Client_Adapter_Socket',
165 'ssltransport' => 'tls'
168 // Instantie un objet client
169 $client = new Zend_Http_Client('https://www.example.com', $config);
171 // Cette requête sera envoyée vers une connexion sécurisée TLS
172 $response = $client->request();
177 Le résultat ci-dessus sera similaire à l'ouverture d'une connexion <acronym>TCP</acronym> avec la
178 commande <acronym>PHP</acronym> suivante :
181 <para><methodname>fsockopen('tls://www.example.com', 443)</methodname></para>
183 <sect3 id="zend.http.client.adapters.socket.streamcontext">
184 <title>Customizing and accessing the Socket adapter stream context</title>
186 Starting from Zend Framework 1.9, <classname>Zend_Http_Client_Adapter_Socket</classname>
187 provides direct access to the underlying <ulink url="http://php.net/manual/en/stream.contexts.php">stream context</ulink>
188 used to connect to the remote server. This allows the user to pass
189 specific options and parameters to the <acronym>TCP</acronym> stream, and to the <acronym>SSL</acronym> wrapper in
190 case of <acronym>HTTPS</acronym> connections.
194 You can access the stream context using the following methods of <classname>Zend_Http_Client_Adapter_Socket</classname>:
198 <firstterm><methodname>setStreamContext($context)</methodname></firstterm>
199 Sets the stream context to be used by the adapter. Can accept either
200 a stream context resource created using the
201 <ulink url="http://php.net/manual/en/function.stream-context-create.php"><methodname>stream_context_create()</methodname></ulink>
202 <acronym>PHP</acronym> function, or an array of stream context options, in the same format provided to this function.
203 Providing an array will create a new stream context using these options, and set it.
208 <firstterm><methodname>getStreamContext()</methodname></firstterm>
209 Get the stream context of the adapter. If no stream context was set,
210 will create a default stream context and return it. You can then set
211 or get the value of different context options using regular <acronym>PHP</acronym> stream
217 <example id="zend.http.client.adapters.socket.streamcontext.example-1">
218 <title>Setting stream context options for the Socket adapter</title>
219 <programlisting language="php"><![CDATA[
223 // Bind local socket side to a specific interface
224 'bindto' => '10.1.2.3:50505'
227 // Verify server side certificate,
228 // do not accept invalid or self-signed SSL certificates
229 'verify_peer' => true,
230 'allow_self_signed' => false,
232 // Capture the peer's certificate
233 'capture_peer_cert' => true
237 // Create an adapter object and attach it to the HTTP client
238 $adapter = new Zend_Http_Client_Adapter_Socket();
239 $client = new Zend_Http_Client();
240 $client->setAdapter($adapter);
242 // Method 1: pass the options array to setStreamContext()
243 $adapter->setStreamContext($options);
245 // Method 2: create a stream context and pass it to setStreamContext()
246 $context = stream_context_create($options);
247 $adapter->setStreamContext($context);
249 // Method 3: get the default stream context and set the options on it
250 $context = $adapter->getStreamContext();
251 stream_context_set_option($context, $options);
253 // Now, preform the request
254 $response = $client->request();
256 // If everything went well, you can now access the context again
257 $opts = stream_context_get_options($adapter->getStreamContext());
258 echo $opts['ssl']['peer_certificate'];
264 Note that you must set any stream context options before using the adapter
265 to preform actual requests. If no context is set before preforming <acronym>HTTP</acronym> requests
266 with the Socket adapter, a default stream context will be created. This context
267 resource could be accessed after preforming any requests using the
268 <methodname>getStreamContext()</methodname> method.
274 <sect2 id="zend.http.client.adapters.proxy">
275 <title>Adaptateur Proxy</title>
278 L'adaptateur Zend_Http_Client_Adapter_Proxy est identique à celui par défaut,
279 Socket, sauf que Proxy se connectera au serveur via un serveur Proxy (mandataire). Cette
280 utilisation peut être rencontrée pour des raisons de performances ou de sécurité.
284 En utilisant l'adaptateur Proxy, quelques paramètres de configuration seront
285 nécessaires en plus du paramètre 'adapter' : <table
286 id="zend.http.client.adapters.proxy.table">
287 <title>Zend_Http_Client paramètres de configuration</title>
292 <entry>Paramètre</entry>
293 <entry>Description</entry>
294 <entry>Valeurs attendues</entry>
295 <entry>Valeur par défaut</entry>
301 <entry>proxy_host</entry>
302 <entry>Adresse du serveur Proxy</entry>
303 <entry>chaîne</entry>
304 <entry>'proxy.myhost.com' ou '10.1.2.3'</entry>
308 <entry>proxy_port</entry>
309 <entry>Port du serveur Proxy</entry>
310 <entry>entier</entry>
311 <entry>8080 (défaut) ou 81</entry>
315 <entry>proxy_user</entry>
316 <entry>nom d'utilisateur pour le Proxy, si requis</entry>
317 <entry>chaîne</entry>
318 <entry>'shahar' ou '' pour aucun (défaut)</entry>
322 <entry>proxy_pass</entry>
323 <entry>Mot de passe du Proxy, si requis</entry>
324 <entry>chaîne</entry>
325 <entry>'secret' ou '' pour aucun (défaut)</entry>
329 <entry>proxy_auth</entry>
330 <entry>Type d'authentification <acronym>HTTP</acronym> du Proxy</entry>
331 <entry>chaîne</entry>
332 <entry>Zend_Http_Client::AUTH_BASIC (défaut)</entry>
340 <code>proxy_host</code> devrait toujours être fourni. Si ça n'est pas le cas,
341 alors le client retournera sur une connexion Socket par défaut. <code>proxy_port</code>
342 est par défaut à "8080".
346 <code>proxy_user</code> et <code>proxy_pass</code> ne sont requis que si le
347 serveur Proxy demande une authentification. Si vous remplissez ces options, alors un
348 champ d'en-tête <acronym>HTTP</acronym> "Proxy-Authentication" sera ajouté à vos requêtes, via votre
353 <code>proxy_auth</code> définit le type d'authentification à utiliser, si le
354 serveur Proxy demande une authentification. Actuellement, seule la méthode "basic"
355 (<classname>Zend_Http_Client::AUTH_BASIC</classname>) est supportée.
358 <example id="zend.http.client.adapters.proxy.example-1">
359 <title>Utiliser Zend_Http_Client derrière un serveur Proxy</title>
361 <programlisting language="php"><![CDATA[
362 // Paramètres de configuration
364 'adapter' => 'Zend_Http_Client_Adapter_Proxy',
365 'proxy_host' => 'proxy.int.zend.com',
366 'proxy_port' => 8000,
367 'proxy_user' => 'shahar.e',
368 'proxy_pass' => 'bananashaped'
371 // Crée l'objet client
372 $client = new Zend_Http_Client('http://www.example.com', $config);
374 // utilisez l'objet client ici ...
379 Comme déjà dit, si proxy_host n'est pas rempli ou défini en tant que chaîne vide,
380 alors le client utilisera l'adaptateur Socket par défaut. Ceci est utile si le proxy est
381 utilisé optionnellement, ou par intermittence.
386 Since the proxy adapter inherits from <classname>Zend_Http_Client_Adapter_Socket</classname>,
387 you can use the stream context access method (see <xref linkend="zend.http.client.adapters.socket.streamcontext" />)
388 to set stream context options on Proxy connections as demonstrated above.
393 <sect2 id="zend.http.client.adapters.curl">
394 <title>The cURL Adapter</title>
396 cURL is a standard <acronym>HTTP</acronym> client library that is distributed with many
397 operating systems and can be used in <acronym>PHP</acronym> via the cURL extension. It
398 offers functionality for many special cases which can occur for a <acronym>HTTP</acronym>
399 client and make it a perfect choice for a <acronym>HTTP</acronym> adapter. It supports
400 secure connections, proxy, all sorts of authentication mechanisms
401 and shines in applications that move large files around between servers.
404 <example id="zend.http.client.adapters.curl.example-1">
405 <title>Setting cURL options</title>
406 <programlisting language="php"><![CDATA[
408 'adapter' => 'Zend_Http_Client_Adapter_Curl',
409 'curloptions' => array(CURLOPT_FOLLOWLOCATION => true),
411 $client = new Zend_Http_Client($uri, $config);
416 By default the cURL adapter is configured to behave exactly like
417 the Socket Adapter and it also accepts the same configuration parameters
418 as the Socket and Proxy adapters. You can also change the cURL options by either specifying
419 the 'curloptions' key in the constructor of the adapter or by calling
420 <methodname>setCurlOption($name, $value)</methodname>. The <varname>$name</varname> key
421 corresponds to the CURL_* constants of the cURL extension. You can
422 get access to the Curl handle by calling <code>$adapter->getHandle();</code>
425 <example id="zend.http.client.adapters.curl.example-2">
426 <title>Transfering Files by Handle</title>
429 You can use cURL to transfer very large files over <acronym>HTTP</acronym> by filehandle.
432 <programlisting language="php"><![CDATA[
433 $putFileSize = filesize("filepath");
434 $putFileHandle = fopen("filepath", "r");
436 $adapter = new Zend_Http_Client_Adapter_Curl();
437 $client = new Zend_Http_Client();
438 $client->setAdapter($adapter);
439 $adapter->setConfig(array(
440 'curloptions' => array(
441 CURLOPT_INFILE => $putFileHandle,
442 CURLOPT_INFILESIZE => $putFileSize
445 $client->request("PUT");
450 <sect2 id="zend.http.client.adapters.test">
451 <title>Adaptateur Test</title>
454 Il est quelque fois difficile de tester une application qui a besoin d'une
455 connexion <acronym>HTTP</acronym>. Par exemple, une application qui est en charge de lire un flux <acronym>RSS</acronym> aura
456 besoin d'une connexion, qui n'est pas tout le temps disponible.
460 C'est pour cette raison que l'adaptateur
461 <classname>Zend_Http_Client_Adapter_Test</classname> est présent. Vous pouvez de cette
462 manière écrire vos applications, et lors de la phase de tests, passer votre connexion
463 sur l'adaptateur Test (objet mock).
467 La classe <classname>Zend_Http_Client_Adapter_Test</classname> possède une méthode
468 supplémentaire, <methodname>setResponse()</methodname>. Elle prend en paramètre un objet
469 <classname>Zend_Http_Response</classname> ou une chaîne. Une fois cet objet de réponse
470 déterminé, l'adaptateur de Test retournera toujours cette réponse, sans effectuer de
471 réelle requête <acronym>HTTP</acronym>.
474 <example id="zend.http.client.adapters.test.example-1">
475 <title>Tester avec un objet de réponse HTTP unique</title>
477 <programlisting language="php"><![CDATA[
478 // Création de l'adatateur et de l'objet client :
479 $adapter = new Zend_Http_Client_Adapter_Test();
480 $client = new Zend_Http_Client('http://www.example.com', array(
481 'adapter' => $adapter
484 // Passage de l'objet de réponse
485 $adapter->setResponse(
486 "HTTP/1.1 200 OK" . "\r\n" .
487 "Content-type: text/xml" . "\r\n" .
489 '<?xml version="1.0" encoding="UTF-8"?>' .
490 '<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"' .
491 ' xmlns:wfw="http://wellformedweb.org/CommentAPI/"' .
492 ' xmlns:dc="http://purl.org/dc/elements/1.1/">' .
494 ' <title>Premature Optimization</title>' .
498 $response = $client->request('GET');
499 // ... continuez à parser $response...
504 L'exemple ci dessus montre comment préconfigurer la réponse qui sera retournée
505 lors d'une requête de votre objet client. Ainsi lors des tests, votre application
506 continuera de se comporter normalement, elle aura tout simplement été trompée (mock).
507 Aucune connexion <acronym>HTTP</acronym> n'est dans ce cas là nécessaire.
511 Quelques fois, plusieurs transactions <acronym>HTTP</acronym> peuvent être nécessaires. Une réponse
512 peut demander une redirection, vers une autre. Dans ce cas, utiliser
513 <methodname>setResponse()</methodname> toute seule n'est pas possible car il ne sera pas possible de
514 spécifier les réponses suivantes, nécessaires alors à l'application.
517 <example id="zend.http.client.adapters.test.example-2">
518 <title>Tester avec plusieurs réponses HTTP</title>
520 <programlisting language="php"><![CDATA[
521 // Création des objets adaptateur, et client
522 $adapter = new Zend_Http_Client_Adapter_Test();
523 $client = new Zend_Http_Client('http://www.example.com', array(
524 'adapter' => $adapter
527 // Configuration de la première réponse attendue
528 $adapter->setResponse(
529 "HTTP/1.1 302 Found" . "\r\n" .
530 "Location: /" . "\r\n" .
531 "Content-Type: text/html" . "\r\n" .
534 ' <head><title>Moved</title></head>' .
535 ' <body><p>This page has moved.</p></body>' .
538 // Configuration des réponses successives
539 $adapter->addResponse(
540 "HTTP/1.1 200 OK" . "\r\n" .
541 "Content-Type: text/html" . "\r\n" .
544 ' <head><title>My Pet Store Home Page</title></head>' .
545 ' <body><p>...</p></body>' .
548 // l'objet $client est prêt à être testé
549 // son comportement est déja configuré
554 La méthode <methodname>setResponse()</methodname> détruit toutes les réponses dans le buffer
555 de <classname>Zend_Http_Client_Adapter_Test</classname> et définit la première réponse
556 qui sera retournée. La méthode <methodname>addResponse()</methodname> définit les réponses
560 <para>Les réponses seront rejouées dans leur ordre d'ajout.</para>
563 Dans l'exemple ci-dessus, l'adaptateur est configuré pour un scénario de test de
564 redirections 302. En fonction de votre application, le suivi d'une redirection peut être
565 ou non désiré. Dans notre exemple, nous nous attendons à ce que la redirection soit
566 suivie et nous configurons notre adaptateur de tests pour ceci. La réponse de
567 redirection originelle (302) est définie avec la méthode <methodname>setResponse()</methodname>,
568 quant à la réponse non redirigeante (200) suivante, elles est définie avec la méthode
569 <methodname>addResponse()</methodname>. Lorsque votre objet client est configuré, vous pouvez
570 l'injecter dans votre application à tester, et voir le résultat et les
575 If you need the adapter to fail on demand you can use
576 <methodname>setNextRequestWillFail($flag)</methodname>. The method will cause the next
577 call to <methodname>connect()</methodname> to throw an
578 <classname>Zend_Http_Client_Adapter_Exception</classname> exception. This can be useful
579 when your application caches content from an external site (in case the site goes down)
580 and you want to test this feature.
583 <example id="zend.http.client.adapters.test.example-3">
584 <title>Forcing the adapter to fail</title>
586 <programlisting language="php"><![CDATA[
587 // Instantiate a new adapter and client
588 $adapter = new Zend_Http_Client_Adapter_Test();
589 $client = new Zend_Http_Client('http://www.example.com', array(
590 'adapter' => $adapter
593 // Force the next request to fail with an exception
594 $adapter->setNextRequestWillFail(true);
597 // This call will result in a Zend_Http_Client_Adapter_Exception
599 } catch (Zend_Http_Client_Adapter_Exception $e) {
603 // Further requests will work as expected until
604 // you call setNextRequestWillFail(true) again
609 <sect2 id="zend.http.client.adapters.extending">
610 <title>Créer vos propres adaptateurs de connexion</title>
613 Vous pouvez créer vos propres adaptateurs, si vous avez un besoin spécial à
614 utiliser. Par exemple, des possibilités de cache, ou des sockets persistantes.
618 Pour ceci, votre classe d'adaptateur doit implémenter l'interface
619 <classname>Zend_Http_Client_Adapter_Interface</classname>. L'exemple suivant montre un
620 squelette de classe. Toutes les méthodes publiques, ici, sont indispensables à la
621 classe, elles sont issues de l'interface :
624 <example id="zend.http.client.adapters.extending.example-1">
625 <title>Création de votre propre adaptateur de connexion</title>
627 <programlisting language="php"><![CDATA[
628 class MyApp_Http_Client_Adapter_BananaProtocol
629 implements Zend_Http_Client_Adapter_Interface
632 * Définit le tableau de configuration pour cet adaptateur
634 * @param array $config
636 public function setConfig($config = array())
638 // Ceci change rarement, vous devriez copier l'implémentation
639 // présente dans Zend_Http_Client_Adapter_Socket.
643 * Connecte à une serveur distant
645 * @param string $host
647 * @param boolean $secure
649 public function connect($host, $port = 80, $secure = false)
651 // Etablit la connexion au serveur
655 * Envoie une requête au serveur
657 * @param string $method
658 * @param Zend_Uri_Http $url
659 * @param string $http_ver
660 * @param array $headers
661 * @param string $body
662 * @return string Request as text
664 public function write($method,
670 // Envoie la requête au serveur distant. Cette fonction devrait
671 // retourner la requête complète (en-tête et corps) as a string
675 * Lit la réponse du serveur
679 public function read()
681 // Lit la réponse du serveur distant, et la retourne sous forme
682 // de chaine de caractères
686 * Ferme la connexion avec le serveur
689 public function close()
691 // Ferme la connexion, appelée en dernière.
695 // Maintenant, vous pouvez utiliser cet adaptateur :
696 $client = new Zend_Http_Client(array(
697 'adapter' => 'MyApp_Http_Client_Adapter_BananaProtocol'