|
<?php
//------------------------------------------------------------------- // gRESTbook.php: an example RESTy web service for a Guestbook //------------------------------------------------------------------- // For more info, see: http://muellerware.org/projects/gRESTbook/ //------------------------------------------------------------------- // Copyright (c) 2007 Patrick Mueller // Using the MIT license: // http://www.opensource.org/licenses/mit-license.php //------------------------------------------------------------------- // 2007/03/xx - Patrick Mueller - pmuellr@yahoo.com //-------------------------------------------------------------------
require_once 'Zend/Json.php';
require_once 'gRESTbookData.php'; require_once 'gRESTbookURL.php';
//------------------------------------------------------------------- // This class models the incoming request; basically it's just // parsing up the 'CGI' variables and placing them in the class's // properties. //------------------------------------------------------------------- class Request {
//------------------------------------------------------------------- // get a 'CGI' variable; return blank if not there //------------------------------------------------------------------- private function getServerVar($key) { if (isset($_SERVER[$key])) return $_SERVER[$key]; return ''; }
//------------------------------------------------------------------- // get the 'CGI' variables we're interested in, and normalize //------------------------------------------------------------------- public function __construct() { $this->requestMethod = $this->getServerVar('REQUEST_METHOD'); $this->queryString = $this->getServerVar('QUERY_STRING'); $this->pathInfo = $this->getServerVar('PATH_INFO'); $this->accept = $this->getServerVar('HTTP_ACCEPT'); $this->acceptEncoding = $this->getServerVar('HTTP_ACCEPT_ENCODING'); $this->acceptCharset = $this->getServerVar('HTTP_ACCEPT_CHARSET'); $this->contentType = $this->getServerVar('CONTENT_TYPE'); // if no path info provided, set to / if ("" == $this->pathInfo) $this->pathInfo = "/"; // get the next path element in the path info; // for the container itself (no path element provided), // this will be the empty string $pieces = explode('/', $this->pathInfo); $this->resourceName = $pieces[1]; } //------------------------------------------------------------------- // diagnostic method to dump the variables to the HTTP response, // and leave. //------------------------------------------------------------------- public function dump() { header('Content-Type: text/plain'); echo (string) $this; exit; } //------------------------------------------------------------------- // nice human readable description of the class //------------------------------------------------------------------- public function __toString() { $result = __CLASS__ . "{\n"; $result .= " requestMethod: $this->requestMethod\n"; $result .= " queryString: $this->queryString\n"; $result .= " pathInfo: $this->pathInfo\n"; $result .= " resourceName: $this->resourceName\n"; $result .= " accept: $this->accept\n"; $result .= " acceptEncoding: $this->acceptEncoding\n"; $result .= " acceptCharset: $this->acceptCharset\n"; $result .= " contentType: $this->contentType\n"; $result .= "}"; return $result; } }
//------------------------------------------------------------------- // function to set the HTTP status code, and leave; used for // error returns //------------------------------------------------------------------- function httpStatus($code, $message) { header("HTTP/1.1 $code $message"); exit; }
//------------------------------------------------------------------- // de-multiplex the service requests against the collection //------------------------------------------------------------------- function handleCollection($request) { switch ($request->requestMethod) { case 'GET': handleCollectionGet($request); break; case 'POST': handleCollectionPost($request); break; default: httpStatus(405, "Method Not Allowed"); break; } }
//------------------------------------------------------------------- // de-multiplex the service requests for items //------------------------------------------------------------------- function handleItem($request, $resourceName) { switch ($request->requestMethod) { case 'GET': handleItemGet($request, $resourceName); break; case 'PUT': handleItemPut($request, $resourceName); break; case 'DELETE': handleItemDelete($request, $resourceName); break; default: httpStatus(405, "Method Not Allowed"); break; } }
//------------------------------------------------------------------- // return a list of entries in the collection //------------------------------------------------------------------- function handleCollectionGet($request) { $db = $request->db; $entries = $db->query(); if (strstr($request->accept,'text/json')) { header('Content-Type: text/json'); print Zend_Json::encode($entries); return; } header('Content-Type: text/html'); print "<ul>\n"; foreach ($entries as $entry) { $line = '<li><a href="' . $entry . '">' . $entry . "</a></li>\n"; } print "</ul>\n"; }
//------------------------------------------------------------------- // add a new entry to the collection //------------------------------------------------------------------- function handleCollectionPost($request) { $db = $request->db; if ($request->ContentType != 'text/json') { httpStatus(415, 'Unsupported Media Type'); } $data = file_get_contents("php://input"); $entry = GRESTbookEntry::fromJSON($data); $db->create($entry); header('Location: ' . gRESTbookURL . '/' . $entry->id); }
//------------------------------------------------------------------- // get an entry from the collection //------------------------------------------------------------------- function handleItemGet($request, $resourceName) { $db = $request->db; $entry = $db->read($resourceName); if (null == $entry) { httpStatus(404, 'Not found'); return; } if (strstr($request->accept,'text/json')) { header('Content-Type: text/json'); header('ETag: ' . $entry->eTag); header('Last-Modified' . date('r', $entry->dateModified)); print $entry->toJSON(); return; } header('Content-Type: text/html'); header('ETag: ' . $entry->eTag); header('Last-Modified' . date('r', $entry->dateModified)); print '<h1>' . $entry->id . "</h1>\n"; print '<span class="author">' . $entry->author . "</span> :\n"; print '<span class="message">' . $entry->message . "</span> :\n"; }
//------------------------------------------------------------------- // update an entry in the collection //------------------------------------------------------------------- function handleItemPut($request, $resourceName) { }
//------------------------------------------------------------------- // delete an entry in the collection //------------------------------------------------------------------- function handleItemDelete($request, $resourceName) { }
//------------------------------------------------------------------- // main processing starts here //-------------------------------------------------------------------
//------------------------------------------------------------------- // create the data accessor object //------------------------------------------------------------------- $db = new GRESTbookDB();
//------------------------------------------------------------------- // create the request object //------------------------------------------------------------------- $request = new Request(); $request->db = $db;
// $request->dump();
// de-multiplex the request into either a collection or entry operation if ('' == $request->resourceName) { handleCollection($request); } else { handleItem($request, $request->resourceName); }
//------------------------------------------------------------------- // //------------------------------------------------------------------- // phpinfo();
?>
|