📄 xmlrpc.php
字号:
<?php/* * btg Copyright (C) 2005 Michael Wojciechowski. * PHP client written by Johan Str枚m. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * This library is, although with heavy modifications, based on: * * IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002 Version 1.61 - * Simon Willison, 11th July 2003 (htmlentities -> htmlspecialchars) * Site: http://scripts.incutio.com/xmlrpc/ * Manual: http://scripts.incutio.com/xmlrpc/manual.php * Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php *//* * $Id: xmlrpc.php,v 1.1.4.17 2007/09/17 15:34:51 wojci Exp $ *//** * Represents a XMLRPC Value. */class XMLRPC_Value{ private $data; private $type; function XMLRPC_Value($data, $type = false) { $this->data = $data; if(!$type) { $type = $this->calculateType(); } $this->type = $type; if($type == 'struct') { /* * Turn all the values in the array in to new * XMLRPC_Value objects */ foreach($this->data as $key => $value) { $this->data[$key] = new XMLRPC_Value($value); } } else if($type == 'array') { for ($i = 0, $j = count($this->data); $i < $j; $i++) { $this->data[$i] = new XMLRPC_Value($this->data[$i]); } } } /** * Try to figure out what type our data has. */ function calculateType() { if($this->data === true || $this->data === false) { return 'boolean'; } if(is_integer($this->data)) { return 'int'; } if(is_double($this->data)) { return 'double'; } // Deal with XMLRPC object types base64 and date if(is_object($this->data) && ($this->data instanceof XMLRPC_Date)) { return 'date'; } if(is_object($this->data) && ($this->data instanceof XMLRPC_Base64)) { return 'base64'; } // If it is a normal PHP object convert it in to a struct if(is_object($this->data)) { $this->data = get_object_vars($this->data); return 'struct'; } if(!is_array($this->data)) { return 'string'; } /* We have an array - is it an array or a struct ? */ if($this->isStruct($this->data)) { return 'struct'; } else { return 'array'; } } /** * Wrap our value in appropriate XML field. */ function getXml() { /* Return XML for this value */ switch ($this->type) { case 'boolean': return '<boolean>'.(($this->data) ? '1' : '0').'</boolean>'; break; case 'int': return '<int>'.$this->data.'</int>'; break; case 'double': return '<double>'.$this->data.'</double>'; break; case 'string': return '<string>'.htmlspecialchars($this->data).'</string>'; break; case 'array': $return = '<array><data>'."\n"; foreach($this->data as $item) { $return.= ' <value>'.$item->getXml()."</value>\n"; } $return.= '</data></array>'; return $return; break; case 'struct': $return = '<struct>'."\n"; foreach($this->data as $name => $value) { $return.= " <member><name>$name</name><value>"; $return.= $value->getXml()."</value></member>\n"; } $return.= '</struct>'; return $return; break; case 'date': case 'base64': // Both date and base64 are special objects. return $this->data->getXml(); break; } return false; } /** * Nasty function to check if the value is a struct or not. */ function isStruct($array) { $expected = 0; foreach($array as $key => $value) { if((string) $key != (string) $expected) { return true; } $expected++; } return false; }}/** * A received XMLRPC message. Handles decoding of the XML. */class XMLRPC_Message{ private $xml; // The raw data (XML) public $messageType; // methodCall / methodResponse / fault public $parseError; // the specific parse error if one occurred public $faultCode; // fault code if a fault occured public $faultString; // fault message public $methodName; // The name of the called method public $params; // Current variable stacks private $_arraystructs = array(); // The stack used to keep track of the current array / struct private $_arraystructstypes = array(); // Stack keeping track of if things are structs or array private $_currentStructName = array(); // A stack as well private $_param; private $_value; private $_currentTag; private $_currentTagContents; private $_parser; //The XML parser function XMLRPC_Message($xml) { $this->xml = $xml; } /** * Parse our XML body. Will sett $params */ function parse() { //first remove the XML declaration $this->xml = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->xml); if(trim($this->xml) == '') { return false; } $this->_parser = xml_parser_create(); // Set XML parser to take the case of tags in to account xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); // Set XML parser callback function s xml_set_object($this->_parser, $this); xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); xml_set_character_data_handler($this->_parser, 'cdata'); if(!xml_parse($this->_parser, $this->xml)) { $this->parseError = sprintf('XML error: %s at line %d', xml_error_string(xml_get_error_code($this->_parser)), xml_get_current_line_number($this->_parser) ); return false; } xml_parser_free($this->_parser); // Grab the error messages, if any if($this->messageType == 'fault') { $this->faultCode = $this->params[0]['faultCode']; $this->faultString = $this->params[0]['faultString']; } return true; } function tag_open($parser, $tag, $attr) { $this->currentTag = $tag; switch ($tag) { case 'methodCall': case 'methodResponse': case 'fault': $this->messageType = $tag; break; /* Deal with stacks of arrays and structs */ case 'data'://data is to all intents and puposes more interesting than array $this->_arraystructstypes[] = 'array'; $this->_arraystructs[] = array(); break; case 'struct': $this->_arraystructstypes[] = 'struct'; $this->_arraystructs[] = array(); break; } } function cdata($parser, $cdata) { $this->_currentTagContents.= $cdata; } function tag_close($parser, $tag) { $valueFlag = false; switch ($tag) { case 'int': case 'i4': $value = (int) trim($this->_currentTagContents); $this->_currentTagContents = ''; $valueFlag = true; break; case 'double': $value = (double) trim($this->_currentTagContents); $this->_currentTagContents = ''; $valueFlag = true; break; case 'string': $value = (string) trim($this->_currentTagContents); $this->_currentTagContents = ''; $valueFlag = true; break; case 'dateTime.iso8601': $value = new XMLRPC_Date(trim($this->_currentTagContents)); //$value = $iso->getTimestamp(); $this->_currentTagContents = ''; $valueFlag = true; break; case 'value': //"If no type is indicated, the type is string." if(trim($this->_currentTagContents) != '') { $value = (string) $this->_currentTagContents; $this->_currentTagContents = ''; $valueFlag = true; } break; case 'boolean': $value = (boolean) trim($this->_currentTagContents); $this->_currentTagContents = ''; $valueFlag = true; break; case 'base64': $value = base64_decode($this->_currentTagContents); $this->_currentTagContents = ''; $valueFlag = true; break; /* Deal with stacks of arrays and structs */ case 'data': case 'struct': $value = array_pop($this->_arraystructs); array_pop($this->_arraystructstypes); $valueFlag = true; break; case 'member': array_pop($this->_currentStructName); break; case 'name': $this->_currentStructName[] = trim($this->_currentTagContents); $this->_currentTagContents = ''; break; case 'methodName': $this->methodName = trim($this->_currentTagContents); $this->_currentTagContents = ''; break; } if($valueFlag) { /* if(!is_array($value) && !is_object($value)) { $value = trim($value); } */ if(count($this->_arraystructs) > 0) { //Add value to struct or array if($this->_arraystructstypes[count($this->_arraystructstypes) - 1] == 'struct') { //Add to struct $this->_arraystructs[count($this->_arraystructs) - 1][$this->_currentStructName[count($this->_currentStructName) - 1]] = $value; } else { //Add to array $this->_arraystructs[count($this->_arraystructs) - 1][] = $value; } } else { //Just add as a paramater $this->params[] = $value; } } }}/** * A XMLRPC Request object. This is used when a request is sent to a server. */class XMLRPC_Request{ private $method; private $args; private $xml; function XMLRPC_Request($method, $args) { $this->method = $method; $this->args = $args; $this->xml = <<<EOD<?xml version="1.0" ?><methodCall><methodName>{$this->method}</methodName><params>EOD; foreach($this->args as $arg) { $this->xml.= '<param><value>'; $v = new XMLRPC_Value($arg); $this->xml.= $v->getXml(); $this->xml.= "</value></param>\n"; } $this->xml.= '</params></methodCall>'; } function getLength() { return strlen($this->xml); } function getXml() { return $this->xml; }}/** * The client used to perform requests. */class XMLRPC_Client{ private $gzip_available = false; private $use_gzip = false; private $method = "http"; private $ssl_ca_cert = null; private $ssl_client_cert = null; private $server; private $port = 80; private $path = "/"; private $timeout; private $context = null; private $useragent= ""; private $response = ""; private $message = false; private $debug = false; private $error = false; //Storage place for an error message private $fp = null; private $rxbuff = ""; function XMLRPC_Client($server, $path = false, $port = 80, $timeout=20) { if(!$path) { // Assume we have been given a URL instead
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -