diff -ru Amf-1.9.6/Parse/Amf0/Serializer.php Amf/Parse/Amf0/Serializer.php --- Amf-1.9.6/Parse/Amf0/Serializer.php 2009-11-12 10:26:19.000000000 -0600 +++ Amf/Parse/Amf0/Serializer.php 2010-01-06 18:48:36.000000000 -0600 @@ -52,63 +52,19 @@ * auto negotiates the type or relies on the user defined markerType to * serialize the data into amf * - * @param misc $data - * @param misc $markerType + * @param mixed $data + * @param mixed $markerType + * @param mixed $dataByVal * @return Zend_Amf_Parse_Amf0_Serializer * @throws Zend_Amf_Exception for unrecognized types or data */ - public function writeTypeMarker($data, $markerType = null) + public function writeTypeMarker(&$data, $markerType=null, $dataByVal=false) { - if (null !== $markerType) { - //try to refrence 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 Zend_Amf_Constants::AMF0_NUMBER: - $this->_stream->writeDouble($data); - break; - case Zend_Amf_Constants::AMF0_BOOLEAN: - $this->_stream->writeByte($data); - break; - case Zend_Amf_Constants::AMF0_STRING: - $this->_stream->writeUTF($data); - break; - case Zend_Amf_Constants::AMF0_OBJECT: - $this->writeObject($data); - break; - case Zend_Amf_Constants::AMF0_NULL: - break; - case Zend_Amf_Constants::AMF0_REFERENCE: - $this->_stream->writeInt($data); - break; - case Zend_Amf_Constants::AMF0_MIXEDARRAY: - // Write length of numeric keys as zero. - $this->_stream->writeLong(0); - $this->writeObject($data); - break; - case Zend_Amf_Constants::AMF0_ARRAY: - $this->writeArray($data); - break; - case Zend_Amf_Constants::AMF0_DATE: - $this->writeDate($data); - break; - case Zend_Amf_Constants::AMF0_LONGSTRING: - $this->_stream->writeLongUTF($data); - break; - case Zend_Amf_Constants::AMF0_TYPEDOBJECT: - $this->writeTypedObject($data); - break; - case Zend_Amf_Constants::AMF0_AMF3: - $this->writeAmf3TypeMarker($data); - break; - default: - require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception("Unknown Type Marker: " . $markerType); - } - } - } else { + // Workaround for PHP5 with E_STRICT enabled complaining about "Only variables should be passed by reference" + if (is_null($data) && ($dataByVal !== false)) { + $data = &$dataByVal; + } + if (null === $markerType) { if(is_resource($data)) { $data = Zend_Amf_Parse_TypeLoader::handleResource($data); } @@ -168,9 +124,59 @@ default: require_once 'Zend/Amf/Exception.php'; throw new Zend_Amf_Exception('Unsupported data type: ' . gettype($data)); + return; } + } - $this->writeTypeMarker($data, $markerType); + //try to refrence the given object + $placeholder = null; + if( (($dataByVal === false) && !$this->writeObjectReference($data, $markerType)) || + (($data === $dataByVal) && !$this->writeObjectReference($placeholder, $markerType, $data)) ) { + + // Write the Type Marker to denote the following action script data type + $this->_stream->writeByte($markerType); + switch($markerType) { + case Zend_Amf_Constants::AMF0_NUMBER: + $this->_stream->writeDouble($data); + break; + case Zend_Amf_Constants::AMF0_BOOLEAN: + $this->_stream->writeByte($data); + break; + case Zend_Amf_Constants::AMF0_STRING: + $this->_stream->writeUTF($data); + break; + case Zend_Amf_Constants::AMF0_OBJECT: + $this->writeObject($data); + break; + case Zend_Amf_Constants::AMF0_NULL: + break; + case Zend_Amf_Constants::AMF0_REFERENCE: + $this->_stream->writeInt($data); + break; + case Zend_Amf_Constants::AMF0_MIXEDARRAY: + // Write length of numeric keys as zero. + $this->_stream->writeLong(0); + $this->writeObject($data); + break; + case Zend_Amf_Constants::AMF0_ARRAY: + $this->writeArray($data); + break; + case Zend_Amf_Constants::AMF0_DATE: + $this->writeDate($data); + break; + case Zend_Amf_Constants::AMF0_LONGSTRING: + $this->_stream->writeLongUTF($data); + break; + case Zend_Amf_Constants::AMF0_TYPEDOBJECT: + $this->writeTypedObject($data); + break; + case Zend_Amf_Constants::AMF0_AMF3: + $this->writeAmf3TypeMarker($data); + break; + default: + require_once 'Zend/Amf/Exception.php'; + throw new Zend_Amf_Exception("Unknown Type Marker: " . $markerType); + } } return $this; } @@ -179,17 +185,23 @@ * Check if the given object is in the reference table, write the reference if it exists, * otherwise add the object to the reference table * - * @param mixed $object object to check for reference + * @param mixed $object object reference to check for reference * @param $markerType AMF type of the object to write + * @param mixed $objectByVal object to check for reference * @return Boolean true, if the reference was written, false otherwise */ - protected function writeObjectReference($object, $markerType){ + protected function writeObjectReference(&$object, $markerType, $objectByVal=false) { + // Workaround for PHP5 with E_STRICT enabled complaining about "Only variables should be passed by reference" + if (is_null($object) && ($objectByVal !== false)) { + $object = &$objectByVal; + } + if( $markerType == Zend_Amf_Constants::AMF0_OBJECT || $markerType == Zend_Amf_Constants::AMF0_MIXEDARRAY || $markerType == Zend_Amf_Constants::AMF0_ARRAY || $markerType == Zend_Amf_Constants::AMF0_TYPEDOBJECT ) { - $ref = array_search($object, $this->_referenceObjects,true); + $ref = array_search($object, $this->_referenceObjects, true); //handle object reference if($ref !== false){ $this->writeTypeMarker($ref,Zend_Amf_Constants::AMF0_REFERENCE); @@ -211,7 +223,7 @@ public function writeObject($object) { // Loop each element and write the name of the property. - foreach ($object as $key => $value) { + foreach ($object as $key => &$value) { // skip variables starting with an _ provate transient if( $key[0] == "_") continue; $this->_stream->writeUTF($key); @@ -231,7 +243,7 @@ * @param array $array * @return Zend_Amf_Parse_Amf0_Serializer */ - public function writeArray($array) + public function writeArray(&$array) { $length = count($array); if (!$length < 0) { @@ -295,7 +307,7 @@ * @param string $data * @return Zend_Amf_Parse_Amf0_Serializer */ - public function writeAmf3TypeMarker($data) + public function writeAmf3TypeMarker(&$data) { require_once 'Zend/Amf/Parse/Amf3/Serializer.php'; $serializer = new Zend_Amf_Parse_Amf3_Serializer($this->_stream); diff -ru Amf-1.9.6/Parse/Amf3/Serializer.php Amf/Parse/Amf3/Serializer.php --- Amf-1.9.6/Parse/Amf3/Serializer.php 2009-11-12 10:26:19.000000000 -0600 +++ Amf/Parse/Amf3/Serializer.php 2010-01-06 18:50:51.000000000 -0600 @@ -37,6 +37,12 @@ class Zend_Amf_Parse_Amf3_Serializer extends Zend_Amf_Parse_Serializer { /** + * A constant empty string + * @var string + */ + protected $_strEmpty = ''; + + /** * An array of reference objects per amf body * @var array */ @@ -61,58 +67,24 @@ * auto negotiates the type or use the user defined markerType to * serialize the data from php back to AMF3 * - * @param mixed $content + * @param mixed $data * @param int $markerType + * @param mixed $dataByVal * @return void */ - public function writeTypeMarker($data, $markerType=null) + public function writeTypeMarker(&$data, $markerType=null, $dataByVal=false) { - if (null !== $markerType) { - // Write the Type Marker to denote the following action script data type - $this->_stream->writeByte($markerType); - - switch ($markerType) { - case Zend_Amf_Constants::AMF3_NULL: - break; - case Zend_Amf_Constants::AMF3_BOOLEAN_FALSE: - break; - case Zend_Amf_Constants::AMF3_BOOLEAN_TRUE: - break; - case Zend_Amf_Constants::AMF3_INTEGER: - $this->writeInteger($data); - break; - case Zend_Amf_Constants::AMF3_NUMBER: - $this->_stream->writeDouble($data); - break; - case Zend_Amf_Constants::AMF3_STRING: - $this->writeString($data); - break; - case Zend_Amf_Constants::AMF3_DATE: - $this->writeDate($data); - break; - case Zend_Amf_Constants::AMF3_ARRAY: - $this->writeArray($data); - break; - case Zend_Amf_Constants::AMF3_OBJECT: - $this->writeObject($data); - break; - case Zend_Amf_Constants::AMF3_BYTEARRAY: - $this->writeByteArray($data); - break; - case Zend_Amf_Constants::AMF3_XMLSTRING; - $this->writeXml($data); - break; - default: - require_once 'Zend/Amf/Exception.php'; - throw new Zend_Amf_Exception('Unknown Type Marker: ' . $markerType); - } - } else { + // Workaround for PHP5 with E_STRICT enabled complaining about "Only variables should be passed by reference" + if (is_null($data) && ($dataByVal !== false)) { + $data = &$dataByVal; + } + if (null === $markerType) { // Detect Type Marker if(is_resource($data)) { $data = Zend_Amf_Parse_TypeLoader::handleResource($data); } - switch (true) { - case (null === $data): + switch (true) { + case (null === $data): $markerType = Zend_Amf_Constants::AMF3_NULL; break; case (is_bool($data)): @@ -153,8 +125,47 @@ default: require_once 'Zend/Amf/Exception.php'; throw new Zend_Amf_Exception('Unsupported data type: ' . gettype($data)); - } - $this->writeTypeMarker($data, $markerType); + return; + } + } + + // Write the Type Marker to denote the following action script data type + $this->_stream->writeByte($markerType); + + switch ($markerType) { + case Zend_Amf_Constants::AMF3_NULL: + break; + case Zend_Amf_Constants::AMF3_BOOLEAN_FALSE: + break; + case Zend_Amf_Constants::AMF3_BOOLEAN_TRUE: + break; + case Zend_Amf_Constants::AMF3_INTEGER: + $this->writeInteger($data); + break; + case Zend_Amf_Constants::AMF3_NUMBER: + $this->_stream->writeDouble($data); + break; + case Zend_Amf_Constants::AMF3_STRING: + $this->writeString($data); + break; + case Zend_Amf_Constants::AMF3_DATE: + $this->writeDate($data); + break; + case Zend_Amf_Constants::AMF3_ARRAY: + $this->writeArray($data); + break; + case Zend_Amf_Constants::AMF3_OBJECT: + $this->writeObject($data); + break; + case Zend_Amf_Constants::AMF3_BYTEARRAY: + $this->writeByteArray($data); + break; + case Zend_Amf_Constants::AMF3_XMLSTRING; + $this->writeXml($data); + break; + default: + require_once 'Zend/Amf/Exception.php'; + throw new Zend_Amf_Exception('Unknown Type Marker: ' . $markerType); } } @@ -198,7 +209,7 @@ * @param string $string * @return Zend_Amf_Parse_Amf3_Serializer */ - protected function writeBinaryString($string){ + protected function writeBinaryString(&$string){ $ref = strlen($string) << 1 | 0x01; $this->writeInteger($ref); $this->_stream->writeBytes($string); @@ -212,7 +223,7 @@ * @param string $string * @return Zend_Amf_Parse_Amf3_Serializer */ - public function writeString($string) + public function writeString(&$string) { $len = strlen($string); if(!$len){ @@ -238,7 +249,7 @@ * @param string|Zend_Amf_Value_ByteArray $data * @return Zend_Amf_Parse_Amf3_Serializer */ - public function writeByteArray($data){ + public function writeByteArray(&$data){ if($this->writeObjectReference($data)){ return $this; } @@ -318,16 +329,16 @@ * @param array $array * @return Zend_Amf_Parse_Amf3_Serializer */ - public function writeArray(array $array) + public function writeArray(&$array) { if($this->writeObjectReference($array)){ return $this; } - // have to seperate mixed from numberic keys. + // have to seperate mixed from numeric keys. $numeric = array(); $string = array(); - foreach ($array as $key => $value) { + foreach ($array as $key => &$value) { if (is_int($key)) { $numeric[] = $value; } else { @@ -341,14 +352,14 @@ $this->writeInteger($id); //Write the mixed type array to the output stream - foreach($string as $key => $value) { + foreach($string as $key => &$value) { $this->writeString($key) ->writeTypeMarker($value); } - $this->writeString(''); + $this->writeString($this->_strEmpty); // Write the numeric array to ouput stream - foreach($numeric as $value) { + foreach($numeric as &$value) { $this->writeTypeMarker($value); } return $this; @@ -358,10 +369,16 @@ * Check if the given object is in the reference table, write the reference if it exists, * otherwise add the object to the reference table * - * @param mixed $object object to check for reference + * @param mixed $object object reference to check for reference + * @param mixed $objectByVal object to check for reference * @return Boolean true, if the reference was written, false otherwise */ - protected function writeObjectReference($object){ + protected function writeObjectReference(&$object, $objectByVal=false) { + // Workaround for PHP5 with E_STRICT enabled complaining about "Only variables should be passed by reference" + if (is_null($object) && ($objectByVal !== false)) { + $object = &$objectByVal; + } + $ref = array_search($object, $this->_referenceObjects,true); //quickly handle object references if($ref !== false){ @@ -484,7 +501,7 @@ } //Write an empty string to end the dynamic part - $this->writeString(''); + $this->writeString($this->_strEmpty); break; case Zend_Amf_Constants::ET_EXTERNAL: require_once 'Zend/Amf/Exception.php'; diff -ru Amf-1.9.6/Parse/Serializer.php Amf/Parse/Serializer.php --- Amf-1.9.6/Parse/Serializer.php 2009-11-12 10:26:19.000000000 -0600 +++ Amf/Parse/Serializer.php 2010-01-06 18:54:39.000000000 -0600 @@ -53,7 +53,8 @@ * * @param mixed $content * @param int $markerType + * @param mixed $contentByVal * @return void */ - public abstract function writeTypeMarker($content, $markerType=null); + public abstract function writeTypeMarker(&$content, $markerType=null, $contentByVal=false); } diff -ru Amf-1.9.6/Response.php Amf/Response.php --- Amf-1.9.6/Response.php 2009-11-12 10:26:19.000000000 -0600 +++ Amf/Response.php 2010-01-06 18:54:13.000000000 -0600 @@ -94,7 +94,13 @@ $stream->writeUTF($header->name); $stream->writeByte($header->mustRead); $stream->writeLong(Zend_Amf_Constants::UNKNOWN_CONTENT_LENGTH); - $serializer->writeTypeMarker($header->data); + if (is_object($header->data)) { + // Workaround for PHP5 with E_STRICT enabled complaining about "Only variables should be passed by reference" + $placeholder = null; + $serializer->writeTypeMarker($placeholder, null, $header->data); + } else { + $serializer->writeTypeMarker($header->data); + } } // loop through the AMF bodies that need to be returned. @@ -105,11 +111,14 @@ $stream->writeUTF($body->getTargetURI()); $stream->writeUTF($body->getResponseURI()); $stream->writeLong(Zend_Amf_Constants::UNKNOWN_CONTENT_LENGTH); - if($this->_objectEncoding == Zend_Amf_Constants::AMF0_OBJECT_ENCODING) { - $serializer->writeTypeMarker($body->getData()); + $bodyData = $body->getData(); + $markerType = ($this->_objectEncoding == Zend_Amf_Constants::AMF0_OBJECT_ENCODING) ? null : Zend_Amf_Constants::AMF0_AMF3; + if (is_object($bodyData)) { + // Workaround for PHP5 with E_STRICT enabled complaining about "Only variables should be passed by reference" + $placeholder = null; + $serializer->writeTypeMarker($placeholder, $markerType, $bodyData); } else { - // Content is AMF3 - $serializer->writeTypeMarker($body->getData(),Zend_Amf_Constants::AMF0_AMF3); + $serializer->writeTypeMarker($bodyData, $markerType); } }