php封装rest获取数据库,手把手教你使用PHP实现REST的HTTP客户端

近来出现了很多REST的API,配合JSONP一起,很容易开发出结构清晰的应用。

我们最近在研究CouchDB。 它有一整套的REST API。

人们已经开发了很多php库,甚至PHP培训(www.tarenaphp.com)扩展来调用CouchDB。

我最喜欢Zend Framework里面的REST client。

但是为了练习一下,我决定自己写一个HTTP client。

我的目的是:创建一个简单的class,可以向远程服务器发送GET ,POST, DELETE请求。

虽然还没有开始进行设计与编码,但我想,我的class应该这样被调用:

echo Http::connect('localhost', 8082)

->doGet('tests/httpclient/dummy.php', array('a' => "a a a"));

PS:这应该算是TDD吧,测试驱动开发。

首先我要实现connect函数,在这个函数里面我不想真的去连接服务器。

应该是在doGet的时候再去连接比较合适。

就像lftp一样,当你在命令行输入

[[email protected] tmp]# lftp 192.168.0.100

lftp 192.168.0.100:~>user uuu  ppp

这时其实没有进行真的连接。

只有在你上传/下载/列表文件的时候,才会进行第一次连接。

回到正题,我把connect作成了一个factory函数,它只是保存一下配置信息,

然后返回一个本类的实例。

private $_host = null;  private $_port = null;  private $_user = null;  private $_pass = null;

/**

* Factory of the class. Lazy connect

*

* @param string $host

* @param integer $port

* @param string $user

* @param string $pass

* @return Http

*/  static public function connect($host, $port, $user=null, $pass=null)  {

return new self($host, $port, $user, $pass);  }  protected function __construct($host, $port, $user, $pass)  {

$this->_host = $host;

$this->_port = $port;

$this->_user = $user;

$this->_pass = $pass;  }

下面为每种操作方式写函数(doGet,doPost,doDelete)

const POST   = 'POST';  const GET    = 'GET';  const DELETE = 'DELETE';

/**

* POST request

*

* @param string $url

* @param array $params

* @return string

*/  public function doPost($url, $params=array())  {

return $this->_exec(self::POST, $this->_url($url), $params);  }

/**

* GET Request

*

* @param string $url

* @param array $params

* @return string

*/  public function doGet($url, $params=array())  {

return $this->_exec(self::GET, $this->_url($url), $params);  }

/**

* DELETE Request

*

* @param string $url

* @param array $params

* @return string

*/  public function doDelete($url, $params=array())  {

return $this->_exec(self::DELETE, $this->_url($url), $params);  }

它们只是去调用了 _exec()函数。

再加入一个设置Header的函数:

private $_headers = array();  /**

* setHeaders

*

* @param array $headers

* @return Http

*/  public function setHeaders($headers)  {

$this->_headers = $headers;

return $this;  }

每个函数都返回了这个类的实例,是因为我比较喜欢链式写法。

就像下面这样:

echo Http::connect('localhost', 8082)

->setHeaders($myCustomHeaders)

->doGet('tests/httpclient/dummy.php', array('a' => "a a a"));

最后来看 _exec()函数。在PHP培训里面,有很多方法来实现它的功能,

在这里我用了CURL。 请看一下phpinfo(),确认你的php支持不支持curl。

不支持的时候,您可以使用socket函数。

const HTTP_OK = 200;  const HTTP_CREATED = 201;  const HTTP_ACEPTED = 202;

/**

* Performing the real request

*

* @param string $type

* @param string $url

* @param array $params

* @return string

*/  private function _exec($type, $url, $params = array())  {

$headers = $this->_headers;

$s = curl_init();

if(!is_null($this->_user)){

curl_setopt($s, CURLOPT_USERPWD, $this->_user.':'.$this->_pass);

}

switch ($type) {

case self::DELETE:

curl_setopt($s, CURLOPT_URL, $url . '?' . http_build_query($params));

curl_setopt($s, CURLOPT_CUSTOMREQUEST, self::DELETE);

break;

case self::POST:

curl_setopt($s, CURLOPT_URL, $url);

curl_setopt($s, CURLOPT_POST, true);

curl_setopt($s, CURLOPT_POSTFIELDS, $params);

break;

case self::GET:

curl_setopt($s, CURLOPT_URL, $url . '?' . http_build_query($params));

break;

}

curl_setopt($s, CURLOPT_RETURNTRANSFER, true);

curl_setopt($s, CURLOPT_HTTPHEADER, $headers);

$_out = curl_exec($s);

$status = curl_getinfo($s, CURLINFO_HTTP_CODE);

curl_close($s);

switch ($status) {

case self::HTTP_OK:

case self::HTTP_CREATED:

case self::HTTP_ACEPTED:

$out = $_out;

break;

default:

throw new Http_Exception("http error: {$status}", $status);

}

return $out;  }

恩,这里使用了一个 Http_Exception 的异常处理类。

class Http_Exception extends Exception{

const NOT_MODIFIED = 304;

const BAD_REQUEST = 400;

const NOT_FOUND = 404;

const NOT_ALOWED = 405;

const CONFLICT = 409;

const PRECONDITION_FAILED = 412;

const INTERNAL_ERROR = 500;  }

在向远程CouchDB服务器请求的过程中,如果出错,CouchDB会返回标准的HTTP STATUS CODE。所以上面的状态码,您应该是蛮熟悉的才对。

异常捕捉代码:

try {

echo Http::connect('localhost', 8082)

->doGet('tests/couchdb/a.php', array('a' => "a a a"));  } catch (Http_Exception $e) {

switch ($e->getCode()) {

case Http_Exception::INTERNAL_ERROR:

// do something

break;

}  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值