/** * Serialize PHP types to AMF3 and write to stream * * Checks to see if the type was declared and then either * auto negotiates the type or use the user defined markerType to * serialize the data from php back to AMF3 * * @param mixed $data * @param int $markerType * @param mixed $extraData The additional data. * In the case $data is NULL, this will param be used as 'byval' value for $data. * In the case $markerType is a AS3 Vector type (AMF3_VECTOR_INT, AMF3_VECTOR_UINT, AMF3_VECTOR_NUMBER or AMF3_VECTOR_OBJECT), * the $extraData will contain AS3 reflection information for writing AS3 Vector. * @throws AmfException */ public function writeTypeMarker(&$data, $markerType = null, $extraData = false) { // Workaround for PHP5 with E_STRICT enabled complaining about "Only // variables should be passed by reference" if (null === $data && $extraData !== false) { $data =& $dataByVal; } if (null !== $markerType) { // Write the Type Marker to denote the following action script data type $this->_stream->writeByte($markerType); switch ($markerType) { case Constants::AMF3_NULL: break; case Constants::AMF3_BOOLEAN_FALSE: break; case Constants::AMF3_BOOLEAN_TRUE: break; case Constants::AMF3_INTEGER: $this->writeInteger($data); break; case Constants::AMF3_NUMBER: $this->_stream->writeDouble($data); break; case Constants::AMF3_STRING: $this->writeString($data); break; case Constants::AMF3_DATE: $this->writeDate($data); break; case Constants::AMF3_ARRAY: $this->writeArray($data); break; case Constants::AMF3_OBJECT: $this->writeObject($data); break; case Constants::AMF3_BYTEARRAY: $this->writeByteArray($data); break; case Constants::AMF3_XMLSTRING: $this->writeXml($data); break; case Constants::AMF3_VECTOR_INT: case Constants::AMF3_VECTOR_UINT: case Constants::AMF3_VECTOR_NUMBER: case Constants::AMF3_VECTOR_OBJECT: return $this->writeVector($data, $markerType, $extraData); //case Constants::AMF3_DICTIONARY: //case Constants::AMF3_DICTIONARY: default: throw new AmfException('Unknown Type Marker: ' . $markerType); } } else { // Detect Type Marker if (is_resource($data)) { $data = TypeLoader::handleResource($data); } switch (true) { case null === $data: $markerType = Constants::AMF3_NULL; break; case is_bool($data): if ($data) { $markerType = Constants::AMF3_BOOLEAN_TRUE; } else { $markerType = Constants::AMF3_BOOLEAN_FALSE; } break; case is_int($data): if ($data > 0xfffffff || $data < -268435456) { $markerType = Constants::AMF3_NUMBER; } else { $markerType = Constants::AMF3_INTEGER; } break; case is_float($data): $markerType = Constants::AMF3_NUMBER; break; case is_string($data): $markerType = Constants::AMF3_STRING; break; case is_array($data): $markerType = Constants::AMF3_ARRAY; break; case is_object($data): // Handle object types. if ($data instanceof DateTime) { $markerType = Constants::AMF3_DATE; } else { if ($data instanceof ByteArray) { $markerType = Constants::AMF3_BYTEARRAY; } else { if ($data instanceof DOMDocument || $data instanceof SimpleXMLElement) { $markerType = Constants::AMF3_XMLSTRING; } else { $markerType = Constants::AMF3_OBJECT; } } } break; default: throw new AmfException('Unsupported data type: ' . gettype($data)); } $this->writeTypeMarker($data, $markerType); } return 0; //To avoid PHP warning }
/** * Determine type and serialize accordingly * * Checks to see if the type was declared and then either * auto negotiates the type or relies on the user defined markerType to * serialize the data into amf * * @param mixed $data * @param mixed $markerType * @param mixed $dataByVal * @return Amf0Serializer * @throws AmfException for unrecognized types or data */ public function writeTypeMarker(&$data, $markerType = null, $dataByVal = false) { // Workaround for PHP5 with E_STRICT enabled complaining about "Only // variables should be passed by reference" if (null === $data && $dataByVal !== false) { $data =& $dataByVal; } if (null !== $markerType) { //try to reference the given object if (!$this->writeObjectReference($data, $markerType)) { // Write the Type Marker to denote the following action script data type $this->_stream->writeByte($markerType); switch ($markerType) { case Constants::AMF0_NUMBER: $this->_stream->writeDouble($data); break; case Constants::AMF0_BOOLEAN: $this->_stream->writeByte($data); break; case Constants::AMF0_STRING: $this->_stream->writeUTF($data); break; case Constants::AMF0_OBJECT: $this->writeObject($data); break; case Constants::AMF0_NULL: break; case Constants::AMF0_REFERENCE: $this->_stream->writeInt($data); break; case Constants::AMF0_MIXEDARRAY: // Write length of numeric keys as zero. $this->_stream->writeLong(0); $this->writeObject($data); break; case Constants::AMF0_ARRAY: $this->writeArray($data); break; case Constants::AMF0_DATE: $this->writeDate($data); break; case Constants::AMF0_LONGSTRING: $this->_stream->writeLongUTF($data); break; case Constants::AMF0_TYPEDOBJECT: $this->writeTypedObject($data); break; case Constants::AMF0_AMF3: $this->writeAmf3TypeMarker($data); break; default: throw new AmfException("Unknown Type Marker: " . $markerType); } } } else { if (is_resource($data)) { $data = TypeLoader::handleResource($data); } switch (true) { case is_int($data) || is_float($data): $markerType = Constants::AMF0_NUMBER; break; case is_bool($data): $markerType = Constants::AMF0_BOOLEAN; break; case is_string($data) && ($this->_mbStringFunctionsOverloaded ? mb_strlen($data, '8bit') : strlen($data)) > 65536: $markerType = Constants::AMF0_LONGSTRING; break; case is_string($data): $markerType = Constants::AMF0_STRING; break; case is_object($data): //20140627 NguyenBS Remove Zend_Date if ($data instanceof DateTime) { $markerType = Constants::AMF0_DATE; } else { if ($className = $this->getClassName($data)) { //Object is a Typed object set classname $markerType = Constants::AMF0_TYPEDOBJECT; $this->_className = $className; } else { // Object is a generic classname $markerType = Constants::AMF0_OBJECT; } break; } break; case null === $data: $markerType = Constants::AMF0_NULL; break; case is_array($data): // check if it is an associative array $i = 0; foreach (array_keys($data) as $key) { // check if it contains non-integer keys if (!is_numeric($key) || intval($key) != $key) { $markerType = Constants::AMF0_OBJECT; break; // check if it is a sparse indexed array } else { if ($key != $i) { $markerType = Constants::AMF0_MIXEDARRAY; break; } } $i++; } // Dealing with a standard numeric array if (!$markerType) { $markerType = Constants::AMF0_ARRAY; break; } break; default: throw new AmfException('Unsupported data type: ' . gettype($data)); } $this->writeTypeMarker($data, $markerType); } return $this; }