File indexing completed on 2025-01-26 05:29:15
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Amf 0017 * @subpackage Parse_Amf0 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 /** Zend_Amf_Constants */ 0024 // require_once 'Zend/Amf/Constants.php'; 0025 0026 /** Zend_Xml_Security */ 0027 // require_once 'Zend/Xml/Security.php'; 0028 0029 /** @see Zend_Amf_Parse_Deserializer */ 0030 // require_once 'Zend/Amf/Parse/Deserializer.php'; 0031 0032 /** 0033 * Read an AMF0 input stream and convert it into PHP data types 0034 * 0035 * @todo Implement Typed Object Class Mapping 0036 * @todo Class could be implemented as Factory Class with each data type it's own class 0037 * @package Zend_Amf 0038 * @subpackage Parse_Amf0 0039 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0040 * @license http://framework.zend.com/license/new-bsd New BSD License 0041 */ 0042 class Zend_Amf_Parse_Amf0_Deserializer extends Zend_Amf_Parse_Deserializer 0043 { 0044 /** 0045 * An array of objects used for recursively deserializing an object. 0046 * @var array 0047 */ 0048 protected $_reference = array(); 0049 0050 /** 0051 * If AMF3 serialization occurs, update to AMF0 0x03 0052 * 0053 * @var int 0054 */ 0055 protected $_objectEncoding = Zend_Amf_Constants::AMF0_OBJECT_ENCODING; 0056 0057 /** 0058 * Read AMF markers and dispatch for deserialization 0059 * 0060 * Checks for AMF marker types and calls the appropriate methods 0061 * for deserializing those marker types. Markers are the data type of 0062 * the following value. 0063 * 0064 * @param integer $typeMarker 0065 * @return mixed whatever the data type is of the marker in php 0066 * @throws Zend_Amf_Exception for invalid type 0067 */ 0068 public function readTypeMarker($typeMarker = null) 0069 { 0070 if ($typeMarker === null) { 0071 $typeMarker = $this->_stream->readByte(); 0072 } 0073 0074 switch($typeMarker) { 0075 // number 0076 case Zend_Amf_Constants::AMF0_NUMBER: 0077 return $this->_stream->readDouble(); 0078 0079 // boolean 0080 case Zend_Amf_Constants::AMF0_BOOLEAN: 0081 return (boolean) $this->_stream->readByte(); 0082 0083 // string 0084 case Zend_Amf_Constants::AMF0_STRING: 0085 return $this->_stream->readUTF(); 0086 0087 // object 0088 case Zend_Amf_Constants::AMF0_OBJECT: 0089 return $this->readObject(); 0090 0091 // null 0092 case Zend_Amf_Constants::AMF0_NULL: 0093 return null; 0094 0095 // undefined 0096 case Zend_Amf_Constants::AMF0_UNDEFINED: 0097 return null; 0098 0099 // Circular references are returned here 0100 case Zend_Amf_Constants::AMF0_REFERENCE: 0101 return $this->readReference(); 0102 0103 // mixed array with numeric and string keys 0104 case Zend_Amf_Constants::AMF0_MIXEDARRAY: 0105 return $this->readMixedArray(); 0106 0107 // array 0108 case Zend_Amf_Constants::AMF0_ARRAY: 0109 return $this->readArray(); 0110 0111 // date 0112 case Zend_Amf_Constants::AMF0_DATE: 0113 return $this->readDate(); 0114 0115 // longString strlen(string) > 2^16 0116 case Zend_Amf_Constants::AMF0_LONGSTRING: 0117 return $this->_stream->readLongUTF(); 0118 0119 //internal AS object, not supported 0120 case Zend_Amf_Constants::AMF0_UNSUPPORTED: 0121 return null; 0122 0123 // XML 0124 case Zend_Amf_Constants::AMF0_XML: 0125 return $this->readXmlString(); 0126 0127 // typed object ie Custom Class 0128 case Zend_Amf_Constants::AMF0_TYPEDOBJECT: 0129 return $this->readTypedObject(); 0130 0131 //AMF3-specific 0132 case Zend_Amf_Constants::AMF0_AMF3: 0133 return $this->readAmf3TypeMarker(); 0134 0135 default: 0136 // require_once 'Zend/Amf/Exception.php'; 0137 throw new Zend_Amf_Exception('Unsupported marker type: ' . $typeMarker); 0138 } 0139 } 0140 0141 /** 0142 * Read AMF objects and convert to PHP objects 0143 * 0144 * Read the name value pair objects form the php message and convert them to 0145 * a php object class. 0146 * 0147 * Called when the marker type is 3. 0148 * 0149 * @param array|null $object 0150 * @return object 0151 */ 0152 public function readObject($object = null) 0153 { 0154 if ($object === null) { 0155 $object = array(); 0156 } 0157 0158 while (true) { 0159 $key = $this->_stream->readUTF(); 0160 $typeMarker = $this->_stream->readByte(); 0161 if ($typeMarker != Zend_Amf_Constants::AMF0_OBJECTTERM ){ 0162 //Recursivly call readTypeMarker to get the types of properties in the object 0163 $object[$key] = $this->readTypeMarker($typeMarker); 0164 } else { 0165 //encountered AMF object terminator 0166 break; 0167 } 0168 } 0169 $this->_reference[] = $object; 0170 return (object) $object; 0171 } 0172 0173 /** 0174 * Read reference objects 0175 * 0176 * Used to gain access to the private array of reference objects. 0177 * Called when marker type is 7. 0178 * 0179 * @return object 0180 * @throws Zend_Amf_Exception for invalid reference keys 0181 */ 0182 public function readReference() 0183 { 0184 $key = $this->_stream->readInt(); 0185 if (!array_key_exists($key, $this->_reference)) { 0186 // require_once 'Zend/Amf/Exception.php'; 0187 throw new Zend_Amf_Exception('Invalid reference key: '. $key); 0188 } 0189 return $this->_reference[$key]; 0190 } 0191 0192 /** 0193 * Reads an array with numeric and string indexes. 0194 * 0195 * Called when marker type is 8 0196 * 0197 * @todo As of Flash Player 9 there is not support for mixed typed arrays 0198 * so we handle this as an object. With the introduction of vectors 0199 * in Flash Player 10 this may need to be reconsidered. 0200 * @return array 0201 */ 0202 public function readMixedArray() 0203 { 0204 $length = $this->_stream->readLong(); 0205 return $this->readObject(); 0206 } 0207 0208 /** 0209 * Converts numerically indexed actiosncript arrays into php arrays. 0210 * 0211 * Called when marker type is 10 0212 * 0213 * @return array 0214 */ 0215 public function readArray() 0216 { 0217 $length = $this->_stream->readLong(); 0218 $array = array(); 0219 while ($length--) { 0220 $array[] = $this->readTypeMarker(); 0221 } 0222 return $array; 0223 } 0224 0225 /** 0226 * Convert AS Date to Zend_Date 0227 * 0228 * @return Zend_Date 0229 */ 0230 public function readDate() 0231 { 0232 // get the unix time stamp. Not sure why ActionScript does not use 0233 // milliseconds 0234 $timestamp = floor($this->_stream->readDouble() / 1000); 0235 0236 // The timezone offset is never returned to the server; it is always 0, 0237 // so read and ignore. 0238 $offset = $this->_stream->readInt(); 0239 0240 // require_once 'Zend/Date.php'; 0241 $date = new Zend_Date($timestamp); 0242 return $date; 0243 } 0244 0245 /** 0246 * Convert XML to SimpleXml 0247 * If user wants DomDocument they can use dom_import_simplexml 0248 * 0249 * @return SimpleXml Object 0250 */ 0251 public function readXmlString() 0252 { 0253 $string = $this->_stream->readLongUTF(); 0254 return Zend_Xml_Security::scan($string); //simplexml_load_string($string); 0255 } 0256 0257 /** 0258 * Read Class that is to be mapped to a server class. 0259 * 0260 * Commonly used for Value Objects on the server 0261 * 0262 * @todo implement Typed Class mapping 0263 * @return object|array 0264 * @throws Zend_Amf_Exception if unable to load type 0265 */ 0266 public function readTypedObject() 0267 { 0268 // require_once 'Zend/Amf/Parse/TypeLoader.php'; 0269 // get the remote class name 0270 $className = $this->_stream->readUTF(); 0271 $loader = Zend_Amf_Parse_TypeLoader::loadType($className); 0272 $returnObject = new $loader(); 0273 $properties = get_object_vars($this->readObject()); 0274 foreach($properties as $key=>$value) { 0275 if($key) { 0276 $returnObject->$key = $value; 0277 } 0278 } 0279 if($returnObject instanceof Zend_Amf_Value_Messaging_ArrayCollection) { 0280 $returnObject = get_object_vars($returnObject); 0281 } 0282 return $returnObject; 0283 } 0284 0285 /** 0286 * AMF3 data type encountered load AMF3 Deserializer to handle 0287 * type markers. 0288 * 0289 * @return string 0290 */ 0291 public function readAmf3TypeMarker() 0292 { 0293 // require_once 'Zend/Amf/Parse/Amf3/Deserializer.php'; 0294 $deserializer = new Zend_Amf_Parse_Amf3_Deserializer($this->_stream); 0295 $this->_objectEncoding = Zend_Amf_Constants::AMF3_OBJECT_ENCODING; 0296 return $deserializer->readTypeMarker(); 0297 } 0298 0299 /** 0300 * Return the object encoding to check if an AMF3 object 0301 * is going to be return. 0302 * 0303 * @return int 0304 */ 0305 public function getObjectEncoding() 0306 { 0307 return $this->_objectEncoding; 0308 } 0309 }