', $nam); } public function fieldValue($nam, $val) { return sprintf('<%s>%s', $nam, $val, $nam); } public function fieldSeparator() { return ''; } public function fieldSuffix($nam) { return sprintf('', $nam); } public function arrayPrefix($nam) { return sprintf('<%s>', $nam); } public function arrayValue($val) { return $val; } public function arraySeparator() { return ''; } public function arraySuffix($nam) { return sprintf('', $nam); } } class Util { private static function Object2Anything($o, $fmt) { $clz = strtolower(get_class($o)); if(substr($clz, -5) == 'array' && isset($o->array)) { $res = $fmt->arrayPrefix($clz); foreach($o->array as $elm) { if(strlen($res) > 1) $res .= $fmt->arraySeparator(); $res .= $fmt->arrayValue(Util::Object2Anything($elm, $fmt)); } $res .= $fmt->arraySuffix($clz); return $res; } else { $res = $fmt->fieldPrefix($clz); foreach(get_object_vars($o) as $nam => $val) { if(strlen($res) > 1) $res .= $fmt->fieldSeparator(); $res .= $fmt->fieldValue($nam, is_object($val) ? Util::Object2Anything($val, $fmt) : $val); } $res .= $fmt->fieldSuffix($clz); return $res; } } public static function Object2JSON($o) { return Util::Object2Anything($o, new JSONFormatter()); } public static function Object2XML($o) { return Util::Object2Anything($o, new XMLFormatter()); } public static function Object2String($o, $typ) { if($typ == 'application/xml') { return Util::Object2XML($o); } else if($typ == 'application/json') { return Util::Object2JSON($o); } else { throw new Exception('Unknown type: ' . $typ); } } private static function mapFields(&$fromobj, &$toobj) { foreach(get_object_vars($toobj) as $nam => $val) { if(is_object($toobj->$nam) || is_array($toobj->$nam)) { Util::map($fromobj->$nam, $toobj->$nam); } else { if(is_int($toobj->$nam)) { $toobj->$nam = (int)$fromobj->$nam; } else { $toobj->$nam = (string)$fromobj->$nam; } } } } private static function mapArray(&$fromarr, &$toarr, $arrelmclz) { foreach($fromarr as $elm) { $temp = new $arrelmclz(); Util::map($elm, $temp); $toarr[] = $temp; } } private static function map(&$fromobj, &$toobj) { $clz = strtolower(get_class($toobj)); if(substr($clz, -5) == 'array' && isset($toobj->array)) { $arrelmclz = substr(get_class($toobj), 0 , -5); $temp = $fromobj; if(isset($fromobj->array)) $temp = $fromobj->array; $f1 = strtolower($arrelmclz . 'array'); $f2 = strtolower($arrelmclz); if(isset($fromobj->$f1)) $temp = $fromobj->$f1->$f2; Util::mapArray($temp, $toobj->array, $arrelmclz); } else { Util::mapFields($fromobj, $toobj); } } public static function XML2Object($clz, $xml) { $temp = simplexml_load_string($xml); $res = new $clz(); Util::map($temp, $res); return $res; } public static function JSON2Object($clz, $json) { $temp = json_decode($json); $res = new $clz(); Util::map($temp, $res); return $res; } public static function String2Object($clz, $s, $typ) { if($typ == 'application/xml') { return Util::XML2Object($clz, $s); } else if($typ == 'application/json') { return Util::JSON2Object($clz, $s); } else { throw new Exception('Unknown type: ' . $typ); } } } */ /* * Minimalistic/hardcoded serializer/deserializer framework. */ class Util { public static function Object2JSON($o) { $clz = get_class($o); switch($clz) { // simple data classes case 'T1': return json_encode($o); // array wrapper classes case 'T1Array': return json_encode($o->array); default: throw new Exception('Unknown type: ' . $clz); } } public static function Object2XML($o) { $clz = get_class($o); $res = sprintf('<%s>', strtolower($clz)); switch($clz) { // simple data classes case 'T1': foreach(get_object_vars($o) as $nam => $val) { $res .= sprintf('<%s>%s', $nam, $val, $nam); } break; // array wrapper classes case 'T1Array': foreach($o->array as $elm) { $res .= Util::Object2XML($elm); } break; default: throw new Exception('Unknown type: ' . $clz); } $res .= sprintf('', strtolower($clz)); return $res; } public static function Object2String($o, $typ) { if($typ == 'application/xml') { return Util::Object2XML($o); } else if($typ == 'application/json') { return Util::Object2JSON($o); } else { throw new Exception('Unknown type: ' . $typ); } } public static function XML2Object($clz, $xml) { $temp = simplexml_load_string($xml); $res = new $clz(); switch($clz) { // simple data classes case 'T1': foreach(get_object_vars($res) as $nam => $val) { if(is_int($res->$nam)) { $res->$nam = (int)$temp->$nam; } else { $res->$nam = (string)$temp->$nam; } } break; // array wrapper classes case 'T1Array': $elmclz = substr($clz, 0, -5); foreach($temp as $elm) { $o = new $elmclz(); foreach(get_object_vars($o) as $nam => $val) { if(is_int($o->$nam)) { $o->$nam = (int)$elm->$nam; } else { $o->$nam = (string)$elm->$nam; } } $res->array[] = $o; } break; default: throw new Exception('Unknown type: ' . $clz); } return $res; } public static function JSON2Object($clz, $json) { $temp = json_decode($json); $res = new $clz(); switch($clz) { // simple data classes case 'T1': foreach(get_object_vars($res) as $nam => $val) { $res->$nam = $temp->$nam; } break; // array wrapper classes case 'T1Array': $elmclz = substr($clz, 0, -5); foreach($temp as $elm) { $o = new $elmclz(); foreach(get_object_vars($o) as $nam => $val) { $o->$nam = $elm->$nam; } $res->array[] = $o; } break; default: throw new Exception('Unknown type: ' . $clz); } return $res; } public static function String2Object($clz, $s, $typ) { if($typ == 'application/xml') { return Util::XML2Object($clz, $s); } else if($typ == 'application/json') { return Util::JSON2Object($clz, $s); } else { throw new Exception('Unknown type: ' . $typ); } } } class T1 { public $f1; public $f2; public function __construct($f1 = 0, $f2 = '') { $this->f1 = $f1; $this->f2 = $f2; } public function __toString() { return sprintf('{%s,%s}', $this->f1, $this->f2); } } class T1Array { public $array; public function __construct($array = array()) { $this->array = $array; } } function testGetOne($urlprefix, $f1, $acctyp) { $curl = curl_init($urlprefix . '/t1/' . $f1); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: ' . $acctyp)); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($curl); $info = curl_getinfo($curl); curl_close($curl); echo (200 <= $info['http_code'] && $info['http_code'] < 300 ? 'true' : 'false') . "\r\n"; echo Util::String2Object('T1', $response, $acctyp) . "\r\n"; } function testGetAll($urlprefix, $acctyp) { $curl = curl_init($urlprefix . '/t1'); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: ' . $acctyp)); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($curl); $info = curl_getinfo($curl); curl_close($curl); echo (200 <= $info['http_code'] && $info['http_code'] < 300 ? 'true' : 'false') . "\r\n"; $a = Util::String2Object('T1Array', $response, $acctyp)->array; foreach($a as $o) echo $o; echo "\r\n"; } function testGetSome($urlprefix, $start, $finish, $acctyp) { $curl = curl_init($urlprefix . '/t1?start=' . $start . '&finish=' . $finish); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: ' . $acctyp)); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($curl); $info = curl_getinfo($curl); curl_close($curl); echo (200 <= $info['http_code'] && $info['http_code'] < 300 ? 'true' : 'false') . "\r\n"; $a = Util::String2Object('T1Array', $response, $acctyp)->array; foreach($a as $o) echo $o; echo "\r\n"; } function testPost($urlprefix, $contyp, $o, $acctyp) { $curl = curl_init($urlprefix . '/t1'); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: ' . $acctyp, 'Content-Type: ' . $contyp)); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, Util::Object2String($o, $contyp)); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($curl); $info = curl_getinfo($curl); curl_close($curl); echo (200 <= $info['http_code'] && $info['http_code'] < 300 ? 'true' : 'false') . "\r\n"; echo Util::String2Object('T1', $response, $acctyp) . "\r\n"; } function testPut($urlprefix, $contyp, $o) { $curl = curl_init($urlprefix . '/t1/' . $o->f1); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: ' . $contyp)); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); curl_setopt($curl, CURLOPT_POSTFIELDS, Util::Object2String($o, $contyp)); curl_exec($curl); $info = curl_getinfo($curl); curl_close($curl); echo (200 <= $info['http_code'] && $info['http_code'] < 300 ? 'true' : 'false') . "\r\n"; } function testDelete($urlprefix, $f1) { $curl = curl_init($urlprefix . '/t1/' . $f1); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); curl_exec($curl); $info = curl_getinfo($curl); curl_close($curl); echo (200 <= $info['http_code'] && $info['http_code'] < 300 ? 'true' : 'false') . "\r\n"; } function test2($urlprefix, $typ) { echo '**** ' . $urlprefix . ' (' . $typ . ') ****' . "\r\n"; testGetOne($urlprefix, 123, $typ); testGetAll($urlprefix, $typ); testGetSome($urlprefix, 10, 12, $typ); testPost($urlprefix, $typ, new T1(123, 'ABC'), $typ); testPut($urlprefix, $typ, new T1(123, 'ABC')); testDelete($urlprefix, 123); } function test($urlprefix) { test2($urlprefix, "application/xml"); test2($urlprefix, "application/json"); } test("http://localhost:8080/wsrest/testapi1"); test("http://localhost:8080/wsrest/testapi2"); test("http://localhost/testapi.ashx"); test("http://localhost/testapi.svc"); test("http://localhost/testapi"); test("http://localhost:81/testapi.php"); ?>