From 8a7d5c07ed3447b5d01cbd05d0b957df09b42b05 Mon Sep 17 00:00:00 2001 From: gggeek Date: Tue, 10 Jan 2023 00:12:30 +0000 Subject: [PATCH] improve server demos: adopt more modern coding practices; docs --- demo/server/discuss.php | 7 +- demo/server/methodProviders/functions.php | 483 ++++++++++----------- demo/server/methodProviders/interop.php | 90 +--- demo/server/methodProviders/testsuite.php | 8 +- demo/server/methodProviders/validator1.php | 3 +- demo/server/methodProviders/wrapper.php | 30 +- demo/server/server.php | 15 +- tests/5ServerTest.php | 8 +- 8 files changed, 283 insertions(+), 361 deletions(-) diff --git a/demo/server/discuss.php b/demo/server/discuss.php index 2a490043..6f2f905b 100644 --- a/demo/server/discuss.php +++ b/demo/server/discuss.php @@ -15,6 +15,7 @@ use PhpXmlRpc\Response; use PhpXmlRpc\Server; use PhpXmlRpc\Value; +// NB: this class is totally unaware of the existence of xml-rpc or phpxmlrpc class CommentManager { protected $dbFile = "/tmp/comments.db"; @@ -87,6 +88,8 @@ class CommentManager } } +// Here starts the mapping of CommentManager's methods into xml-rpc methods + $manager = new CommentManager(); $addComment_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcString, Value::$xmlrpcString, Value::$xmlrpcString)); @@ -99,8 +102,6 @@ $getComments_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcString)); $getComments_doc = 'Returns an array of comments for a given ID, which is the sole argument. Each array item is a struct ' . 'containing name and comment text.'; -// NB: take care not to output anything else after this call, as it will mess up the responses and it will be hard to -// debug. In case you have to do so, at least re-emit a correct Content-Length http header (requires output buffering) $srv = new Server(array( "discuss.addComment" => array( "function" => array($manager, "addComment"), @@ -120,4 +121,6 @@ $srv->functions_parameters_type = 'phpvals'; // let code exceptions float all the way to the remote caller as xml-rpc faults - it helps debugging $srv->exception_handling = 1; +// NB: take care not to output anything else after this call, as it will mess up the responses and it will be hard to +// debug. In case you have to do so, at least re-emit a correct Content-Length http header (requires output buffering) $srv->service(); diff --git a/demo/server/methodProviders/functions.php b/demo/server/methodProviders/functions.php index dededd81..cdb0e9be 100644 --- a/demo/server/methodProviders/functions.php +++ b/demo/server/methodProviders/functions.php @@ -5,7 +5,19 @@ * To use this, use something akin to: * $signatures = include('functions.php'); * - * Simplest possible way to implement webservices: create xml-rpc-aware php functions in the global namespace + * Demoes a simple possible way to implement webservices without cluttering the global scope: create xml-rpc-aware static + * methods in a class, and use them for the Server's dispatch map without the need to instantiate an object. + * + * Alternative implementation strategies are possible as well: + * 1. same as above, but use non-static class methods + * 2. define functions in the global scope to be used as xml-rpc method handlers: see interop.php, validator1.php + * 3. define xml-rpc method handlers as anonymous functions directly within the dispatch map + * 4. use php methods or functions which are not aware of xml-rpc and let the Server do all the necessary type conversion: + * see discuss.php + * 5. use the PhpXmlRpc\Wrapper class to achieve the same as in point 4, with no need to manually write the dispatch map + * configuration (but taking instead a performance hit) + * 6. use the PhpXmlRpc\Wrapper class to generate php code in offline mode, achieving the same as in point 5 with no + * performance hit at runtime */ use PhpXmlRpc\Encoder; @@ -13,317 +25,286 @@ use PhpXmlRpc\Response; use PhpXmlRpc\Server; use PhpXmlRpc\Value; -// a PHP version of the state-number server -// send me an integer and I'll sell you a state - -$GLOBALS['stateNames'] = array( - "Alabama", "Alaska", "Arizona", "Arkansas", "California", - "Colorado", "Columbia", "Connecticut", "Delaware", "Florida", - "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", - "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", - "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", - "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", - "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", - "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", - "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming", -); - -$findstate_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcInt)); -$findstate_doc = 'When passed an integer between 1 and 51 returns the name of a US state, where the integer is the ' . - 'index of that state name in an alphabetic order.'; -function findState($req) -{ - $err = ""; - // get the first param - $sno = $req->getParam(0); - - // param must be there and of the correct type: server object does the validation for us - - // extract the value of the state number - $snv = $sno->scalarval(); - // look it up in our array (zero-based) - if (isset($GLOBALS['stateNames'][$snv - 1])) { - $stateName = $GLOBALS['stateNames'][$snv - 1]; - } else { - // not there, so complain - $err = "I don't have a state for the index '" . $snv . "'"; - } - - // if we generated an error, create an error return response - if ($err) { - return new Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err); - } else { - // otherwise, we create the right response with the state name - return new Response(new Value($stateName)); - } -} - -// Sorting demo -// -// send me an array of structs thus: -// -// Dave 35 -// Edd 45 -// Fred 23 -// Barney 37 -// -// and I'll return it to you in sorted order - -function agesorter_compare($a, $b) +class exampleMethods { - /// @todo move away from usage of globals for such a simple case - global $agesorter_arr; - - // don't even ask me _why_ these come padded with hyphens, I couldn't tell you :p - $a = str_replace("-", "", $a); - $b = str_replace("-", "", $b); + public static $stateNames = array( + "Alabama", "Alaska", "Arizona", "Arkansas", "California", + "Colorado", "Columbia", "Connecticut", "Delaware", "Florida", + "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", + "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", + "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", + "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", + "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", + "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", + "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming", + ); + + public static $findstate_sig = array(array('string', 'int')); + public static $findstate_doc = 'When passed an integer between 1 and 51 returns the name of a US state, where the integer is the index of that state name in an alphabetic order.'; + public static function findState($req) + { + $err = ''; + + // get the first param + // param must be there and of the correct type: server object does the validation for us + $sno = $req->getParam(0); + + // extract the value of the state number + $snv = $sno->scalarval(); + + // look it up in our array (zero-based) + if (isset(self::$stateNames[$snv - 1])) { + $stateName = self::$stateNames[$snv - 1]; + } else { + // not there, so complain + $err = "I don't have a state for the index '" . $snv . "'"; + } - if ($agesorter_arr[$a] == $agesorter_arr[$b]) { - return 0; + if ($err != '') { + // if we generated an error, create an error return response + return new Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err); + } else { + // otherwise, we create the right response with the state name + return new Response(new Value($stateName)); + } } - return ($agesorter_arr[$a] > $agesorter_arr[$b]) ? -1 : 1; -} - -$agesorter_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray)); -$agesorter_doc = 'Send this method an array of [string, int] structs, eg: + public static $agesorter_sig = array(array('array', 'array')); + public static $agesorter_doc = 'Send this method an array of [string, int] structs, eg:
  Dave   35
  Edd    45
  Fred   23
  Barney 37
 
-And the array will be returned with the entries sorted by their numbers. -'; -function ageSorter($req) -{ - global $agesorter_arr; - - Server::xmlrpc_debugmsg("Entering 'agesorter'"); - // get the parameter - $sno = $req->getParam(0); - // error string for [if|when] things go wrong - $err = ""; - $agar = array(); - - $max = $sno->count(); - Server::xmlrpc_debugmsg("Found $max array elements"); - foreach ($sno as $i => $rec) { - if ($rec->kindOf() != "struct") { - $err = "Found non-struct in array at element $i"; - break; +And the array will be returned with the entries sorted by their numbers.'; + public static function ageSorter($req) + { + Server::xmlrpc_debugmsg("Entering 'agesorter'"); + + // error string for [if|when] things go wrong + $err = ''; + + // get the parameter, turn it into an easy-to-manipulate php array + $enc = new Encoder(); + $v = $enc->decode($req->getParam(0)); + + $max = count($v); + Server::xmlrpc_debugmsg("Found $max array elements"); + + // extract name and age from struct. The values nested inside it were not type-checked, so we do it + $agar = array(); + foreach ($v as $i => $rec) { + if (!is_array($rec)) { + $err = "Found non-struct in array at element $i"; + break; + } + if (!isset($rec['name']) || !isset($rec['age'])) { + Server::xmlrpc_debugmsg("Invalid array element $i: miss name or age"); + continue; + } + $agar[$rec["name"]] = $rec["age"]; } - // extract name and age from struct - $n = $rec["name"]; - $a = $rec["age"]; - // $n and $a are Values, - // so get the scalarval from them - $agar[$n->scalarval()] = $a->scalarval(); - } - // create the output value - $v = new Value(array(), Value::$xmlrpcArray); - - $agesorter_arr = $agar; - // hack, must make global as uksort() won't - // allow us to pass any other auxiliary information - uksort($agesorter_arr, 'agesorter_compare'); - foreach($agesorter_arr as $key => $val) { - // recreate each struct element - $v[] = new Value( - array( - "name" => new Value($key), - "age" => new Value($val, "int") - ), - Value::$xmlrpcStruct - ); - } + if ($err != '') { + Server::xmlrpc_debugmsg("Aborting 'agesorter'"); + return new Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err); + } - if ($err) { - return new Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err); - } else { - return new Response($v); - } -} + asort($agar); -$addtwo_sig = array(array(Value::$xmlrpcInt, Value::$xmlrpcInt, Value::$xmlrpcInt)); -$addtwo_doc = 'Add two integers together and return the result'; -function addTwo($req) -{ - $s = $req->getParam(0); - $t = $req->getParam(1); + // create the output value + $o = array(); + foreach ($agar as $name => $age) { + $o[] = array("name" => $name, "age" => $age); + } - return new Response(new Value($s->scalarval() + $t->scalarval(), Value::$xmlrpcInt)); -} + Server::xmlrpc_debugmsg("Leaving 'agesorter'"); -$addtwodouble_sig = array(array(Value::$xmlrpcDouble, Value::$xmlrpcDouble, Value::$xmlrpcDouble)); -$addtwodouble_doc = 'Add two doubles together and return the result'; -function addTwoDouble($req) -{ - $s = $req->getParam(0); - $t = $req->getParam(1); + return new Response($enc->encode($o)); + } - return new Response(new Value($s->scalarval() + $t->scalarval(), Value::$xmlrpcDouble)); -} + public static $addtwo_sig = array(array('int', 'int', 'int')); + public static $addtwo_doc = 'Add two integers together and return the result'; + public static function addTwo($req) + { + $s = $req->getParam(0); + $t = $req->getParam(1); -$stringecho_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcString)); -$stringecho_doc = 'Accepts a string parameter, returns the string.'; -function stringEcho($req) -{ - // just sends back a string - return new Response(new Value($req->getParam(0)->scalarval())); -} + return new Response(new Value($s->scalarval() + $t->scalarval(), Value::$xmlrpcInt)); + } -$echoback_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcString)); -$echoback_doc = 'Accepts a string parameter, returns the entire incoming payload'; -function echoBack($req) -{ - // just sends back a string with what i got sent to me, just escaped, that's all - $s = "I got the following message:\n" . $req->serialize(); + public static $addtwodouble_sig = array(array('double', 'double', 'double')); + public static $addtwodouble_doc = 'Add two doubles together and return the result'; + public static function addTwoDouble($req) + { + $s = $req->getParam(0); + $t = $req->getParam(1); - return new Response(new Value($s)); -} + return new Response(new Value($s->scalarval() + $t->scalarval(), Value::$xmlrpcDouble)); + } -$echosixtyfour_sig = array(array(Value::$xmlrpcString, Value::$xmlrpcBase64)); -$echosixtyfour_doc = 'Accepts a base64 parameter and returns it decoded as a string'; -function echoSixtyFour($req) -{ - // Accepts an encoded value, but sends it back as a normal string. - // This is to test that base64 encoding is working as expected - $incoming = $req->getParam(0); + public static $stringecho_sig = array(array('string', 'string')); + public static $stringecho_doc = 'Accepts a string parameter, returns the string.'; + function stringEcho($req) + { + // just sends back a string + return new Response(new Value($req->getParam(0)->scalarval())); + } - return new Response(new Value($incoming->scalarval(), Value::$xmlrpcString)); -} + public static $echoback_sig = array(array('string', 'string')); + public static $echoback_doc = 'Accepts a string parameter, returns the entire incoming payload'; + function echoBack($req) + { + // just sends back a string with what I got sent to me, that's all (escaping for xml is automatic) + $s = "I got the following message:\n" . $req->serialize(); -$bitflipper_sig = array(array(Value::$xmlrpcArray, Value::$xmlrpcArray)); -$bitflipper_doc = 'Accepts an array of booleans, and returns them inverted'; -function bitFlipper($req) -{ - $v = $req->getParam(0); - $rv = new Value(array(), Value::$xmlrpcArray); + return new Response(new Value($s)); + } - foreach ($v as $b) { - if ($b->scalarval()) { - $rv[] = new Value(false, Value::$xmlrpcBoolean); - } else { - $rv[] = new Value(true, Value::$xmlrpcBoolean); - } + public static $echosixtyfour_sig = array(array('string', 'base64')); + public static $echosixtyfour_doc = 'Accepts a base64 parameter and returns it decoded as a string'; + function echoSixtyFour($req) + { + // Accepts an encoded value, but sends it back as a normal string. + // This is to test that base64 encoding is working as expected + $incoming = $req->getParam(0); + + return new Response(new Value($incoming->scalarval(), Value::$xmlrpcString)); } - return new Response($rv); -} + public static $bitflipper_sig = array(array('array', 'array')); + public static $bitflipper_doc = 'Accepts an array of booleans, and returns them inverted'; + function bitFlipper($req) + { + $v = $req->getParam(0); + $rv = new Value(array(), Value::$xmlrpcArray); + + foreach ($v as $b) { + if ($b->scalarval()) { + $rv[] = new Value(false, Value::$xmlrpcBoolean); + } else { + $rv[] = new Value(true, Value::$xmlrpcBoolean); + } + } + return new Response($rv); + } -$mailsend_sig = array(array( - Value::$xmlrpcBoolean, Value::$xmlrpcString, Value::$xmlrpcString, - Value::$xmlrpcString, Value::$xmlrpcString, Value::$xmlrpcString, - Value::$xmlrpcString, Value::$xmlrpcString, -)); -$mailsend_doc = 'mail.send(recipient, subject, text, sender, cc, bcc, mimetype)
+ public static $mailsend_sig = array(array( + 'boolean', 'string', 'string', + 'string', 'string', 'string', + 'string', 'string', + )); + public static $mailsend_doc = 'mail.send(recipient, subject, text, sender, cc, bcc, mimetype)
recipient, cc, and bcc are strings, comma-separated lists of email addresses, as described above.
subject is a string, the subject of the message.
sender is a string, it\'s the email address of the person sending the message. This string can not be a comma-separated list, it must contain a single email address only.
text is a string, it contains the body of the message.
-mimetype, a string, is a standard MIME type, for example, text/plain. -'; -// WARNING; this functionality depends on the sendmail -t option -// it may not work with Windows machines properly; particularly -// the Bcc option. Sneak on your friends at your own risk! -function mailSend($req) -{ - $err = ""; - - $mTo = $req->getParam(0); - $mSub = $req->getParam(1); - $mBody = $req->getParam(2); - $mFrom = $req->getParam(3); - $mCc = $req->getParam(4); - $mBcc = $req->getParam(5); - $mMime = $req->getParam(6); - - if ($mTo->scalarval() == "") { - $err = "Error, no 'To' field specified"; - } +mimetype, a string, is a standard MIME type, for example, text/plain.'; + /** + * WARNING: this functionality depends on the sendmail -t option, it may not work with Windows machines properly; + * particularly the Bcc option. + * Sneak on your friends at your own risk! + */ + public static function mailSend($req) + { + $err = ""; + + $mTo = $req->getParam(0); + $mSub = $req->getParam(1); + $mBody = $req->getParam(2); + $mFrom = $req->getParam(3); + $mCc = $req->getParam(4); + $mBcc = $req->getParam(5); + $mMime = $req->getParam(6); + + if ($mTo->scalarval() == "") { + $err = "Error, no 'To' field specified"; + } - if ($mFrom->scalarval() == "") { - $err = "Error, no 'From' field specified"; - } + if ($mFrom->scalarval() == "") { + $err = "Error, no 'From' field specified"; + } - $msgHdr = "From: " . $mFrom->scalarval() . "\n"; - $msgHdr .= "To: " . $mTo->scalarval() . "\n"; + /// @todo in real life, we should check for presence of return characters to avoid header injection! - if ($mCc->scalarval() != "") { - $msgHdr .= "Cc: " . $mCc->scalarval() . "\n"; - } - if ($mBcc->scalarval() != "") { - $msgHdr .= "Bcc: " . $mBcc->scalarval() . "\n"; - } - if ($mMime->scalarval() != "") { - $msgHdr .= "Content-type: " . $mMime->scalarval() . "\n"; - } - $msgHdr .= "X-Mailer: XML-RPC for PHP mailer 1.0"; + $msgHdr = "From: " . $mFrom->scalarval() . "\n"; + $msgHdr .= "To: " . $mTo->scalarval() . "\n"; - if ($err == "") { - if (!mail("", $mSub->scalarval(), $mBody->scalarval(), $msgHdr) - ) { - $err = "Error, could not send the mail."; + if ($mCc->scalarval() != "") { + $msgHdr .= "Cc: " . $mCc->scalarval() . "\n"; + } + if ($mBcc->scalarval() != "") { + $msgHdr .= "Bcc: " . $mBcc->scalarval() . "\n"; + } + if ($mMime->scalarval() != "") { + $msgHdr .= "Content-type: " . $mMime->scalarval() . "\n"; + } + $msgHdr .= "X-Mailer: XML-RPC for PHP mailer 1.0"; + + if ($err == "") { + if (!mail("", $mSub->scalarval(), $mBody->scalarval(), $msgHdr)) { + $err = "Error, could not send the mail."; + } } - } - if ($err) { - return new Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err); - } else { - return new Response(new Value(true, Value::$xmlrpcBoolean)); + if ($err) { + return new Response(0, PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser, $err); + } else { + return new Response(new Value(true, Value::$xmlrpcBoolean)); + } } + } return array( "examples.getStateName" => array( - "function" => "findState", - "signature" => $findstate_sig, - "docstring" => $findstate_doc, + "function" => array("exampleMethods", "findState"), + "signature" => exampleMethods::$findstate_sig, + "docstring" => exampleMethods::$findstate_doc, ), "examples.sortByAge" => array( - "function" => "ageSorter", - "signature" => $agesorter_sig, - "docstring" => $agesorter_doc, + "function" => array("exampleMethods", "ageSorter"), + "signature" => exampleMethods::$agesorter_sig, + "docstring" => exampleMethods::$agesorter_doc, ), "examples.addtwo" => array( - "function" => "addTwo", - "signature" => $addtwo_sig, - "docstring" => $addtwo_doc, + "function" => array("exampleMethods", "addTwo"), + "signature" => exampleMethods::$addtwo_sig, + "docstring" => exampleMethods::$addtwo_doc, ), "examples.addtwodouble" => array( - "function" => "addTwoDouble", - "signature" => $addtwodouble_sig, - "docstring" => $addtwodouble_doc, + "function" => array("exampleMethods", "addTwoDouble"), + "signature" => exampleMethods::$addtwodouble_sig, + "docstring" => exampleMethods::$addtwodouble_doc, ), "examples.stringecho" => array( - "function" => "stringEcho", - "signature" => $stringecho_sig, - "docstring" => $stringecho_doc, + "function" => array("exampleMethods", "stringEcho"), + "signature" => exampleMethods::$stringecho_sig, + "docstring" => exampleMethods::$stringecho_doc, ), "examples.echo" => array( - "function" => "echoBack", - "signature" => $echoback_sig, - "docstring" => $echoback_doc, + "function" => array("exampleMethods", "echoBack"), + "signature" => exampleMethods::$echoback_sig, + "docstring" => exampleMethods::$echoback_doc, ), "examples.decode64" => array( - "function" => "echoSixtyFour", - "signature" => $echosixtyfour_sig, - "docstring" => $echosixtyfour_doc, + "function" => array("exampleMethods", "echoSixtyFour"), + "signature" => exampleMethods::$echosixtyfour_sig, + "docstring" => exampleMethods::$echosixtyfour_doc, ), "examples.invertBooleans" => array( - "function" => "bitFlipper", - "signature" => $bitflipper_sig, - "docstring" => $bitflipper_doc, + "function" => array("exampleMethods", "bitFlipper"), + "signature" => exampleMethods::$bitflipper_sig, + "docstring" => exampleMethods::$bitflipper_doc, ), // left in as an example, but disabled by default, to avoid this being abused if left on an open server /*"mail.send" => array( - "function" => "mailSend", - "signature" => $mailsend_sig, - "docstring" => $mailsend_doc, + "function" => array("exampleMethods", "mailSend"), + "signature" => exampleMethods::$mailsend_sig, + "docstring" => exampleMethods::$mailsend_doc, ),*/ ); diff --git a/demo/server/methodProviders/interop.php b/demo/server/methodProviders/interop.php index 54f00d40..345d151a 100644 --- a/demo/server/methodProviders/interop.php +++ b/demo/server/methodProviders/interop.php @@ -45,79 +45,23 @@ $i_echoBase64_doc = "Echoes base64."; $i_echoDate_sig = array(array(Value::$xmlrpcDateTime, Value::$xmlrpcDateTime)); $i_echoDate_doc = "Echoes dateTime."; -function i_echoParam($req) -{ - $s = $req->getParam(0); - - return new Response($s); -} - -function i_echoString($req) -{ - return i_echoParam($req); -} - -function i_echoInteger($req) -{ - return i_echoParam($req); -} - -function i_echoFloat($req) -{ - return i_echoParam($req); -} - -function i_echoStruct($req) -{ - return i_echoParam($req); -} - -function i_echoStringArray($req) -{ - return i_echoParam($req); -} - -function i_echoIntegerArray($req) -{ - return i_echoParam($req); -} - -function i_echoFloatArray($req) -{ - return i_echoParam($req); -} - -function i_echoStructArray($req) -{ - return i_echoParam($req); -} - -function i_echoValue($req) -{ - return i_echoParam($req); -} +$i_whichToolkit_sig = array(array(Value::$xmlrpcStruct)); +$i_whichToolkit_doc = "Returns a struct containing the following strings: toolkitDocsUrl, toolkitName, toolkitVersion, toolkitOperatingSystem."; -function i_echoBase64($req) +function i_echoParam($req) { - return i_echoParam($req); -} + $v = $req->getParam(0); -function i_echoDate($req) -{ - return i_echoParam($req); + return new Response($v); } -$i_whichToolkit_sig = array(array(Value::$xmlrpcStruct)); -$i_whichToolkit_doc = "Returns a struct containing the following strings: toolkitDocsUrl, toolkitName, toolkitVersion, toolkitOperatingSystem."; - function i_whichToolkit($req) { - global $SERVER_SOFTWARE; $ret = array( "toolkitDocsUrl" => "https://gggeek.github.io/phpxmlrpc/", "toolkitName" => PhpXmlRpc\PhpXmlRpc::$xmlrpcName, "toolkitVersion" => PhpXmlRpc\PhpXmlRpc::$xmlrpcVersion, - "toolkitOperatingSystem" => isset($SERVER_SOFTWARE) ? $SERVER_SOFTWARE : $_SERVER['SERVER_SOFTWARE'], + "toolkitOperatingSystem" => $_SERVER['SERVER_SOFTWARE'], ); $encoder = new PhpXmlRpc\Encoder(); @@ -126,57 +70,57 @@ function i_whichToolkit($req) return array( "interopEchoTests.echoString" => array( - "function" => "i_echoString", + "function" => "i_echoParam", "signature" => $i_echoString_sig, "docstring" => $i_echoString_doc, ), "interopEchoTests.echoStringArray" => array( - "function" => "i_echoStringArray", + "function" => "i_echoParam", "signature" => $i_echoStringArray_sig, "docstring" => $i_echoStringArray_doc, ), "interopEchoTests.echoInteger" => array( - "function" => "i_echoInteger", + "function" => "i_echoParam", "signature" => $i_echoInteger_sig, "docstring" => $i_echoInteger_doc, ), "interopEchoTests.echoIntegerArray" => array( - "function" => "i_echoIntegerArray", + "function" => "i_echoParam", "signature" => $i_echoIntegerArray_sig, "docstring" => $i_echoIntegerArray_doc, ), "interopEchoTests.echoFloat" => array( - "function" => "i_echoFloat", + "function" => "i_echoParam", "signature" => $i_echoFloat_sig, "docstring" => $i_echoFloat_doc, ), "interopEchoTests.echoFloatArray" => array( - "function" => "i_echoFloatArray", + "function" => "i_echoParam", "signature" => $i_echoFloatArray_sig, "docstring" => $i_echoFloatArray_doc, ), "interopEchoTests.echoStruct" => array( - "function" => "i_echoStruct", + "function" => "i_echoParam", "signature" => $i_echoStruct_sig, "docstring" => $i_echoStruct_doc, ), "interopEchoTests.echoStructArray" => array( - "function" => "i_echoStructArray", + "function" => "i_echoParam", "signature" => $i_echoStructArray_sig, "docstring" => $i_echoStructArray_doc, ), "interopEchoTests.echoValue" => array( - "function" => "i_echoValue", + "function" => "i_echoParam", "signature" => $i_echoValue_sig, "docstring" => $i_echoValue_doc, ), "interopEchoTests.echoBase64" => array( - "function" => "i_echoBase64", + "function" => "i_echoParam", "signature" => $i_echoBase64_sig, "docstring" => $i_echoBase64_doc, ), "interopEchoTests.echoDate" => array( - "function" => "i_echoDate", + "function" => "i_echoParam", "signature" => $i_echoDate_sig, "docstring" => $i_echoDate_doc, ), diff --git a/demo/server/methodProviders/testsuite.php b/demo/server/methodProviders/testsuite.php index 61b79d0c..6b6cd5ad 100644 --- a/demo/server/methodProviders/testsuite.php +++ b/demo/server/methodProviders/testsuite.php @@ -92,9 +92,9 @@ return array( // Greek word 'kosme'. NB: NOT a valid ISO8859 string! // NB: we can only register this when setting internal encoding to UTF-8, or it will break system.listMethods "tests.utf8methodname." . 'κόσμε' => array( - "function" => "stringEcho", - "signature" => $stringecho_sig, - //"docstring" => $stringecho_doc, + "function" => "exampleMethods::stringEcho", + "signature" => exampleMethods::$stringecho_sig, + "docstring" => exampleMethods::$stringecho_doc, ), /*"tests.iso88591methodname." . chr(224) . chr(252) . chr(232) => array( "function" => "stringEcho", @@ -105,6 +105,6 @@ return array( 'tests.getStateName.12' => array( "function" => "findStateWithNulls", "signature" => $findstate12_sig, - //"docstring" => $findstate_doc, + "docstring" => exampleMethods::$findstate_doc, ), ); diff --git a/demo/server/methodProviders/validator1.php b/demo/server/methodProviders/validator1.php index 4024eb6a..4dc17aa9 100644 --- a/demo/server/methodProviders/validator1.php +++ b/demo/server/methodProviders/validator1.php @@ -80,8 +80,7 @@ function v1_moderateSizeArrayCheck($req) $first = $ar[0]; $last = $ar[$sz - 1]; - return new Response(new Value($first->scalarval() . - $last->scalarval(), Value::$xmlrpcString)); + return new Response(new Value($first->scalarval() . $last->scalarval(), Value::$xmlrpcString)); } $v1_simpleStructReturn_sig = array(array(Value::$xmlrpcStruct, Value::$xmlrpcInt)); diff --git a/demo/server/methodProviders/wrapper.php b/demo/server/methodProviders/wrapper.php index 488b9777..e128ff0c 100644 --- a/demo/server/methodProviders/wrapper.php +++ b/demo/server/methodProviders/wrapper.php @@ -26,10 +26,8 @@ use PhpXmlRpc\Value; */ function plain_findstate($stateNo) { - global $stateNames; - - if (isset($stateNames[$stateNo - 1])) { - return $stateNames[$stateNo - 1]; + if (isset(exampleMethods::$stateNames[$stateNo - 1])) { + return exampleMethods::$stateNames[$stateNo - 1]; } else { // not, there so complain throw new Exception("I don't have a state for the index '" . $stateNo . "'", PhpXmlRpc\PhpXmlRpc::$xmlrpcerruser); @@ -46,7 +44,7 @@ $findstate2_sig = $wrapper->wrapPhpFunction('plain_findstate'); /** * Used to test usage of object methods in dispatch maps and in wrapper code. */ -class xmlrpcServerMethodsContainer +class handlersContainer { /** * Method used to test logging of php warnings generated by user functions. @@ -104,29 +102,29 @@ class xmlrpcServerMethodsContainer } } -$findstate3_sig = $wrapper->wrapPhpFunction(array('xmlrpcServerMethodsContainer', 'findState')); +$findstate3_sig = $wrapper->wrapPhpFunction(array('handlersContainer', 'findState')); -$obj = new xmlrpcServerMethodsContainer(); -$findstate4_sig = $wrapper->wrapPhpFunction(array($obj, 'findstate')); +$instance = new handlersContainer(); +$findstate4_sig = $wrapper->wrapPhpFunction(array($instance, 'findstate')); -$findstate5_sig = $wrapper->wrapPhpFunction('xmlrpcServerMethodsContainer::findState', '', array('return_source' => true)); +$findstate5_sig = $wrapper->wrapPhpFunction('handlersContainer::findState', '', array('return_source' => true)); eval($findstate5_sig['source']); $findstate6_sig = $wrapper->wrapPhpFunction('plain_findstate', '', array('return_source' => true)); eval($findstate6_sig['source']); -$findstate7_sig = $wrapper->wrapPhpFunction(array('xmlrpcServerMethodsContainer', 'findState'), '', array('return_source' => true)); +$findstate7_sig = $wrapper->wrapPhpFunction(array('handlersContainer', 'findState'), '', array('return_source' => true)); eval($findstate7_sig['source']); -$findstate8_sig = $wrapper->wrapPhpFunction(array($obj, 'findstate'), '', array('return_source' => true)); +$findstate8_sig = $wrapper->wrapPhpFunction(array($instance, 'findstate'), '', array('return_source' => true)); eval($findstate8_sig['source']); -$findstate9_sig = $wrapper->wrapPhpFunction('xmlrpcServerMethodsContainer::findState', '', array('return_source' => true)); +$findstate9_sig = $wrapper->wrapPhpFunction('handlersContainer::findState', '', array('return_source' => true)); eval($findstate9_sig['source']); $findstate10_sig = array( /// @todo add a demo and test with closure usage - "function" => function ($req) { return findState($req); }, + "function" => function ($req) { return exampleMethods::findState($req); }, "signature" => array(array(Value::$xmlrpcString, Value::$xmlrpcInt)), "docstring" => 'When passed an integer between 1 and 51 returns the name of a US state, where the integer is the ' . 'index of that state name in an alphabetic order.', @@ -135,7 +133,7 @@ $findstate10_sig = array( $findstate11_sig = $wrapper->wrapPhpFunction(function ($stateNo) { return plain_findstate($stateNo); }); /// @todo do we really need a new instance ? -$c = new xmlrpcServerMethodsContainer(); +$c = new handlersContainer(); $moreSignatures = $wrapper->wrapPhpClass($c, array('prefix' => 'tests.', 'method_type' => 'all')); @@ -163,11 +161,11 @@ return array_merge( 'tests.returnPhpObject' => $returnObj_sig, // signature omitted on purpose "tests.generatePHPWarning" => array( - "function" => array($obj, "phpWarningGenerator"), + "function" => array($instance, "phpWarningGenerator"), ), // signature omitted on purpose "tests.raiseException" => array( - "function" => array($obj, "exceptionGenerator"), + "function" => array($instance, "exceptionGenerator"), ), ) ); diff --git a/demo/server/server.php b/demo/server/server.php index 93691b66..41779279 100644 --- a/demo/server/server.php +++ b/demo/server/server.php @@ -13,27 +13,24 @@ require_once __DIR__ . "/_prepend.php"; use PhpXmlRpc\PhpXmlRpc; -use PhpXmlRpc\Response; use PhpXmlRpc\Server; -use PhpXmlRpc\Value; // Most of the code used to implement the webservices, and their signatures, are stowed away in neatly organized files, // each demoing a different topic -// The simplest way of implementing webservices: as xml-rpc-aware global functions +// One of the simplest way of implementing webservices: as xml-rpc-aware methods of a php object $signatures1 = include(__DIR__.'/methodProviders/functions.php'); -// Definitions of webservices used for interoperability testing +// Even simpler? webservices defined using php functions in the global scope: definitions of webservices used for +// interoperability testing $signatures2 = include(__DIR__.'/methodProviders/interop.php'); $signatures3 = include(__DIR__.'/methodProviders/validator1.php'); -// And finally a few examples inline -/// @todo bring back a few, basic examples here -$signatures = array(); +// See also discuss.php for a different take: implementing webservices out of php code which is not aware of xml-rpc -$signatures = array_merge($signatures, $signatures1, $signatures2, $signatures3); +$signatures = array_merge($signatures1, $signatures2, $signatures3); -if (defined('TESTMODE')) { +if (defined('TESTMODE') || true) { // Webservices used only by the testsuite - do not use them in production $signatures4 = include(__DIR__.'/methodProviders/testsuite.php'); $signatures5 = include(__DIR__.'/methodProviders/wrapper.php'); diff --git a/tests/5ServerTest.php b/tests/5ServerTest.php index 23e80942..7b3f7217 100644 --- a/tests/5ServerTest.php +++ b/tests/5ServerTest.php @@ -271,8 +271,8 @@ class ServerTest extends PhpXmlRpc_PolyfillTestCase // (used on the server side) sort it out $this->addQueryParams(array('DETECT_ENCODINGS' => array('EUC-JP', 'UTF-8'))); $v = $this->send(mb_convert_encoding($str, 'EUC-JP', 'UTF-8')); - $this->assertEquals($sendString, $v->scalarval()); PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1'; + $this->assertEquals($sendString, $v->scalarval()); } public function testExoticCharsetsRequests3() @@ -319,10 +319,10 @@ class ServerTest extends PhpXmlRpc_PolyfillTestCase new xmlrpcval('hello') )); $v = $this->send($m); + PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1'; if ($v) { $this->assertEquals('hello', $v->scalarval()); } - PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-1'; } public function testAddingDoubles() @@ -830,7 +830,7 @@ And turned it into nylon'; public function testServerWrappedClass() { - $m = new xmlrpcmsg('tests.xmlrpcServerMethodsContainer.findState', array( + $m = new xmlrpcmsg('tests.handlersContainer.findState', array( new xmlrpcval(23, 'int'), )); $v = $this->send($m); @@ -1008,7 +1008,7 @@ And turned it into nylon'; public function testServerComments() { - $m = new xmlrpcmsg('tests.xmlrpcServerMethodsContainer.debugMessageGenerator', array( + $m = new xmlrpcmsg('tests.handlersContainer.debugMessageGenerator', array( new xmlrpcval('hello world', 'string'), )); $r = $this->send($m, 0, true); -- 2.47.0