* changed: the minimum php version required has increased to 5.4
+* changed: dropped support for parsing cookie headers which follow the obsolete "version 2" specification
+
* new: allow to specify other charsets than the canonical three (UTF-8, ISO-8859-1, ASCII), when mbstring is
- available, both for outgoing and incoming data.
+ available, both for outgoing and incoming data (issue #42).
For outgoing data, this can be set in `$client->request_charset_encoding` and `$server->response_charset_encoding`.
The library will then transcode the data fed to it by the application into the desired charset when serializing
on to the application. The same will apply for elements of type struct-member which miss either the name or the value
* new: it is now possible to tell the library to allow non-standard formats for received datetime value, such as f.e.
- datetimes with a timezone specifier, by setting a custom value to `PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format`.
+ datetimes with a timezone specifier, by setting a custom value to `PhpXmlRpc\PhpXmlRpc::$xmlrpc_datetime_format`
+ (issue #46).
* new: it is now possible to tell the library to allow non-standard formats for received int and float values, as well
as for methdoname elements. See the api docs for `PhpXmlRpc\PhpXmlRpc` static variables.
-* improved: limit the size of incoming data which will be used in error responses and logged error messages, making
- it slightly harder to carry out DOS attacks against the library
-
* fixed: when a server is configured with its default value of 'xmlrpcvals' for `$functions_parameters_type`, and
a method handler in the dispatch was defined with `'parameters_type' = 'phpvals'`, the handler would be passed a
Request object instead of plain php values.
* new: method `Server::setDispatchMap()`
* new: it is now possible to inject a custom logger into helper classes `Charset`, `Http`, `XMLParser`, inching a step
- closer to supporting DIC patterns
+ closer to supporting DIC patterns (issue #78)
* new: method `PhpXmlRpc::setLogger()`, to simplify injecting the logger into all classes of the library in one step
+* improved: the `Logger` class now sports methods adhering to Psr\Log\LoggerInterface
+
+* improved: made sure all debug output goes through the logger at response parsing time (there was one printf call left)
+
+* improved: limit the size of incoming data which will be used in error responses and logged error messages, making
+ it slightly harder to carry out DOS attacks against the library
+
* new: passing value -1 to `$client->setDebug` will avoid storing the full http response data in the returned Response
object when executing `call`. This could be useful in reducing memory usage for big responses
* new: methods `Wrapper::holdObject()` and `Wrapper::getheldObject()`, allowing flexibility in storing object instances
for code-generation scenarios involving `Wrapper::wrapPhpClass` and `Wrapper::wrapPhpFunction`
-* improved: the `Logger` class now sports methods adhering to Psr\Log\LoggerInterface
-
-* improved: made sure all debug output goes through the logger at response parsing time (there was one printf call left)
+* improved: all `Value` methods now follow snakeCase convention
* improved: all the Exceptions thrown by the library are now `\PhpXmlRpc\Exception` or subclasses thereof
* new: method `Helper\Date::iso8601Encode` now accepts a DateTime input beside a timestamp
-* new: in the dispatch map, it is now possible to set different exception handling modes for each expose xml-rpc method
+* new: in the dispatch map, it is now possible to set different exception handling modes for each exposed xml-rpc method
* new: method `Server::add_to_map` has acquired new parameters: `$parametersType = false, $exceptionHandling = false`
* improved: the `XMLParser` accepts more options in its constructor (see phpdocs for details)
-* improved: dropped support for parsing cookie headers which follow the obsolete "version 2" specification
-
* improved: removed usage of `extension_loaded` in favour of `function_exists` when checking for mbstring. This allows
for mbstring functions to be polyfilled
* improved: made sure the test container and gha test runners have at least one locale with comma as decimal separator
-* BC notes:
+* BC notes (besides what can be inferred from the changes listed above):
for library users
- an error message will now be generated if, in incoming data, a STRUCT element has no NAME
- parameters `$timeout` and `$method` are now considered deprecated in `Client::send()` and `Client::multicall()`
- Client properties `$errno` and `$errstring` are now deprecated
+ - direct access to all properties of Client and Server is now deprecated and should be replaced by calls to
+ `setOption` and `getOption`. The same applies to a few "setter" methods of the Client
- direct access to `Wrapper::$objHolder` is now deprecated
- the code generated by the debugger when using "Generate stub for method call" will throw on errors instead of
returning a Response object
/**
* @param string $path either the PATH part of the xml-rpc server URL, or complete server URL (in which case you
- * should use and empty string for all other parameters)
+ * should use an empty string for all other parameters)
* e.g. /xmlrpc/server.php
* e.g. http://phpxmlrpc.sourceforge.net/server.php
* e.g. https://james:bond@secret.service.com:444/xmlrpcserver?agent=007
{
/// @todo log a warning if passed an unsupported method
- if ($port == 0) {
- $port = ($method === 'https') ? 443 : 80;
- }
-
// Only create the payload if it was not created previously
/// @todo what if the request's payload was created with a different encoding?
if (empty($req->payload)) {
$req->serialize($this->request_charset_encoding);
}
-
$payload = $req->payload;
+
// Deflate request body and set appropriate request headers
$encodingHdr = '';
if (function_exists('gzdeflate') && ($this->request_compression == 'gzip' || $this->request_compression == 'deflate')) {
$acceptedEncoding = 'Accept-Encoding: ' . implode(', ', $this->accepted_compression) . "\r\n";
}
+ if ($port == 0) {
+ $port = ($method === 'https') ? 443 : 80;
+ }
+
$proxyCredentials = '';
if ($proxyHost) {
if ($proxyPort == 0) {
}
/** @var Value $code */
$code = $val['faultCode'];
- if ($code->kindOf() != 'scalar' || $code->scalartyp() != 'int') {
+ if ($code->kindOf() != 'scalar' || $code->scalarTyp() != 'int') {
return new Response(0, PhpXmlRpc::$xmlrpcerr['multicall_error'],
PhpXmlRpc::$xmlrpcstr['multicall_error'] . ": response element $i has invalid or no faultCode",
'xmlrpcvals', $result->httpResponse());
}
/** @var Value $str */
$str = $val['faultString'];
- if ($str->kindOf() != 'scalar' || $str->scalartyp() != 'string') {
+ if ($str->kindOf() != 'scalar' || $str->scalarTyp() != 'string') {
return new Response(0, PhpXmlRpc::$xmlrpcerr['multicall_error'],
PhpXmlRpc::$xmlrpcstr['multicall_error'] . ": response element $i has invalid or no faultCode",
'xmlrpcvals', $result->httpResponse());
}
- $response[] = new Response(0, $code->scalarval(), $str->scalarval(), 'xmlrpcvals', $result->httpResponse());
+ $response[] = new Response(0, $code->scalarVal(), $str->scalarVal(), 'xmlrpcvals', $result->httpResponse());
break;
default:
return new Response(0, PhpXmlRpc::$xmlrpcerr['multicall_error'],
return $val;
}
}
- if (in_array('dates_as_objects', $options) && $xmlrpcVal->scalartyp() == 'dateTime.iso8601') {
+ if (in_array('dates_as_objects', $options) && $xmlrpcVal->scalarTyp() == 'dateTime.iso8601') {
// we return a Datetime object instead of a string; since now the constructor of xml-rpc value accepts
// safely string, int and DateTimeInterface, we cater to all 3 cases here
- $out = $xmlrpcVal->scalarval();
+ $out = $xmlrpcVal->scalarVal();
if (is_string($out)) {
$out = strtotime($out);
// NB: if the string does not convert into a timestamp, this will return false.
return $out;
}
}
- return $xmlrpcVal->scalarval();
+ return $xmlrpcVal->scalarVal();
case 'array':
$arr = array();
$vc = $v['faultCode'];
/** @var Value $vs */
$vs = $v['faultString'];
- $r = new Response(0, $vc->scalarval(), $vs->scalarval());
+ $r = new Response(0, $vc->scalarVal(), $vs->scalarVal());
} else {
$r = new Response($v);
}
$v = $xmlRpcParser->_xh['value'];
// use a known error code
/** @var Value $vc */
- $vc = isset($v['faultCode']) ? $v['faultCode']->scalarval() : PhpXmlRpc::$xmlrpcerr['invalid_return'];
+ $vc = isset($v['faultCode']) ? $v['faultCode']->scalarVal() : PhpXmlRpc::$xmlrpcerr['invalid_return'];
/** @var Value $vs */
- $vs = isset($v['faultString']) ? $v['faultString']->scalarval() : '';
+ $vs = isset($v['faultString']) ? $v['faultString']->scalarVal() : '';
if (!is_int($vc) || $vc == 0) {
$vc = PhpXmlRpc::$xmlrpcerr['invalid_return'];
}
case 'I8':
case 'INT':
// NB: we build the Value object with the original xml element name found, except for ex:i8. The
- // `Value::scalartyp()` function will do some normalization of the data
+ // `Value::scalarTyp()` function will do some normalization of the data
$this->_xh['vt'] = strtolower($name);
$this->_xh['lv'] = 3; // indicate we've found a value
if (!preg_match(PhpXmlRpc::$xmlrpc_int_format, $this->_xh['ac'])) {
if ($returnType == XMLParser::RETURN_XMLRPCVALS) {
$errNo_v = $v['faultCode'];
$errStr_v = $v['faultString'];
- $errNo = $errNo_v->scalarval();
- $errStr = $errStr_v->scalarval();
+ $errNo = $errNo_v->scalarVal();
+ $errStr = $errStr_v->scalarVal();
} else {
$errNo = $v['faultCode'];
$errStr = $v['faultString'];
if (is_object($in)) {
$p = $in->getParam($n);
if ($p->kindOf() == 'scalar') {
- $pt = $p->scalartyp();
+ $pt = $p->scalarTyp();
} else {
$pt = $p->kindOf();
}
// let's accept as parameter either an xml-rpc value or string
if (is_object($req)) {
$methName = $req->getParam(0);
- $methName = $methName->scalarval();
+ $methName = $methName->scalarVal();
} else {
$methName = $req;
}
// let's accept as parameter either an xml-rpc value or string
if (is_object($req)) {
$methName = $req->getParam(0);
- $methName = $methName->scalarval();
+ $methName = $methName->scalarVal();
} else {
$methName = $req;
}
if (!$methName) {
return static::_xmlrpcs_multicall_error('nomethod');
}
- if ($methName->kindOf() != 'scalar' || $methName->scalartyp() != 'string') {
+ if ($methName->kindOf() != 'scalar' || $methName->scalarTyp() != 'string') {
return static::_xmlrpcs_multicall_error('notstring');
}
- if ($methName->scalarval() == 'system.multicall') {
+ if ($methName->scalarVal() == 'system.multicall') {
return static::_xmlrpcs_multicall_error('recursion');
}
return static::_xmlrpcs_multicall_error('notarray');
}
- $req = new Request($methName->scalarval());
+ $req = new Request($methName->scalarVal());
foreach ($params as $i => $param) {
if (!$req->addParam($param)) {
$i++; // for error message, we count params from 1
return 0;
case 2:
// we're adding a scalar value to an array here
-/// @todo do not re-wrap Value objects
+ /// @todo should we try avoiding re-wrapping Value objects?
$class = get_class($this);
$this->me['array'][] = new $class($val, $type);
*
* @deprecated this should be folded back into serialize()
*/
- protected function serializedata($typ, $val, $charsetEncoding = '')
+ protected function serializeData($typ, $val, $charsetEncoding = '')
{
$rs = '';
$val = reset($this->me);
$typ = key($this->me);
- return '<value>' . $this->serializedata($typ, $val, $charsetEncoding) . "</value>\n";
+ return '<value>' . $this->serializeData($typ, $val, $charsetEncoding) . "</value>\n";
}
/**
*
* @deprecated use array access, e.g. isset($val[$key])
*/
- public function structmemexists($key)
+ public function structMemExists($key)
{
//trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
*
* @deprecated use array access, e.g. $val[$key]
*/
- public function structmem($key)
+ public function structMem($key)
{
//trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
*
* @deprecated iterate directly over the object using foreach instead
*/
- public function structreset()
+ public function structReset()
{
//trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
*
* @deprecated iterate directly over the object using foreach instead
*/
- public function structeach()
+ public function structEach()
{
//trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
*
* @return mixed
*/
- public function scalarval()
+ public function scalarVal()
{
$b = reset($this->me);
* @return string For integers, 'int' is always returned in place of 'i4'. 'i8' is considered a separate type and
* returned as such
*/
- public function scalartyp()
+ public function scalarTyp()
{
reset($this->me);
$a = key($this->me);
*
* @deprecated use array access, e.g. $val[$key]
*/
- public function arraymem($key)
+ public function arrayMem($key)
{
//trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
*
* @deprecated use count() instead
*/
- public function arraysize()
+ public function arraySize()
{
//trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
*
* @deprecated use count() instead
*/
- public function structsize()
+ public function structSize()
{
//trigger_error('Method ' . __METHOD__ . ' is deprecated', E_USER_DEPRECATED);
return;
case 1:
/// @todo: should we handle usage of i4 to retrieve int (in both set/unset/isset)? After all we consider
- /// 'int' to be the preferred form, as evidenced in scalartyp()
+ /// 'int' to be the preferred form, as evidenced in scalarTyp()
reset($this->me);
$type = key($this->me);
if ($type != $offset && ($type != 'i4' || $offset != 'int')) {
reset($this->me);
return $offset == key($this->me);
} else {
- return $offset == $this->scalartyp();
+ return $offset == $this->scalarTyp();
}
default:
return false;
if (!$response->faultCode()) {
$mDesc = $response->value();
if ($client->return_type != 'phpvals') {
- $mDesc = $mDesc->scalarval();
+ $mDesc = $mDesc->scalarVal();
}
}