📄 rpc.php
字号:
<?php// by Edd Dumbill (C) 1999-2001// <edd@usefulinc.com>// $Id: RPC.php,v 1.1.1.1 2003/03/28 20:05:27 sterling Exp $// License is granted to use or modify this software ("XML-RPC for PHP")// for commercial or non-commercial use provided the copyright of the author// is preserved in any distributed or derivative work.// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// Adapted to PEAR standards by Stig S鎡her Bakken <stig@php.net> and// Martin Jansen <mj@php.net>require_once "bundled-libs/PEAR.php";if (!function_exists('xml_parser_create')) {// Win 32 fix. From: "Leo West" <lwest@imaginet.fr> if($WINDIR) { dl("php3_xml.dll"); } else { dl("xml.so"); }}$GLOBALS['XML_RPC_I4']="i4";$GLOBALS['XML_RPC_Int']="int";$GLOBALS['XML_RPC_Boolean']="boolean";$GLOBALS['XML_RPC_Double']="double";$GLOBALS['XML_RPC_String']="string";$GLOBALS['XML_RPC_DateTime']="dateTime.iso8601";$GLOBALS['XML_RPC_Base64']="base64";$GLOBALS['XML_RPC_Array']="array";$GLOBALS['XML_RPC_Struct']="struct";$GLOBALS['XML_RPC_Types']=array($GLOBALS['XML_RPC_I4'] => 1, $GLOBALS['XML_RPC_Int'] => 1, $GLOBALS['XML_RPC_Boolean'] => 1, $GLOBALS['XML_RPC_String'] => 1, $GLOBALS['XML_RPC_Double'] => 1, $GLOBALS['XML_RPC_DateTime'] => 1, $GLOBALS['XML_RPC_Base64'] => 1, $GLOBALS['XML_RPC_Array'] => 2, $GLOBALS['XML_RPC_Struct'] => 3);$GLOBALS['XML_RPC_entities']=array("quot" => '"', "amp" => "&", "lt" => "<", "gt" => ">", "apos" => "'");$GLOBALS['XML_RPC_err']["unknown_method"]=1;$GLOBALS['XML_RPC_str']["unknown_method"]="Unknown method";$GLOBALS['XML_RPC_err']["invalid_return"]=2;$GLOBALS['XML_RPC_str']["invalid_return"]="Invalid return payload: enabling debugging to examine incoming payload";$GLOBALS['XML_RPC_err']["incorrect_params"]=3;$GLOBALS['XML_RPC_str']["incorrect_params"]="Incorrect parameters passed to method";$GLOBALS['XML_RPC_err']["introspect_unknown"]=4;$GLOBALS['XML_RPC_str']["introspect_unknown"]="Can't introspect: method unknown";$GLOBALS['XML_RPC_err']["http_error"]=5;$GLOBALS['XML_RPC_str']["http_error"]="Didn't receive 200 OK from remote server.";$GLOBALS['XML_RPC_defencoding']="UTF-8";// let user errors start at 800$GLOBALS['XML_RPC_erruser']=800;// let XML parse errors start at 100$GLOBALS['XML_RPC_errxml']=100;// formulate backslashes for escaping regexp$GLOBALS['XML_RPC_backslash']=chr(92).chr(92);$GLOBALS['XML_RPC_twoslash']=$GLOBALS['XML_RPC_backslash'] . $GLOBALS['XML_RPC_backslash'];$GLOBALS['XML_RPC_twoslash']="2SLS";// used to store state during parsing// quick explanation of components:// st - used to build up a string for evaluation// ac - used to accumulate values// qt - used to decide if quotes are needed for evaluation// cm - used to denote struct or array (comma needed)// isf - used to indicate a fault// lv - used to indicate "looking for a value": implements// the logic to allow values with no types to be strings// params - used to store parameters in method calls// method - used to store method name$GLOBALS['XML_RPC_xh']=array();function XML_RPC_entity_decode($string){ $top=split("&", $string); $op=""; $i=0; while($i<sizeof($top)) { if (ereg("^([#a-zA-Z0-9]+);", $top[$i], $regs)) { $op.=ereg_replace("^[#a-zA-Z0-9]+;", XML_RPC_lookup_entity($regs[1]), $top[$i]); } else { if ($i==0) $op=$top[$i]; else $op.="&" . $top[$i]; } $i++; } return $op;}function XML_RPC_lookup_entity($ent){ global $XML_RPC_entities; if ($XML_RPC_entities[strtolower($ent)]) return $XML_RPC_entities[strtolower($ent)]; if (ereg("^#([0-9]+)$", $ent, $regs)) return chr($regs[1]); return "?";}function XML_RPC_se($parser, $name, $attrs){ global $XML_RPC_xh, $XML_RPC_DateTime, $XML_RPC_String; switch($name) { case "STRUCT": case "ARRAY": $XML_RPC_xh[$parser]['st'].="array("; $XML_RPC_xh[$parser]['cm']++; // this last line turns quoting off // this means if we get an empty array we'll // simply get a bit of whitespace in the eval $XML_RPC_xh[$parser]['qt']=0; break; case "NAME": $XML_RPC_xh[$parser]['st'].="'"; $XML_RPC_xh[$parser]['ac']=""; break; case "FAULT": $XML_RPC_xh[$parser]['isf']=1; break; case "PARAM": $XML_RPC_xh[$parser]['st']=""; break; case "VALUE": $XML_RPC_xh[$parser]['st'].="new XML_RPC_Value("; $XML_RPC_xh[$parser]['lv']=1; $XML_RPC_xh[$parser]['vt']=$XML_RPC_String; $XML_RPC_xh[$parser]['ac']=""; $XML_RPC_xh[$parser]['qt']=0; // look for a value: if this is still 1 by the // time we reach the first data segment then the type is string // by implication and we need to add in a quote break; case "I4": case "INT": case "STRING": case "BOOLEAN": case "DOUBLE": case "DATETIME.ISO8601": case "BASE64": $XML_RPC_xh[$parser]['ac']=""; // reset the accumulator if ($name=="DATETIME.ISO8601" || $name=="STRING") { $XML_RPC_xh[$parser]['qt']=1; if ($name=="DATETIME.ISO8601") $XML_RPC_xh[$parser]['vt']=$XML_RPC_DateTime; } else if ($name=="BASE64") { $XML_RPC_xh[$parser]['qt']=2; } else { // No quoting is required here -- but // at the end of the element we must check // for data format errors. $XML_RPC_xh[$parser]['qt']=0; } break; case "MEMBER": $XML_RPC_xh[$parser]['ac']=""; break; default: break; } if ($name!="VALUE") $XML_RPC_xh[$parser]['lv']=0;}function XML_RPC_ee($parser, $name){ global $XML_RPC_xh,$XML_RPC_Types,$XML_RPC_String; switch($name) { case "STRUCT": case "ARRAY": if ($XML_RPC_xh[$parser]['cm'] && substr($XML_RPC_xh[$parser]['st'], -1) ==',') { $XML_RPC_xh[$parser]['st']=substr($XML_RPC_xh[$parser]['st'],0,-1); } $XML_RPC_xh[$parser]['st'].=")"; $XML_RPC_xh[$parser]['vt']=strtolower($name); $XML_RPC_xh[$parser]['cm']--; break; case "NAME": $XML_RPC_xh[$parser]['st'].= $XML_RPC_xh[$parser]['ac'] . "' => "; break; case "BOOLEAN": // special case here: we translate boolean 1 or 0 into PHP // constants true or false if ($XML_RPC_xh[$parser]['ac']=='1') $XML_RPC_xh[$parser]['ac']="true"; else $XML_RPC_xh[$parser]['ac']="false"; $XML_RPC_xh[$parser]['vt']=strtolower($name); // Drop through intentionally. case "I4": case "INT": case "STRING": case "DOUBLE": case "DATETIME.ISO8601": case "BASE64": if ($XML_RPC_xh[$parser]['qt']==1) { // we use double quotes rather than single so backslashification works OK $XML_RPC_xh[$parser]['st'].="\"". $XML_RPC_xh[$parser]['ac'] . "\""; } else if ($XML_RPC_xh[$parser]['qt']==2) { $XML_RPC_xh[$parser]['st'].="base64_decode('". $XML_RPC_xh[$parser]['ac'] . "')"; } else if ($name=="BOOLEAN") { $XML_RPC_xh[$parser]['st'].=$XML_RPC_xh[$parser]['ac']; } else { // we have an I4, INT or a DOUBLE // we must check that only 0123456789-.<space> are characters here if (!ereg("^\-?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) { // TODO: find a better way of throwing an error // than this! error_log("XML-RPC: non numeric value received in INT or DOUBLE"); $XML_RPC_xh[$parser]['st'].="ERROR_NON_NUMERIC_FOUND"; } else { // it's ok, add it on $XML_RPC_xh[$parser]['st'].=$XML_RPC_xh[$parser]['ac']; } } $XML_RPC_xh[$parser]['ac']=""; $XML_RPC_xh[$parser]['qt']=0; $XML_RPC_xh[$parser]['lv']=3; // indicate we've found a value break; case "VALUE": // deal with a string value if (strlen($XML_RPC_xh[$parser]['ac'])>0 && $XML_RPC_xh[$parser]['vt']==$XML_RPC_String) { $XML_RPC_xh[$parser]['st'].="\"". $XML_RPC_xh[$parser]['ac'] . "\""; } // This if() detects if no scalar was inside <VALUE></VALUE> // and pads an empty "". if($XML_RPC_xh[$parser]['st'][strlen($XML_RPC_xh[$parser]['st'])-1] == '(') { $XML_RPC_xh[$parser]['st'].= '""'; } $XML_RPC_xh[$parser]['st'].=", '" . $XML_RPC_xh[$parser]['vt'] . "')"; if ($XML_RPC_xh[$parser]['cm']) $XML_RPC_xh[$parser]['st'].=","; break; case "MEMBER": $XML_RPC_xh[$parser]['ac']=""; $XML_RPC_xh[$parser]['qt']=0; break; case "DATA": $XML_RPC_xh[$parser]['ac']=""; $XML_RPC_xh[$parser]['qt']=0; break; case "PARAM": $XML_RPC_xh[$parser]['params'][]=$XML_RPC_xh[$parser]['st']; break; case "METHODNAME": $XML_RPC_xh[$parser]['method']=ereg_replace("^[\n\r\t ]+", "", $XML_RPC_xh[$parser]['ac']); break; case "BOOLEAN": // special case here: we translate boolean 1 or 0 into PHP // constants true or false if ($XML_RPC_xh[$parser]['ac']=='1') $XML_RPC_xh[$parser]['ac']="true"; else $XML_RPC_xh[$parser]['ac']="false"; $XML_RPC_xh[$parser]['vt']=strtolower($name); break; default: break; } // if it's a valid type name, set the type if (isset($XML_RPC_Types[strtolower($name)])) { $XML_RPC_xh[$parser]['vt']=strtolower($name); }}function XML_RPC_cd($parser, $data){ global $XML_RPC_xh, $XML_RPC_backslash; //if (ereg("^[\n\r \t]+$", $data)) return; // print "adding [${data}]\n"; if ($XML_RPC_xh[$parser]['lv']!=3) { // "lookforvalue==3" means that we've found an entire value // and should discard any further character data if ($XML_RPC_xh[$parser]['lv']==1) { // if we've found text and we're just in a <value> then // turn quoting on, as this will be a string $XML_RPC_xh[$parser]['qt']=1; // and say we've found a value $XML_RPC_xh[$parser]['lv']=2; } // replace characters that eval would // do special things with @$XML_RPC_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92), $XML_RPC_backslash, $data))); }}function XML_RPC_dh($parser, $data){ global $XML_RPC_xh; if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") { if ($XML_RPC_xh[$parser]['lv']==1) { $XML_RPC_xh[$parser]['qt']=1; $XML_RPC_xh[$parser]['lv']=2; } $XML_RPC_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92), $XML_RPC_backslash, $data))); }}class XML_RPC_Client{ var $path; var $server;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -