⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amfserializer.php

📁 实现flash的饼图投票
💻 PHP
字号:
<?php/** * AMFSerializer manages the job of translating PHP objects into * the actionscript equivalent via amf.  The main method of the serializer * is the serialize method which takes and AMFObject as it's argument * and builds the resulting amf body. */class AMFSerializer{	var $data; // holder for the data	var $out; // holder for the output stream	var $amfout;		/**	 *AMFSerializer is the constructor function.  You must pass the	 * method an AMFOutputStream as the single argument.	 *	 * @param $stream The AMFOutputStream	 */	function AMFSerializer(&$stream)	{			$this->out = &$stream; // save	}		/**	 *	serialize is the run method of the class.  When serialize is called	 * the AMFObject passed in is read and converted into the amf binary	 * representing the PHP data represented.	 *	 * @param $d the AMFObject to serialize	 */	function serialize($d)	{		$this->amfout = $d;		$this->out->writeInt(0); // write the version ???				$count = $this->amfout->numHeader(); // get the header count		$this->out->writeInt($count); // write header count		for ($i=0; $i<$count; $i++) {			$this->writeHeader($i);		}				$count = $this->amfout->numBody();		$this->out->writeInt($count); // write the body count		for ($i=0; $i<$count; $i++) {			$this->writeBody($i); // start writing the body		}	}		/**	 * writeHeader will write all of the header information	 * that the Flash client can react to.  This method is currently	 * unimplemented and is only really used for the NetConnection Debugger	 * and pageable record sets. 	 */	function writeHeader($i)	{		// for all header values		// write the header to the output stream		// ignoring header for now	}	/**	 *	writeBody converts the body part of the AMFObject into the amf binary	 *	 * @param $i The numeric index of the body object within the AMFObject	 */	function writeBody($i)	{		$body = $this->amfout->getBodyAt($i);		$this->out->writeUTF($body["target"]); // write the responseURI header		$this->out->writeUTF($body["response"]); // write null, haven't found another use for this		$this->out->writeLong(-1); // always, always there is four bytes of FF, which is -1 of course		$this->writeData($body["value"], $body["type"]); // write the data to the output stream	}		/**	 *	writeBoolean writes the boolean code (0x01) and the data to the output stream	 *	 * @param $d The boolean value	 */	function writeBoolean($d)	{		$this->out->writeByte(1); // write the boolean flag		$this->out->writeByte($d); // write the boolean byte	}		/**	 *	writeString writes the string code (0x02) and the UTF8 encoded	 * string to the output stream.	 * 支持中文,需修改以下两个函数	 * @param $d The string data	 */	function writeString($d)	{		$this->out->writeByte(2); // write the string code		$this->out->writeUTF($d);		//$this->out->writeUTF(mb_convert_encoding($d,"UTF-8","EUC-CN")); //支持中文		//$this->out->writeUTF(iconv("EUC-CN","UTF-8",$d));		//$this->out->writeUTF(utf8_encode($d)); // write the string value	}		/**	 *	writeXML writes the xml code (0x0F) and the XML string to the output stream	 *	 * @param $d The XML string	 */	function writeXML($d)	{		$this->out->writeByte(15);	    $this->out->writeLongUTF($d);	//$this->out->writeLongUTF(mb_convert_encoding($d,"UTF-8","EUC-CN"));//支持中文的		//$this->out->writeLongUTF(iconv("EUC-CN","UTF-8",$d));		//$this->out->writeLongUTF(utf8_encode($d));//原来只支持英文的	}		/**	 *	writeData writes the date code (0x0B) and the date value to the output stream	 *	 * @param $d The date value	 */	function writeDate($d)	{		$this->out->writeByte(11); // write date code		$this->out->writeDouble($d); // write date (milliseconds from 1970)		/****************************************************************		write timezone		?? this is wierd -- put what you like and it pumps it back into flash at the current GMT ?? 		have a look at the amf it creates...		****************************************************************/		$this->out->writeInt(0); 	}		/**	 * writeNumber writes the number code (0x00) and the numeric data to the output stream	 * All numbers passed through remoting are floats.	 *	 * @param $d The numeric data	 */	function writeNumber($d)	{		$this->out->writeByte(0); // write the number code		$this->out->writeDouble($d); // write the number as a double	}		/**	 * writeNull writes the null code (0x05) to the output stream	 */	function writeNull()	{		$this->out->writeByte(5); // null is only a 0x05 flag	}	/**	 * writeArray first deterines if the PHP array contains all numeric indexes	 * or a mix of keys.  Then it either writes the array code (0x0A) or the	 * object code (0x03) and then the associated data.	 *	 * @param $d The php array	 */	function writeArray($d)	{		if (is_array($d)) { // make damn certain the input is an array			$numeric = array(); // holder to store the numeric keys			$string = array(); // holder to store the string keys			$len = count($d); // get the total number of entries for the array			foreach($d as $key => $data) { // loop over each element					if(is_int($key) && ($key >= 0)) { // make sure the keys are numeric					$numeric[$key] = $data; // The key is an index in an array				} else {					$string[$key] = $data; // The key is a property of an object				}			}			$num_count = count($numeric); // get the number of numeric keys			$str_count = count($string); // get the number of string keys						if ($num_count > 0) { // if there are numeric keys				$this->array_empty_fill($numeric); // null fill the empty slots to preseve sparsity				$num_count = count($numeric); // get the new count			}						if ($num_count > 0 && $str_count > 0) { // this is a mixed array				$this->out->writeByte(8); // write the mixed array code				$this->out->writeLong($num_count); // write the count of items in the array				$this->writeObject($numeric + $string); // write the numeric and string keys in the mixed array			} else if ($num_count > 0) { // this is just an array				$this->out->writeByte(10); // write the mixed array code				$this->out->writeLong($num_count); // write the count of items in the array				for($i=0 ; $i < $num_count ; $i++) { // write all of the array elements					$this->writeData($numeric[$i]);				}			} else { // this is an object				$this->out->writeByte(3); // this is an object so write the object code				$this->writeObject($string); // write the object name/value pairs			}		}	}	/**	 *	array_empty_fill fills in all of the empty numeric slots with null to preserve the	 * indexes of a sparse array.	 */	function array_empty_fill(&$array, $fill = NULL)	{ 		$indexmax = -1;		for (end($array); $key = key($array); prev($array)) { // loop over the array			if (is_int($key)) { // if the key is an integer				if ($key > $indexmax) { // is this key greater than the previous max					$indexmax = $key; // save this key as the high				}			}		} 		for ($i = 0; $i <= $indexmax; $i++) { // loop over all possible indexes from 0 to max			if (!isset($array[$i])) { // is it set already				$array[$i] = $fill; // fill it with the $fill value			}		} 		ksort($array); // resort the keys		reset($array); // reset the pointer to the beginning	}		/**	 *	writeObject handles writing a php array with string or mixed keys.  It does	 * not write the object code as that is handled by the writeArray and this method	 * is shared with the CustomClass writer which doesn't use the object code.	 *	 * @param $d The php array with string keys	 */	function writeObject($d)	{		foreach($d as $key => $data) { // loop over each element				$this->out->writeUTF($key); // write the name of the object			$this->writeData($data); // write the value of the object		}		$this->out->writeInt(0); // write the end object flag 0x00, 0x00, 0x09		$this->out->writeByte(9);	}		/**	 *	writePHPObject takes an instance of a class and writes the variables defined	 * in it to the output stream.	 * To accomplish this we just blanket grab all of the object vars with get_object_vars	 *	 * @param object The object to serialize the properties	 */	 function writePHPObject($d)	 {	 	$this->writeCustomClass(get_class($d), get_object_vars($d));	 }		/**	 * writeRecordSet is the abstracted method to write a custom class recordset object.	 * Any recordset from any datasource can be written here, it just needs to be properly formatted	 * beforehand.	 *	 * @param $rs The formatted RecordSet object	 */	function writeRecordSet($rs)	{			$RecordSet = array(); // create the RecordSet object		$RecordSet["serverInfo"] = array(); // create the serverInfo array		$RecordSet["serverInfo"]["id"] = "PHPRemoting"; // create the id field --> i think this is used for pageable recordsets		$RecordSet["serverInfo"]["totalCount"] = $rs->numRows; // get the total number of records		$RecordSet["serverInfo"]["initialData"] = $rs->initialData; // save the initial data into the RecordSet object		$RecordSet["serverInfo"]["cursor"] = 1; // maybe the current record ????		$RecordSet["serverInfo"]["serviceName"] = "doStuff"; // in CF this is PageAbleResult not here		$RecordSet["serverInfo"]["columnNames"] = $rs->columnNames;		$RecordSet["serverInfo"]["version"] = 1; // versioning		$this->writeCustomClass("RecordSet", $RecordSet);		}		/**	 * writeCustomClass promotes the writing of the class name and data for CustomClasses	 *	 * @param string The class name	 * @param object The class instance object	 */	function writeCustomClass ($name, $d)	{		$this->out->writeByte(16); // write the custom class code		$this->out->writeUTF($name); // write the class name		$this->writeObject($d); // write the classes data	}		/**	 *	throwWrongDataTypeError sends the message back to the user that the 	 * manual data type passed doesn't match the actual data type returned by	 * the service method.	 *	 * @param $dt The data type that was expected but not encountered	 */	function throwWrongDataTypeError($dt)	{		trigger_error("The returned data was not of the type " . $dt);	}	/**	 *	autoNegotiateType tries to determine the data type of the passed data with	 * php's recommended is_ class of methods.	 *	 * @param $d the data to negotiate	 */	function autoNegotiateType($d)	{		if (is_bool($d)) { // boolean			$this->writeBoolean($d);			return true;		} else if (is_string($d)) { // string			$this->writeString($d);			return true;			} else if (is_double($d)) { // double			$this->writeNumber($d);			return true;		} else if (is_int($d)) { // int			$this->writeNumber($d);			return true;		} else if (is_object($d)) { // object			$this->writePHPObject($d);			return true;		} else if (is_array($d)) { // array			$this->writeArray($d);			return true;		} else if (is_null($d)) { // null			$this->writeNull();			return true;		} else if (is_resource($d)) { // resource			$this->writeData($d, get_resource_type($d));			return true;		}		return false;			}		/**	 * manualType allows the developer to explicitly set the type of	 * the returned data.  The returned data is validated for most of the	 * cases when possible.  Some datatypes like xml and date have to	 * be returned this way in order for the Flash client to correctly serialize them	 *	 * mysql result appears top on the list because that will probably be the most	 * common hit in this method.  Then the other datasource types, followed by the	 * datatypes that have to be manually set.  Then the auto negotiatable types last.	 * The order may be changed for optimization.	 *	 * @param $d The data	 * @param $type The type of $d	 */	function manualType($d, $type)	{		$type = strtolower($type);		$dbtype = $type; // save this here incase we need it in a few lines		$result = strpos($type , " result"); // first check to see if this is a recordset do this here for efficiency		if ($result !== FALSE) {			$type = "__RECORDSET__";		}		switch ($type) {			case "__RECORDSET__" :				$resultType = substr($dbtype, 0, $result);				$classname = $resultType . "RecordSet"; // full class name				$includeFile = @include_once(AMFPHP_BASE . "sql/" . $classname . ".php"); // try to load the recordset library from the sql folder				if(!$includeFile) {					if (!@include_once($classname . ".php")) {// try from the same folder as the service						trigger_error("The recordset filter class " . $classname . " was not found");					}				}				$recordSet = new $classname($d); // returns formatted recordset				$this->writeRecordSet($recordSet); // writes the recordset formatted for Flash				break;					case "xml" :				if (is_string($d)) {					$this->writeXML($d);				} else {					$this->throwWrongDataTypeError("xml");				}				break;			case "date" :				if (is_float($d)) {					$this->writeDate($d);				} else {					$this->throwWrongDataTypeError("date");				}				break;			case "boolean" :				if (is_bool($d)) {					$this->writeBoolean($d);				} else {					$this->throwWrongDataTypeError("boolean");				}				break;			case "string" :				if (is_string($d)) {					$this->writeString($d);				} else {					$this->throwWrongDataTypeError("string");				}				break;			case "double" :				if (is_double($d)) {					$this->writeNumber($d);				} else {					$this->throwWrongDataTypeError("double");				}				break;			case "integer" :				if (is_int($d)) {					$this->writeNumber($d);				} else {					$this->throwWrongDataTypeError("integer");				}				break;			case "object" :				if (is_object($d)) {					$this->writePHPObject($d);				} else {					$this->throwWrongDataTypeError("object");				}				break;			case "array" :				if (is_array($d)) {					$this->writeArray($d);				} else {					$this->throwWrongDataTypeError("array");				}				break;			case "null" :				if (is_null($d)) {					$this->writeNull();				} else {					$this->throwWrongDataError("null");				}				break;			case "resource" :				if (is_resource($d)) {					$this->writeData($d, get_resource_type($d));				} else {					$this->throwWrongDataTypeError("resource");				}				break;			default:				// non of the above so lets assume its a Custom Class thats defined in the client				$this->writeCustomClass($type, $d);				//trigger_error("Unsupported Datatype");				break;						}	}		/**	 *	writeData checks to see if the type was declared and then either	 * auto negotiates the type or relies on the user defined type to 	 * serialize the data into amf	 *	 * @param $d The data	 * @param $type The optional type	 */    function writeData($d, $type=-1)	{		if ($type==-1) {			if ($this->autoNegotiateType($d)) {				return; // we successfully found the type so quit			} else {				$type = gettype($d); // if the auto negotiate failed, try the old way			}		}		$this->manualType($d, $type); // try the manual route if we didn't return already	}}?>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -