| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.http.client.advanced">
- <title>Zend_Http_Client - Advanced Usage</title>
- <sect2 id="zend.http.client.redirections">
- <title>HTTP Redirections</title>
- <para>
- By default, <classname>Zend_Http_Client</classname> automatically handles
- <acronym>HTTP</acronym> redirections, and will follow up to 5 redirections. This can be
- changed by setting the 'maxredirects' configuration parameter.
- </para>
- <para>
- According to the <acronym>HTTP</acronym>/1.1 RFC, <acronym>HTTP</acronym> 301 and 302
- responses should be treated by the client by resending the same request to the
- specified location - using the same request method. However, most
- clients to not implement this and always use a <constant>GET</constant> request when
- redirecting. By default, <classname>Zend_Http_Client</classname> does the same - when
- redirecting on a 301 or 302 response, all <constant>GET</constant> and POST parameters
- are reset, and a <constant>GET</constant> request is sent to the new location. This
- behavior can be changed by setting the 'strictredirects' configuration
- parameter to boolean <constant>TRUE</constant>:
- <example id="zend.http.client.redirections.example-1">
- <title>Forcing RFC 2616 Strict Redirections on 301 and 302 Responses</title>
- <programlisting language="php"><![CDATA[
- // Strict Redirections
- $client->setConfig(array('strictredirects' => true));
- // Non-strict Redirections
- $client->setConfig(array('strictredirects' => false));
- ]]></programlisting>
- </example>
- </para>
- <para>
- You can always get the number of redirections done after sending a
- request using the getRedirectionsCount() method.
- </para>
- </sect2>
- <sect2 id="zend.http.client.cookies">
- <title>Adding Cookies and Using Cookie Persistence</title>
- <para>
- <classname>Zend_Http_Client</classname> provides an easy interface for adding cookies
- to your request, so that no direct header modification is
- required. This is done using the setCookie() method. This method
- can be used in several ways:
- <example id="zend.http.client.cookies.example-1">
- <title>Setting Cookies Using setCookie()</title>
- <programlisting language="php"><![CDATA[
- // Easy and simple: by providing a cookie name and cookie value
- $client->setCookie('flavor', 'chocolate chips');
- // By directly providing a raw cookie string (name=value)
- // Note that the value must be already URL encoded
- $client->setCookie('flavor=chocolate%20chips');
- // By providing a Zend_Http_Cookie object
- $cookie = Zend_Http_Cookie::fromString('flavor=chocolate%20chips');
- $client->setCookie($cookie);
- ]]></programlisting>
- </example>
- For more information about <classname>Zend_Http_Cookie</classname> objects, see
- <link linkend="zend.http.cookies">this section</link>.
- </para>
- <para>
- <classname>Zend_Http_Client</classname> also provides the means for cookie stickiness -
- that is having the client internally store all sent and received
- cookies, and resend them automatically on subsequent requests. This
- is useful, for example when you need to log in to a remote site
- first and receive and authentication or session ID cookie before
- sending further requests.
- <example id="zend.http.client.cookies.example-2">
- <title>Enabling Cookie Stickiness</title>
- <programlisting language="php"><![CDATA[
- // To turn cookie stickiness on, set a Cookie Jar
- $client->setCookieJar();
- // First request: log in and start a session
- $client->setUri('http://example.com/login.php');
- $client->setParameterPost('user', 'h4x0r');
- $client->setParameterPost('password', '1337');
- $client->request('POST');
- // The Cookie Jar automatically stores the cookies set
- // in the response, like a session ID cookie.
- // Now we can send our next request - the stored cookies
- // will be automatically sent.
- $client->setUri('http://example.com/read_member_news.php');
- $client->request('GET');
- ]]></programlisting>
- </example>
- For more information about the <classname>Zend_Http_CookieJar</classname> class, see
- <link linkend="zend.http.cookies.cookiejar">this section</link>.
- </para>
- </sect2>
- <sect2 id="zend.http.client.custom_headers">
- <title>Setting Custom Request Headers</title>
- <para>
- Setting custom headers can be done by using the setHeaders() method.
- This method is quite diverse and can be used in several ways, as
- the following example shows:
- <example id="zend.http.client.custom_headers.example-1">
- <title>Setting A Single Custom Request Header</title>
- <programlisting language="php"><![CDATA[
- // Setting a single header, overwriting any previous value
- $client->setHeaders('Host', 'www.example.com');
- // Another way of doing the exact same thing
- $client->setHeaders('Host: www.example.com');
- // Setting several values for the same header
- // (useful mostly for Cookie headers):
- $client->setHeaders('Cookie', array(
- 'PHPSESSID=1234567890abcdef1234567890abcdef',
- 'language=he'
- ));
- ]]></programlisting>
- </example>
- </para>
- <para>
- setHeader() can also be easily used to set multiple headers in one
- call, by providing an array of headers as a single parameter:
- <example id="zend.http.client.custom_headers.example-2">
- <title>Setting Multiple Custom Request Headers</title>
- <programlisting language="php"><![CDATA[
- // Setting multiple headers, overwriting any previous value
- $client->setHeaders(array(
- 'Host' => 'www.example.com',
- 'Accept-encoding' => 'gzip,deflate',
- 'X-Powered-By' => 'Zend Framework'));
- // The array can also contain full array strings:
- $client->setHeaders(array(
- 'Host: www.example.com',
- 'Accept-encoding: gzip,deflate',
- 'X-Powered-By: Zend Framework'));
- ]]></programlisting>
- </example>
- </para>
- </sect2>
- <sect2 id="zend.http.client.file_uploads">
- <title>File Uploads</title>
- <para>
- You can upload files through <acronym>HTTP</acronym> using the setFileUpload method.
- This method takes a file name as the first parameter, a form name
- as the second parameter, and data as a third optional parameter.
- If the third data parameter is <constant>NULL</constant>, the first file name parameter
- is considered to be a real file on disk, and <classname>Zend_Http_Client</classname>
- will try to read this file and upload it. If the data parameter is not
- <constant>NULL</constant>, the first file name parameter will be sent as the file name,
- but no actual file needs to exist on the disk.
- The second form name parameter is always required, and is equivalent
- to the "name" attribute of an >input< tag, if the file was to
- be uploaded through an <acronym>HTML</acronym> form.
- A fourth optional parameter provides the file's content-type. If
- not specified, and <classname>Zend_Http_Client</classname> reads the file from the disk,
- the mime_content_type function will be used to guess the file's
- content type, if it is available. In any case, the default MIME
- type will be application/octet-stream.
- <example id="zend.http.client.file_uploads.example-1">
- <title>Using setFileUpload to Upload Files</title>
- <programlisting language="php"><![CDATA[
- // Uploading arbitrary data as a file
- $text = 'this is some plain text';
- $client->setFileUpload('some_text.txt', 'upload', $text, 'text/plain');
- // Uploading an existing file
- $client->setFileUpload('/tmp/Backup.tar.gz', 'bufile');
- // Send the files
- $client->request('POST');
- ]]></programlisting>
- </example>
- In the first example, the $text variable is uploaded and will be
- available as $_FILES['upload'] on the server side. In the second
- example, the existing file /tmp/Backup.tar.gz is uploaded to the
- server and will be available as $_FILES['bufile']. The content type
- will be guesses automatically if possible - and if not, the content
- type will be set to 'application/octet-stream'.
- </para>
- <note>
- <title>Uploading files</title>
- <para>
- When uploading files, the <acronym>HTTP</acronym> request content-type is
- automatically set to multipart/form-data. Keep in mind that
- you must send a POST or PUT request in order to upload files.
- Most servers will ignore the requests body on other request
- methods.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.http.client.raw_post_data">
- <title>Sending Raw POST Data</title>
- <para>
- You can use a <classname>Zend_Http_Client</classname> to send raw POST data using the
- setRawData() method. This method takes two parameters: the first
- is the data to send in the request body. The second optional
- parameter is the content-type of the data. While this parameter is
- optional, you should usually set it before sending the request -
- either using setRawData(), or with another method: setEncType().
- <example id="zend.http.client.raw_post_data.example-1">
- <title>Sending Raw POST Data</title>
- <programlisting language="php"><![CDATA[
- $xml = '<book>' .
- ' <title>Islands in the Stream</title>' .
- ' <author>Ernest Hemingway</author>' .
- ' <year>1970</year>' .
- '</book>';
- $client->setRawData($xml, 'text/xml')->request('POST');
- // Another way to do the same thing:
- $client->setRawData($xml)->setEncType('text/xml')->request('POST');
- ]]></programlisting>
- </example>
- The data should be available on the server side through <acronym>PHP</acronym>'s
- $HTTP_RAW_POST_DATA variable or through the php://input stream.
- </para>
- <note>
- <title>Using raw POST data</title>
- <para>
- Setting raw POST data for a request will override any POST
- parameters or file uploads. You should not try to use both on
- the same request. Keep in mind that most servers will ignore
- the request body unless you send a POST request.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.http.client.http_authentication">
- <title>HTTP Authentication</title>
- <para>
- Currently, <classname>Zend_Http_Client</classname> only supports basic
- <acronym>HTTP</acronym> authentication. This feature is utilized using the
- <methodname>setAuth()</methodname> method, or by specifying a username and a password in
- the URI. The <methodname>setAuth()</methodname> method
- takes 3 parameters: The user name, the password and an optional
- authentication type parameter. As mentioned, currently only basic
- authentication is supported (digest authentication support is
- planned).
- <example id="zend.http.client.http_authentication.example-1">
- <title>Setting HTTP Authentication User and Password</title>
- <programlisting language="php"><![CDATA[
- // Using basic authentication
- $client->setAuth('shahar', 'myPassword!', Zend_Http_Client::AUTH_BASIC);
- // Since basic auth is default, you can just do this:
- $client->setAuth('shahar', 'myPassword!');
- // You can also specify username and password in the URI
- $client->setUri('http://christer:secret@example.com');
- ]]></programlisting>
- </example>
- </para>
- </sect2>
- <sect2 id="zend.http.client.multiple_requests">
- <title>Sending Multiple Requests With the Same Client</title>
- <para>
- <classname>Zend_Http_Client</classname> was also designed specifically to handle several
- consecutive requests with the same object. This is useful in cases
- where a script requires data to be fetched from several places, or
- when accessing a specific <acronym>HTTP</acronym> resource requires logging in and
- obtaining a session cookie, for example.
- </para>
- <para>
- When performing several requests to the same host, it is highly
- recommended to enable the 'keepalive' configuration flag. This way,
- if the server supports keep-alive connections, the connection to the
- server will only be closed once all requests are done and the Client
- object is destroyed. This prevents the overhead of opening and
- closing <acronym>TCP</acronym> connections to the server.
- </para>
- <para>
- When you perform several requests with the same client, but want
- to make sure all the request-specific parameters are cleared, you
- should use the resetParameters() method. This ensures that <constant>GET</constant> and
- POST parameters, request body and request-specific headers are
- reset and are not reused in the next request.
- </para>
- <note>
- <title>Resetting parameters</title>
- <para>
- Note that non-request specific headers are not reset by default
- when the <methodname>resetParameters()</methodname> method is used.
- Only the 'Content-length' and 'Content-type' headers are reset. This
- allows you to set-and-forget headers like 'Accept-language' and
- 'Accept-encoding'
- </para>
- <para>
- To clean all headers and other data except for URI and method, use
- <methodname>resetParameters(true)</methodname>.
- </para>
- </note>
- <para>
- Another feature designed specifically for consecutive requests is
- the Cookie Jar object. Cookie Jars allow you to automatically save
- cookies set by the server in the first request, and send them on
- consecutive requests transparently. This allows, for example, going
- through an authentication request before sending the actual data
- fetching request.
- </para>
- <para>
- If your application requires one authentication request per user,
- and consecutive requests might be performed in more than one script
- in your application, it might be a good idea to store the Cookie Jar
- object in the user's session. This way, you will only need to
- authenticate the user once every session.
- </para>
- <example id="zend.http.client.multiple_requests.example-1">
- <title>Performing consecutive requests with one client</title>
- <programlisting language="php"><![CDATA[
- // First, instantiate the client
- $client = new Zend_Http_Client('http://www.example.com/fetchdata.php', array(
- 'keepalive' => true
- ));
- // Do we have the cookies stored in our session?
- if (isset($_SESSION['cookiejar']) &&
- $_SESSION['cookiejar'] instanceof Zend_Http_CookieJar) {
- $client->setCookieJar($_SESSION['cookiejar']);
- } else {
- // If we don't, authenticate and store cookies
- $client->setCookieJar();
- $client->setUri('http://www.example.com/login.php');
- $client->setParameterPost(array(
- 'user' => 'shahar',
- 'pass' => 'somesecret'
- ));
- $client->request(Zend_Http_Client::POST);
- // Now, clear parameters and set the URI to the original one
- // (note that the cookies that were set by the server are now
- // stored in the jar)
- $client->resetParameters();
- $client->setUri('http://www.example.com/fetchdata.php');
- }
- $response = $client->request(Zend_Http_Client::GET);
- // Store cookies in session, for next page
- $_SESSION['cookiejar'] = $client->getCookieJar();
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.http.client.streaming">
- <title>Data Streaming</title>
- <para>
- By default, <classname>Zend_Http_Client</classname> accepts and returns data as
- <acronym>PHP</acronym> strings. However, in many cases there are big files to be sent or
- received, thus keeping them in memory might be unnecessary or too expensive. For these
- cases, <classname>Zend_Http_Client</classname> supports reading data from files (and in
- general, <acronym>PHP</acronym> streams) and writing data to files (streams).
- </para>
- <para>
- In order to use stream to pass data to <classname>Zend_Http_Client</classname>,
- use <methodname>setRawData()</methodname> method with data argument being stream
- resource (e.g., result of <methodname>fopen()</methodname>).
- <example id="zend.http.client.streaming.example-1">
- <title>Sending file to HTTP server with streaming</title>
- <programlisting language="php"><![CDATA[
- $fp = fopen("mybigfile.zip", "r");
- $client->setRawData($fp, 'application/zip')->request('PUT');
- ]]></programlisting>
- </example>
- </para>
- <para>
- Only PUT requests currently support sending streams to <acronym>HTTP</acronym> server.
- </para>
- <para>
- In order to receive data from the server as stream, use
- <methodname>setStream()</methodname>. Optional argument specifies the filename where the
- data will be stored. If the argument is just <constant>TRUE</constant> (default),
- temporary file will be used and will be deleted once response object is destroyed.
- Setting argument to <constant>FALSE</constant> disables the streaming functionality.
- </para>
- <para>
- When using streaming, <methodname>request()</methodname> method will return object of
- class <classname>Zend_Http_Client_Response_Stream</classname>, which has two useful
- methods: <methodname>getStreamName()</methodname> will return the name of the file where
- the response is stored, and <methodname>getStream()</methodname> will return stream from
- which the response could be read.
- </para>
- <para>
- You can either write the response to pre-defined file, or use temporary file for storing
- it and send it out or write it to another file using regular stream functions.
- <example id="zend.http.client.streaming.example-2">
- <title>Receiving file from HTTP server with streaming</title>
- <programlisting language="php"><![CDATA[
- $client->setStream(); // will use temp file
- $response = $client->request('GET');
- // copy file
- copy($response->getStreamName(), "my/downloads/file");
- // use stream
- $fp = fopen("my/downloads/file2", "w");
- stream_copy_to_stream($response->getStream(), $fp);
- // Also can write to known file
- $client->setStream("my/downloads/myfile")->request('GET');
- ]]></programlisting>
- </example>
- </para>
- </sect2>
- </sect1>
|