From: gggeek Date: Mon, 2 Jan 2023 19:19:44 +0000 (+0000) Subject: replace PHP-XMLRPC with PHPXMLRPC; WIP manual; code comments X-Git-Tag: 4.9.4~38 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=6f4e22a7fd5d286f909760e96faf325682bf2480;p=plcapi.git replace PHP-XMLRPC with PHPXMLRPC; WIP manual; code comments --- diff --git a/README.md b/README.md index d53f8fa7..6e4215d0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -XMLRPC for PHP -============== +XMLRPC for PHP (a.k.a. PHPXMLRPC) +================================= A php library for building xml-rpc clients and servers. @@ -22,16 +22,17 @@ It includes sections about upgrading from previous versions as well as running t debugger. The manual is formatted as an asciidoc file - if viewing it locally, it is recommended to either use an IDE which can -natively render asciidoc, or view it as html via in-browser rendering by serving it via a webserver and accessing /doc/manual/index.html +natively render asciidoc, or view it as html via in-browser rendering by serving it via a webserver and accessing +/doc/manual/index.html Automatically-generated documentation for the API is available online at [http://gggeek.github.io/phpxmlrpc/doc-4/api/index.html](http://gggeek.github.io/phpxmlrpc/doc-4/api/index.html) You are encouraged to look also at the code examples found in the demo/ directory. Note: to reduce the size of the download, the demo files are not part of the default package installed with Composer. -You can either make sure they are available locally, by installing the library using Composer option `--prefer-install=source` -(when doing so, make sure that the demo folder is not directly accessible from the internet, ie. it is not within the -webserver root directory), or just check them out online at https://github.com/gggeek/phpxmlrpc/tree/master/demo. +You can either check them out online at https://github.com/gggeek/phpxmlrpc/tree/master/demo, or make sure they are +available locally, by installing the library using Composer option `--prefer-install=source` (when doing so, make sure +that the demo folder is not directly accessible from the internet, ie. it is not within the webserver root directory). License ------- diff --git a/debugger/controller.php b/debugger/controller.php index 0d4acc60..bd7a42fe 100644 --- a/debugger/controller.php +++ b/debugger/controller.php @@ -268,7 +268,7 @@ if (defined('JSXMLRPC_BASEURL')) {
/>
/
/>
- JSONRPC Debugger (based on the PHP-XMLRPC library) + JSONRPC Debugger (based on the PHPXMLRPC library)
diff --git a/doc/build/generate.sh b/doc/build/generate.sh index 1e13596c..f15b7dc3 100755 --- a/doc/build/generate.sh +++ b/doc/build/generate.sh @@ -6,7 +6,7 @@ cd "$(dirname -- "$(dirname -- "${BASH_SOURCE[0]}")")" ### API docs -php ./build/vendor/bin/phpdoc run --cache-folder './build/.phpdoc' -d "$(realpath ../src/)" -t './api' --title PHP-XMLRPC --defaultpackagename PHPXMLRPC +php ./build/vendor/bin/phpdoc run --cache-folder './build/.phpdoc' -d "$(realpath ../src/)" -t './api' --title PHPXMLRPC --defaultpackagename PHPXMLRPC ### User Manual diff --git a/doc/manual/phpxmlrpc_manual.adoc b/doc/manual/phpxmlrpc_manual.adoc index e7fa3fd7..26dc7862 100644 --- a/doc/manual/phpxmlrpc_manual.adoc +++ b/doc/manual/phpxmlrpc_manual.adoc @@ -197,8 +197,31 @@ $myStruct = new Encoder()->encode([ ]); ---- -See the http://gggeek.github.io/phpxmlrpc/doc-4/api/classes/PhpXmlRpc-Encoder.html#method_encode[phpdoc documentation] -for `PhpXmlRpc\Encoder::encode` for the full details of the encoding process. +Encoding works recursively on arrays and objects, encoding numerically indexed php arrays into array-type Value objects +and non numerically indexed php arrays into struct-type Value objects. PHP objects are encoded into struct-type Value by +iterating over their public properties, excepted for those that are already instances of the Value class or descendants +thereof, which will not be further encoded. Optionally, encoding of date-times is carried-on on php strings with the +corresponding format, as well as encoding of NULL values. Note that there's no support for encoding php values into base64 +values - base64 Value objects have to be created manually (but they can be part of a php array passed to `encode`). +Another example, showcasing some of those features: + +[source, php] +---- +use PhpXmlRpc\Encoder; +use PhpXmlRpc\Value; + +$value = new Encoder()->encode( + array( + 'first struct_element: a null' => null, + '2nd: a base64 element' => new Value('hello world', 'base64'), + '3rd: a datetime' => '20060107T01:53:00' + ), + array('auto_dates', 'null_extension') +); +---- + +See the https://gggeek.github.io/phpxmlrpc/doc-4/api/classes/PhpXmlRpc-Encoder.html#method_encode[phpdoc documentation] +for `PhpXmlRpc\Encoder::encode` for more details on the encoding process and available options. ==== Automatic type conversion: XMLRPC to PHP @@ -225,7 +248,7 @@ Note that when using automatic conversion this way, all information about the or impossible to tell apart an `i4` from an `i8` value, or to know if a php string had been encoded as xmlrpc string or as base64. -See the http://gggeek.github.io/phpxmlrpc/doc-4/api/classes/PhpXmlRpc-Encoder.html#method_encode[phpdoc documentation] +See the https://gggeek.github.io/phpxmlrpc/doc-4/api/classes/PhpXmlRpc-Encoder.html#method_encode[phpdoc documentation] for `PhpXmlRpc\Encoder::decode` for the full details of the decoding process. ==== Notes on types @@ -334,7 +357,7 @@ The `$server_port` parameter is optional, and if omitted will default to '80' wh The `$transport` parameter is optional, and if omitted will default to 'http'. Allowed values are either 'http', 'https', 'http11', 'http2' or 'h2c'. Its value can be overridden with every call to the `send()` method. See the -http://gggeek.github.io/phpxmlrpc/doc-4/api/classes/PhpXmlRpc-Client.html#method_send[phpdoc documentation] for the send +https://gggeek.github.io/phpxmlrpc/doc-4/api/classes/PhpXmlRpc-Client.html#method_send[phpdoc documentation] for the send method for more details about the meaning of the different values. ==== Sending requests @@ -414,7 +437,7 @@ A wide range of options can be set to the client to manage the details of the HT authentication (Basic, Digest, NTLM), SSL certificates, proxies, cookies, compression of the requests, usage of keepalives for consecutive calls, the accepted response compression, charset encoding used for the requests and the user-agent string. -See the http://gggeek.github.io/phpxmlrpc/doc-4/api/classes/PhpXmlRpc-Client.html[phpdoc documentation] for details on +See the https://gggeek.github.io/phpxmlrpc/doc-4/api/classes/PhpXmlRpc-Client.html[phpdoc documentation] for details on all of those. ===== cURL vs socket calls @@ -426,7 +449,7 @@ can make use of the `setUseCurl` method to force or disable usage of the cURL ba When using cURL as the underlying transport, it is possible to set directly into the client any of the cURL options available in your php installation, via the `setCurlOptions` method. -==== Sending multiple calls +==== Sending multiple requests @TODO... @@ -601,6 +624,9 @@ function foo ($xmlrpcreq) $par = $xmlrpcreq->getParam(0); // retrieve value of first parameter - assumes at least one param received $val = $par->scalarval(); // decode value of first parameter - assumes it is a scalar value + // note that we could also have achieved the same this way: + //$val = new PhpXmlRpc\Encoder()->decode($xmlrpcreq)[0]; + ... if ($err) { @@ -973,11 +999,11 @@ xmlrpc, and the corresponding xmlrpcvals will return "null" for scalarTyp(). When set to `TRUE`, php NULL values encoded into Value objects will get serialized using the `` tag instead of ``. Please note that both forms are always accepted as input regardless of the value of this variable. -=== Helper classes [[helpers]] +=== Helper classes and functions [[helpers]] XML-RPC for PHP contains some helper classes which you can use to make processing of XML-RPC requests easier. -==== Date functions +==== Date handling The XML-RPC specification has this to say on dates: @@ -1007,7 +1033,7 @@ The argument $utc can be omitted, in which case it defaults to `0`. If it is set time passed in for UTC. Example: if you're in the GMT-6:00 timezone and set $utc, you will receive a date representation six hours ahead of your local time. -The included demo program __vardemo.php__ includes a demonstration of this function. +The included demo program __demo/client/vardemo.php__ includes a demonstration of this function. ===== iso8601_decode [[iso8601decode]] @@ -1017,116 +1043,12 @@ Returns a UNIX timestamp from an ISO 8601 encoded time and date string passed in to be in the UTC timezone, and thus the result is also UTC: otherwise, the timezone is assumed to be your local timezone and you receive a local timestamp. -[[arrayuse]] -@TODO MERGE... -==== Easy use with nested PHP values - -Dan Libby was kind enough to contribute two helper functions that make it easier to translate to and from PHP values. -This makes it easier to deal with complex structures. At the moment support is limited to int, double, string, -array, datetime and struct datatypes; note also that all PHP arrays are encoded as structs, except arrays whose keys are -integer numbers starting with 0 and incremented by 1. - -These functions reside in __xmlrpc.inc__. - -[[phpxmlrpcdecode]] -===== php_xmlrpc_decode - - mixed php_xmlrpc_decode(Value $xmlrpc_val, array $options) - array php_xmlrpc_decode(xmlrpcmsg $xmlrpcmsg_val, string $options) +==== Decoding xml -Returns a native PHP value corresponding to the values found in the Value $xmlrpc_val, translated into PHP types. Base-64 -and datetime values are automatically decoded to strings. - -In the second form, returns an array containing the parameters of the given xmlrpcmsg_val, decoded to php types. - -The options parameter is optional. If specified, it must consist of an array of options to be enabled in the decoding -process. At the moment the only valid option are decode_php_objs and `dates_as_objects`. When the first is set, php -objects that have been converted to xml-rpc structs using the php_xmlrpc_encode function and a corresponding -encoding option will be converted back into object values instead of arrays (provided that the class definition is -available at reconstruction time). When the second is set, XML-RPC datetime values will be converted into native dateTime -objects instead of strings. - -____WARNING__:__ please take extreme care before enabling the decode_php_objs option: when php objects are rebuilt from -the received xml, their constructor function will be silently invoked. This means that you are allowing the remote end -to trigger execution of uncontrolled PHP code on your server, opening the door to code injection exploits. Only -enable this option when you have complete trust of the remote server/client. - -Example: -[source, php] ----- -use PhpXmlRpc\Response; -use PhpXmlRpc\Server; -use PhpXmlRpc\Value; - -// wrapper to expose an existing php function as xmlrpc method handler -function foo_wrapper($m) -{ - $params = php_xmlrpc_decode($m); - $retval = call_user_func_array('foo', $params); - return new Response(new Value($retval)); // foo return value will be serialized as string -} - -$s = new Server(array( - "examples.myFunc1" => array( - "function" => "foo_wrapper", - "signatures" => ... - ) -)); ----- - -[[phpxmlrpcencode]] -===== php_xmlrpc_encode - - Value php_xmlrpc_encode(mixed $phpval, array $options) - -Returns a Value object populated with the PHP -values in $phpval. Works recursively on arrays -and objects, encoding numerically indexed php arrays into array-type -Value objects and non numerically indexed php arrays into -struct-type Value objects. Php objects are encoded into -struct-type xmlrpcvals, excepted for php values that are already -instances of the Value class or descendants thereof, which will -not be further encoded. Note that there's no support for encoding php -values into base-64 values. Encoding of date-times is optionally -carried-on on php strings with the correct format. - -The options parameter is optional. If specified, it must consist of an array of options to be enabled in the -encoding process. At the moment the only valid options are encode_php_objs, `null_extension` and auto_dates. - -The first will enable the creation of 'particular' Value -objects out of php objects, that add a "php_class" xml attribute to -their serialized representation. This attribute allows the function -php_xmlrpc_decode to rebuild the native php objects (provided that the -same class definition exists on both sides of the communication). The -second allows to encode php `NULL` values to the -`` (or -``, see ...) tag. The last encodes any -string that matches the ISO8601 format into an XML-RPC -datetime. - -Example: -[source, php] ----- -use PhpXmlRpc\Server; - -// the easy way to build a complex xml-rpc struct, showing nested base64 value and datetime values -$val = php_xmlrpc_encode( - array( - 'first struct_element: an int' => 666, - 'second: an array' => array ('apple', 'orange', 'banana'), - 'third: a base64 element' => new Value('hello world', 'base64'), - 'fourth: a datetime' => '20060107T01:53:00' - ), - array('auto_dates') -); ----- - -===== php_xmlrpc_decode_xml - - Value | Response | xmlrpcmsg php_xmlrpc_decode_xml(string $xml, array $options) + Value | Request | Response Encoder::decodeXml(string $xml, array $options) Decodes the xml representation of either an xmlrpc request, response or single value, returning the corresponding -php-xmlrpc object, or `FALSE` in case of an error. +phpxmlrpc object, or `FALSE` in case of an error. The options parameter is optional. If specified, it must consist of an array of options to be enabled in the decoding process. At the moment, no option is supported. @@ -1135,8 +1057,8 @@ Example: [source, php] ---- $text = 'Hello world'; -$val = php_xmlrpc_decode_xml($text); -if ($val) echo 'Found a value of type '.$val->kindOf(); else echo 'Found invalid xml'; +$val = $encoder::decodeXml($text); +if ($val) echo 'Found a value of type ' . $val->kindOf(); else echo 'Found invalid xml'; ---- === Logging @@ -1145,7 +1067,28 @@ if ($val) echo 'Found a value of type '.$val->kindOf(); else echo 'Found invalid === Transferring PHP objects over XML-RPC -@TODO... +In case there is a (real) need to transfer php object instances over XMLRPC, the "usual" way would be to use a `serialize` +call on the sender side, then transfer the serialized string using a base64 xmlrpc value, and call `unserialize` on the +receiving side. + +The phpxmlrpc library does offer an alternative method, which might offer marginally better performances and ease of use, +by usage of `PhpXmlRpc\Encoder::encode` and `PhpXmlRpc\Encoder::decode`: + +. on the sender side, encode the desired object using option 'encode_php_objs'. This will lead to the creation of an + xmlrpc struct value with an extra xml attribute: "php_class" + +. on the receiver side, decode the received Value using option 'decode_php_objs'. The xml-rpc struct with the extra + attribute will be converted back into an object of the desired class instead of an array + +____WARNING__:__ please take extreme care before enabling the 'decode_php_objs' option: when php objects are rebuilt from +the received xml, their constructor function will be silently invoked. This means that you are allowing the remote end +to trigger execution of uncontrolled PHP code on your server, opening the door to code injection exploits. Only +enable this option when you trust completely the remote server/client. DO NOT USE THIS WITH UNTRUSTED USER INPUT + +Note also that there are multiple limitations to this: the same PHP class definition must be available on both ends of +the communication; the class constructor will be called but with no parameters at all, and methods such as `__unserialize` +or `__wakeup` will not be called. Also, if a different toolkit than the phpxmlrpc library is used on the receiving side, +it might reject the generated xml as invalid. === Code generation, Proxy objects & co. @@ -1153,7 +1096,7 @@ For the extremely lazy coder, helper functions have been added that allow to con and a remotely exposed xmlrpc method into a local php function - or a set of xmlrpc methods into a php class. Note that these come with many caveat. [[wrap_xmlrpc_method]] -===== wrap_xmlrpc_method +==== wrap_xmlrpc_method string wrap_xmlrpc_method($client, $methodname, $extra_options) @@ -1246,7 +1189,7 @@ else { } ---- -===== wrap_php_function [[wrap_php_function]] +==== wrap_php_function [[wrap_php_function]] array wrap_php_function(string $funcname, string $wrapper_function_name, array $extra_options) @@ -1497,7 +1440,7 @@ To find out what the server is really returning to your client, you have to enab If what you need is to save the responses received from the server as xml, you have two options: -1- use the serialize() method on the response object. +1- use the `serialize` method on the Response object. [source, php] ---- @@ -1528,6 +1471,10 @@ protocol will be checked. This means that xmlrpc responses sent by the server th response on the client (e.g. malformed xml, responses that have faultCode set, etc...) now will not be flagged as invalid, and you might end up saving not valid xml but random junk... +3 - use the Response's `httpResponse` method + +@TODO... + === Can I use the MS Windows character set? If the data your application is using comes from a Microsoft application, there are some chances that the character set @@ -1535,7 +1482,7 @@ used to encode it is CP1252 (the same might apply to data received from an exter rare to find xmlrpc toolkits that encode to CP1252 instead of UTF8). It is a character set which is "almost" compatible with ISO 8859-1, but for a few extra characters. -PHP-XMLRPC only supports the ISO 8859-1 and UTF8 character sets. +PHPXMLRPC only supports the ISO 8859-1 and UTF8 character sets. The net result of this situation is that those extra characters will not be properly encoded, and will be received at the other end of the XML-RPC transmission as "garbled data". Unfortunately the library cannot provide real support for CP1252 because of limitations in the PHP 4 xml parser. Luckily, we tried our best to support this character set anyway, @@ -1622,10 +1569,10 @@ because of shared hosting constraints). Since version 2.1, the PHP-XMLRPC library provides a compatibility layer that aims to be 100% compliant with the xmlrpc extension API. This means that any code written to run on the extension should obtain the exact same results, albeit -using more resources and a longer processing time, using the PHP-XMLRPC library and the extension compatibility module. +using more resources and a longer processing time, using the PHPXMLRPC library and the extension compatibility module. The module was originally part of the EXTRAS package, available as a separate download from the sourceforge.net website; -it has since become available aa Packagist package `phpxmlrpc/polyfill-xmlrpc ` and can be found on GitHub at +it has since become available as Packagist package `phpxmlrpc/polyfill-xmlrpc` and can be found on GitHub at https://github.com/gggeek/polyfill-xmlrpc ++++++++++++++++++++++++++++++++++++++ diff --git a/extras/benchmark.php b/extras/benchmark.php index ae937541..3e0930ba 100644 --- a/extras/benchmark.php +++ b/extras/benchmark.php @@ -1,6 +1,6 @@ ' with ']]]]>') diff --git a/src/Helper/XMLParser.php b/src/Helper/XMLParser.php index 06c16aa0..6ccfb34f 100644 --- a/src/Helper/XMLParser.php +++ b/src/Helper/XMLParser.php @@ -672,6 +672,7 @@ class XMLParser } // 4 - if mbstring is available, let it do the guesswork + /// @todo replace with function_exists if (extension_loaded('mbstring')) { if ($encodingPrefs == null && PhpXmlRpc::$xmlrpc_detectencodings != null) { $encodingPrefs = PhpXmlRpc::$xmlrpc_detectencodings; diff --git a/src/Request.php b/src/Request.php index b7e0906d..39273cf0 100644 --- a/src/Request.php +++ b/src/Request.php @@ -312,6 +312,7 @@ class Request // The following code might be better for mb_string enabled installs, but makes the lib about 200% slower... //if (!is_valid_charset($respEncoding, array('UTF-8'))) if (!in_array($respEncoding, array('UTF-8', 'US-ASCII')) && !XMLParser::hasEncoding($data)) { + /// @todo replace with function_exists if (extension_loaded('mbstring')) { $data = mb_convert_encoding($data, 'UTF-8', $respEncoding); } else { diff --git a/src/Server.php b/src/Server.php index 7debd2c5..05161dce 100644 --- a/src/Server.php +++ b/src/Server.php @@ -557,6 +557,7 @@ class Server // makes the lib about 200% slower... //if (!is_valid_charset($reqEncoding, array('UTF-8'))) if (!in_array($reqEncoding, array('UTF-8', 'US-ASCII')) && !XMLParser::hasEncoding($data)) { + /// @todo replace with function_exists if (extension_loaded('mbstring')) { $data = mb_convert_encoding($data, 'UTF-8', $reqEncoding); } else { diff --git a/src/Wrapper.php b/src/Wrapper.php index eec2554c..7b3968fe 100644 --- a/src/Wrapper.php +++ b/src/Wrapper.php @@ -10,7 +10,7 @@ namespace PhpXmlRpc; use PhpXmlRpc\Helper\Logger; /** - * PHP-XMLRPC "wrapper" class - generate stubs to transparently access xmlrpc methods as php functions and vice-versa. + * PHPXMLRPC "wrapper" class - generate stubs to transparently access xmlrpc methods as php functions and vice-versa. * Note: this class implements the PROXY pattern, but it is not named so to avoid confusion with http proxies. * * @todo use some better templating system for code generation?