|
<?php
//------------------------------------------------------------------- // ToyModSer.php: serialize an object given metadata //------------------------------------------------------------------- // Copyright (c) 2007 Patrick Mueller // Using the MIT license: // http://www.opensource.org/licenses/mit-license.php //------------------------------------------------------------------- // 2007/05 - Patrick Mueller - pmuellr@yahoo.com //-------------------------------------------------------------------
require_once 'Zend/Json.php';
class ToyModSer {
private $className; private $properties; //--------------------------------------------------------------- // Create an instance of this class, for the specified model class //--------------------------------------------------------------- public function __construct($className) { // save the name $this->className = $className; // get the property information $this->getPropertyMetadata(); // check the types to make sure they are valid. foreach ($this->properties as $name => $type) { switch ($type) { case "integer": break; case "string": break; default: $msg = "invalid type for property '$name': '$type'"; throw new Exception($msg); } } } //--------------------------------------------------------------- // convert the object passed in to JSON //--------------------------------------------------------------- public function toJSON($object) {
// make sure the class of the object matches the serializer if (get_class($object) != $this->className) { $msg = "attempting to serialize instance of '" . get_class($object) . "' with a serializer for '" . $this->className . "'"; throw new Exception($msg); } // initialize the array to convert to JSON $toSerialize = array(); // get the properties set on the object instance $instanceProperties = get_object_vars($object); // for each model property ... foreach ($this->properties as $name => $type) { // get the value of the property $value = $instanceProperties[$name]; // check it's type $wrongType = false; switch ($type) { case "integer": if (!is_int($value)) $wrongType = true; break; case "string": if (!is_string($value)) $wrongType = true; break; } // if it's the wrong type, throw an exception if ($wrongType) { $msg = "property '$name' is not the expected type"; throw new Exception($msg); }
// looks good, save the value away $toSerialize[$name] = $value; }
return Zend_JSON::encode($toSerialize); }
//--------------------------------------------------------------- // convert the json passed in to an object //--------------------------------------------------------------- public function fromJSON($string) { $fromSerialize = Zend_JSON::decode($string); $result = new $this->className(); // for each model property ... foreach ($this->properties as $name => $type) { // get the value of the property $value = $fromSerialize[$name]; // check it's type $wrongType = false; switch ($type) { case "integer": if (!is_int($value)) $wrongType = true; break; case "string": if (!is_string($value)) $wrongType = true; break; } // if it's the wrong type, throw an exception if ($wrongType) { $msg = "property '$name' is not the expected type"; throw new Exception($msg); } $result->$name = $value; } return $result; }
//--------------------------------------------------------------- // get the class meta data for the properties //--------------------------------------------------------------- private function getPropertyMetadata() {
// initialize the properties that we'll be setting $this->properties = array(); // get the properties defined on the class $refClass = new ReflectionClass($this->className); $refProperties = $refClass->getProperties(); // for each property ... foreach ($refProperties as $refProperty) {
// get the property name and doc comment $name = $refProperty->getName(); $docComment = $refProperty->getDocComment(); // get the type from the doc comment, if available $type = $this->getTypeFromDocComment($docComment); if (null == $type) continue; // if a type was specified in the doc comment, set it $this->properties[$name] = $type; } }
//--------------------------------------------------------------- // get the class meta data for the properties //--------------------------------------------------------------- private function getTypeFromDocComment($docComment) { // split the doc comment into lines $lines = explode("\n", $docComment); // for each line ... foreach ($lines as $line) {
// if it matches "@model type=foo", return "foo" $pattern = '/.*@model\s.*type\s*=\s*(\S+).*/'; if (preg_match($pattern, $line,$matches)) { return $matches[1]; } } // no match, return null return null; } }
?>
|