CouchDBのWrapper By PHPらしきもの。

です。探しても無かったので作りました。ライセンスはBSDで。
検証は、PHP 5.3 + CouchDBv0.91 @ Ubuntu9.04です

<?php
class CouchdbWapper{
	private $dbaddress;
	private $dbname;
	private $ngObj;
	private $default_couchdb_port="5984";

	function __construct($dbaddress="localhost",$dbname="mydb") {
		$this->dbaddress = $dbaddress;
		$this->dbname = $dbname;
		$this->ngObj = new stdClass;
		$this->ngObj->error = "NG";
	}
	
	function createDB($dbname=""){
		$res = $this->getDBinfo($dbname);
		if($res->error=="not_found"){
			return $this->httpConnect("PUT",$this->dbaddress,$dbname);
		}else{
			return $this->ngObj;
		}
	}
	function deleteDB($dbname=""){
		$res = $this->getDBinfo($dbname);
		if($res->error==""){
			return $this->httpConnect("DELETE",$this->dbaddress,$dbname);
		}else{
			return $this->ngObj;
		}
	}
	function getDBinfo($dbname=""){
		if($dbname=="")$dbname = $this->dbname;
		return $this->httpConnect("GET",$this->dbaddress,$dbname);
	}
	function getRevs($dbname="",$id=""){
		if($dbname=="")$dbname = $this->dbname;
		if($id!=""){
			return $this->httpConnect("GET",$this->dbaddress,$dbname."/".$id."?revs=true");
		}else{
			return $this->ngObj;
		}
	}
	
	function get($dbname="",$id=""){
		if($dbname=="")$dbname = $this->dbname;
		if($id!=""){
			$id!=urlencode($id);
			return $this->httpConnect("GET",$this->dbaddress,$dbname."/".$id);
		}else{
			return $this->ngObj;
		}
	}
	function getDesign($dbname="",$design_name=""){
		if($dbname=="")$dbname = $this->dbname;
		if($design_name!=""){
			return $this->httpConnect("GET",$this->dbaddress,$dbname."/_design/".$design_name);
		}else{
			return $this->ngObj;
		}
	}
	function getView($dbname="",$design_name="",$view_name=""){
		if($dbname=="")$dbname = $this->dbname;
		if($design_name!="" && $view_name!= ""){
			return $this->httpConnect("GET",$this->dbaddress,$dbname."/_design/".$design_name."/_view/".$view_name);
		}else{
			return $this->ngObj;
		}
	}
	function put($dbname="",$id="",$rev="",$data=array('test1'=>'wwwwww')){
		if($dbname=="")$dbname = $this->dbname;
		if($id != "" && $rev!=""){
			$data["_rev"] = $rev;
			return $this->httpConnect("PUT",$this->dbaddress,$dbname."/".$id,$data);
		}else{
			return $this->ngObj;
		}
	}
	function putDesign($dbname="",$design_name="",$rev="3-22222222",$data=array('test1'=>'wwwwww')){
		if($dbname=="")$dbname = $this->dbname;
		if($design_name != "" && $rev!=""){
			$data["_rev"] = $rev;
			return $this->httpConnect("PUT",$this->dbaddress,$dbname."/_design/".$design_name,$data);
		}else{
			return $this->ngObj;
		}
	}
	function orverrideDesign($dbname="",$design_name="",$data=array('test1'=>'wwwwww')){
		if($dbname=="")$dbname = $this->dbname;
		if($design_name != "" ){
			$dataCurrent = $this->getDesign($dbname,$design_name);
			if($dataCurrent->_id==""){
				return $this->postDesign($dbname,$design_name,$data);
			}else{
				return $this->putDesign($dbname,$design_name,$dataCurrent->_rev,$data);
			}
		}else{
			return $this->ngObj;
		}
	}
	function post($dbname="",$data=array('test1'=>'test2','testA'=>'testB')){
		if($dbname=="")$dbname = $this->dbname;
		return $this->httpConnect("POST",$this->dbaddress,$dbname,$data);
	}
	function postDesign($dbname="",$design_name="",$data=array('test1'=>'wwwwww')){
		if($dbname=="")$dbname = $this->dbname;
		if($design_name != "" ){
			return $this->httpConnect("PUT",$this->dbaddress,$dbname."/_design/".$design_name,$data);
		}else{
			return $this->ngObj;
		}
	}
	function delete($dbname="",$_id="",$_rev=""){
			if($dbname=="")$dbname = $this->dbname;
		if($_id!="" && $_rev!=""){
			return $this->httpConnect("DELETE",$this->dbaddress,$dbname."/".$_id."?rev=".$_rev);
		}else{
			return $this->ngObj;
		}
	}
	private function httpConnect($method,$host = "localhost",$path="",$post=""){
		if($path=="")$path = $this->dbname;
		$request  = "$method /$path HTTP/1.1\n";
		$request .= "Host: $host\n";
    	$request .= "User-Agent: PHP/".phpversion()."\n";
	    if ((strtoupper($method) == "POST" || strtoupper($method) == "PUT") && $post!="") {
	        $postdata = json_encode($post);
	        $request .= "Content-Type: application/json\n";
	        $request .= "Content-Length: ".strlen($postdata)."\n";
	        $request .= "Accept: application/json\n";
	        $request .= "Accept-Encoding: gzip,deflate\n";
	        $request .= "Keep-Alive: 300\n";
	        $request .= "\n";
	        $request .= $postdata;//;
    	}else{
			$request .= "\n";
    	}
	    $fp = fsockopen($host, $this->default_couchdb_port);
	
	    if (!$fp) {
	    	echo "fp";
	        die("ERROR\n");
	    }
	
	    fputs($fp, $request,strlen($request));
	    $response = "";
	    $length = 0;
	    $nowlen = 0;
	    $isBodyFlag = false;
	    $isInChankFlag = false;
	    $isChankedFlag = false;
	    $ress = array();
	    while (!feof($fp)) {
			$res =fgets($fp, 128);//1 row Read
	    	$isAddFlag = true;
	        array_push($ress,$res);
			if($length==0 && preg_match("/Content-Length:\s([0-9]+)/",$res,$match)){
				$length = $match[1];
			}else if($length==0 && preg_match("/Transfer-Encoding: chunked/",$res,$match)){
				$isInChankFlag = true;
				$isChankedFlag = true;
			}else if($isBodyFlag!=true && $res == "\r\n" && ($isInChankFlag==true ||$length>0)){	
				$isBodyFlag=true;
			}else if($isInChankFlag==true && $isBodyFlag==true){
				$torkens = explode("\r\n",$res);
				$length = hexdec($torkens[0]);
				$isInChankFlag = false;
				array_pop($ress);
				$nowlen = 0;
				if($length<1) break;
			}else if($isBodyFlag==true){
				$nowlen+=strlen($res);
				if($nowlen >= $length){
					if($isChankedFlag ==true){
						$isInChankFlag=true;
					}else{
						break;
					}
				} 
			}
			if($res=="" || $res=="\n"){
				break;
			}
			
	    }
	    fclose($fp);
		$respons = explode("\r\n\r\n",implode("",$ress));
		$values = array();
		for($i=1;$i<count($respons);$i++){
			array_push($values,$respons[$i]);
		}
		$value = implode("",$values);
		$resdata 	= json_decode($value);
		if($resdata==NULL){
			$resdata = new stdClass;
			$resdata->count = json_decode($resV,true);
		}
		return $resdata;
	}
}