全部博文(315)
分类:
2008-02-28 13:33:15
Zend_Http_Client是基于一种连接适配器设计。连接适配器是对象,负责实际连接服务器,
以及写入请求和读取响应。这个连接适配器可以被替换,
你可以创建和扩展缺省的连接适配器以满足你的特殊要求,没必要用同样的接口来扩展和替换整个HTTP Client类
当前,Zend_Http_Client类提供了三个内建的连接适配器:
Zend_Http_Client_Adapter_Socket(default)
Zend_Http_Client_Adapter_Proxy
Zend_Http_Client_Adapter_Test
Zend_Http_Client对象的连接适配器设定使用‘适配器’的配置选项。
当实例化Client对象的时候,你可以用一个包含适配器名称的字符串(比如Zend_Http_Client_Adapter_Socket)
或者使用一个适配器对象(比如new Zend_Http_Client_Adapter_test)
的方式来设定‘适配器’的配置选项。
你也可以使用Zend_Http_Client->setConfig()方法来设定适配器
The Socket Adapter
缺省的连接适配器是Zend_Http_Client_Adapter_Socket适配器
-除非你明确的设定连接适配器。The Socket Adapter基于PHP内建的fsockopen方法,
不需要额外的插件或编辑标签
The Socket Adapter可以使用Zend_Http_Client->setConfig()
或者传给Client构造器来设定几个额外的配置选项。
这些选项均与HTTPS连接相关,连接非安全的Http Server时配置无效。
Parameter |
Description |
Expected Values |
Default Value |
ssltransport |
SSL transport layer (eg. 'sslv2', 'tls') |
string |
ssl |
sslcert |
PEM encoded SSL certificate file path |
string |
'/path/to/cert.pem' |
sslpassphrase |
Passphrase for the SSL certificate file |
string |
's0mes3cre7' |
上面所有参数都与使用HTTPS连接的SSL层关联。缺省的设定可以应对大多数的应用,
但如果你所连接的服务器需要特殊的客户端设定你也许会需要改变设定。
如果这样,你应该阅读关于SSL传输层和选项
例子:
// Set the configuration parameters
$config
= array(
'adapter'
=>
'Zend_Http_Client_Adapter_Socket'
,
'ssltransport'
=>
'tls'
);
// Instantiate a client object
$client
=
Zend_Http_Client
(
''
,
$config
);
// The following request will be sent over a TLS secure connection.
$response
=
$client
->
request
();
上面执行的结果将与使用下面的PHP命令打开一个TCP连接相似
fsockopen('tls://', 443)
The Proxy Adapter
Zend_Http_Client_Adapter_Proxy
适配器与缺省的Socket适配器类似-唯一不同的是它不是直接连接到目的服务器而是穿过Http 代理服务器。
这可以使得Zend_Http_Client在代理服务器后面有所应用-也许有时候出于安全和性能的要求。
使用Proxy适配器需要几个另外的配置参数设定,除缺省的‘adapter’选项之外
Table 17.3. Zend_Http_Client configuration parameters
Parameter |
Description |
Expected Type |
Example Value |
proxy_host |
Proxy server address |
string |
'proxy.myhost.com' or '10.1.2.3' |
proxy_port |
Proxy server TCP port |
integer |
8080 (default) or 81 |
proxy_user |
Proxy user name, if required |
string |
'shahar' or '' for none (default) |
proxy_pass |
Proxy password, if required |
string |
'secret' or '' for none (default) |
proxy_auth |
Proxy HTTP authentication type |
string |
Zend_Http_Client::AUTH_BASIC (default) |
Proxy_host应该首先被设定,如果没有,Client将返回并使用Zend_Http_Client_Adapter_Socket直接连接.Proxy_host缺省使用8080。
Proxy_user和Proxy_pass只有当proxy服务器需要认证的时候才需要。提供他们将添加一个Proxy-Authentication’的报头到请求当中。
如果你的Proxy不需要认证,他们将被忽略
Proxy_auth设定Proxy的认证类型。如果你的proxy服务器需要认证,该值可能会等同于Zend_Http_Client::setAuth()方法所设定的值。
目前只支持基本认证(Zend_Http_Client::AUTH_BASIC)
// Set the configuration parameters
$config
= array(
'adapter'
=>
'Zend_Http_Client_Adapter_Proxy'
,
'proxy_host'
=>
'proxy.int.zend.com'
,
'proxy_port'
=>
8000
,
'proxy_user'
=>
'shahar.e'
,
'proxy_pass'
=>
'bananashaped'
);
// Instantiate a client object
$client
=
Zend_Http_Client
(
'http://'
,
$config
);
// Continue working...
需要提醒的是,如果proxy_host没有被设定或是空字符串,将会返回作一般的直接连接。
这点在你的应用中很容易根据配置参数配置出一个可选的proxy连接。
The Test Adapter
有时候,很难依靠HTTP连接来测试代码。比如,测试一个应用从远端服务器获取RSS
将会需要一个网络连接,而这个连接并不总是可用的。
基于这个原因,提供了Zend_Http_Client_Adapter_Test适配器。你可以替换缺省
的适配器为Test适配器,使用它用来作单元测试模块,使之可以运行测试而并不需要
进行服务器的连接。
Zend_Http_Client_Adapter_Test
提供了另外的方法setResponse方法。一旦设定,
你的Test适配器将总会返回设定好的响应信息,甚至不会发起一个实际的HTTP请求。
// Instantiate a new adapter and client
$adapter
= new
Zend_Http_Client_Adapter_Test
();
$client
=
Zend_Http_Client
(
'http://'
, array(
'adapter'
=>
$adapter
));
// Set the expected response
$adapter
->
setResponse
(
"HTTP/1.1 200 OK"
.
"\r\n"
.
"Content-type: text/xml"
.
"\r\n"
.
"\r\n"
.
''
.
'
.
' xmlns:wfw=""'
.
' xmlns:dc="">'
.
'
' .
'
Premature Optimization '.
// and so on...
''
);
$response
=
$client
->
request
(
'GET'
);
// .. continue parsing $response..
这个例子演示了你可以预先设定好你的HTTP 客户端返回你所指定的响应。然后你可以
持续测试你自己的代码,并不需要一个网络连接、服务器响应信息等等。在这个例子,
测试将会继续测试应用程序怎么解析响应实体里面的xml。
有时,实例化对象后调用函数会导致对象发起多个HTTP会话。但在这里,你不能单独
使用setResponse方法,因为在返回给调用者之前,没有机会设定你应用程序所需的
下个响应。
// Instantiate a new adapter and client
$adapter
= new
Zend_Http_Client_Adapter_Test
();
$client
=
Zend_Http_Client
(
'http://'
, array(
'adapter'
=>
$adapter
));
// Set the first expected response
$adapter
->
setResponse
(
"HTTP/1.1 302 Found"
.
"\r\n"
.
"Location: /"
.
"\r\n"
.
"Content-Type: text/html"
.
"\r\n"
.
"\r\n"
.
''
.
'
Moved '.
'
This page has moved.
'.
''
);
// Set the next successive response
$adapter
->
addResponse
(
"HTTP/1.1 200 OK"
.
"\r\n"
.
"Content-Type: text/html"
.
"\r\n"
.
"\r\n"
.
''
.
'
My Pet Store Home Page '.
'
...
'.
''
);
// inject the http client object ($client) into your object
// being tested and then test your object's behavior below
setResponse
方法将清除Zend_Http_Client_Adapter_Test的缓存,并设定
第一个将要返回的响应。addResponse方法将添加之后的响应。响应将会依照添加
的顺序进行重放。
创建你自己的连接适配器
你可以创建你自己的连接适配器并使用它们。比如,创建一个连接适配器用来做持久
的sockets,或是一个有缓存功能的连接适配器,或是根据应用程序的需要来使用它们。
实现这点,你必须创建你自己的适配器类库,根据
Zend_Http_Client_Adapter_Interface来实现。
所有在下例中定义的公共函数均必须定义在你自己的适配器中
class
MyApp_Http_Client_Adapter_BananaProtocol
implements
Zend_Http_Client_Adapter_Interface
{
/**
* Set the configuration array for the adapter
* @param array $config
*/
public function
setConfig
(
$config
= array())
{
// This rarely changes - you should usually copy the implementation
// in Zend_Http_Client_Adapter_Socket.
}
/**
* Connect to the remote server
* @param string $host
* @param int $port
* @param boolean $secure
*/
public function
connect
(
$host
,
$port
=
80
,
$secure
=
false
)
{
// Set up the connection to the remote server
}
/**
* Send request to the remote server
* @param string $method
* @param Zend_Uri_Http $url
* @param string $http_ver
* @param array $headers
* @param string $body
* @return string Request as text
*/
public function
write
(
$method
,
$url
,
$http_ver
=
'1.1'
,
$headers
= array(),
$body
=
''
)
{
// Send request to the remote server.
// This function is expected to return the full request (headers and body) as a string
}
/**
* Read response from server
*
* @return string
*/
public function
read
()
{
// Read response from remote server and return it as a string
}
/**
* Close the connection to the server
*/
public function
close
()
{
// Close the connection to the remote server - called last.
}
}
// Then, you could use this adapter:
$client
= new
Zend_Http_Client
(array(
'adapter'
=>
'MyApp_Http_Client_Adapter_BananaProtocol'
));