* changed: dropped support for parsing cookie headers which follow the obsolete Cookie2 specification
+* new: it is now possible to make the library generate warning messages whenever a deprecated feature is used, such as
+ calling deprecated methods, using deprecated method parameters, or reading/writing deprecated object properties.
+ This is disabled by default, and can be enabled by setting `PhpXmlRpc\PhpXmlRpc::xmlrpc_silence_deprecations = false`.
+ Note that the deprecation warnings will be by default added to the php error log, and not be displayed on screen.
+ If you prefer them to be handled in some other way, you should take over the Logger, as described below here
+
* 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 (issue #42).
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.
+* fixed: made sure all debug output goes through the logger at response parsing time (there was one printf call left)
+
* fixed: when calling `Client::multicall()` with `$client->return_type = 'xml'`, the code would be always falling back to
non-multicall requests
* new: added methods `getOption`, `setOption`, `setOptions` and `getOptions` to both Client and Server, meant to replace
direct access to _all public properties_ as well as the `$timeout` argument in calls to `Client::send` and `Client::multicall`
-* new: it is now possible to make the library generate warning messages whenever a deprecated feature is used, such as
- calling deprecated methods, using deprecated method parameters, or reading/writing deprecated object properties.
- This is disabled by default, and can be enabled by setting `PhpXmlRpc\PhpXmlRpc::xmlrpc_silence_deprecations = false`.
- Note that the deprecation warnings will be by default added to the php error log, and not be displayed on screen.
- If you prefer them to be handled in some other way, you should take over the Logger, as described just below here
-
* new: it is now possible to inject a custom logger into helper classes `Charset`, `Http`, `XMLParser`, inching a step
closer to supporting DIC patterns (issue #78)
* 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
* improved: made sure the test container and gha test runners have at least one locale with comma as decimal separator
-* BC notes (besides what can be inferred from the changes listed above):
+* BC notes:
+
+ *NB* Given the considerable amount of API changes in this release, a set of tables listing every change has been
+ added in doc/api_changes_v4.10.md; a textual description follows.
- for library users
+ Besides what can be inferred from the changes listed above, for library users:
- the data passed to the application is not encoded anymore in UTF-8 when setting `PhpXmlRpc::$internal_encoding`
to a custom character set and the mbstring extension is enabled. It will be encoded instead in the specified character
- the code generated by the debugger when using "Generate stub for method call" will throw on errors instead of
returning a Response object
- for library extenders
+ For library extenders:
- the `$options` argument passed to `XMLParser::parse` will now contain both options intended to be passed down to
the php xml parser, and further options used to tweak the parsing results. If you have subclassed `XMLParser`
- new methods in helper classes: `Charset::knownCharsets`, `Http::parseAcceptHeader`, `XMLParser::truncateValueForLog`
- exception `\PhpXmlRpc\Exception\PhpXmlRpcException` is deprecated. Use `\PhpXmlRpc\Exception` instead
+
## XML-RPC for PHP version 4.9.5 - 2023/01/11
* improved: revised all demo files. Showcase more features in client demos; isolate better testsuite functions in
--- /dev/null
+API Changes between library versions 4.9 and 4.10
+=================================================
+
+While 4.10 keeps the usual BC promise with previous 4.x releases, it also paves the way for all the API changes foreseen
+to happen in future version 5.
+
+In particular, API cleanups mean that most public access to object properties has been replaced by dedicated methods.
+
+New classes, traits, exceptions
+-------------------------------
+
+For the first time, usage of custom exceptions is in place. Traits are also in use for sharing common functionality.
+
+| Type | Name | Notes |
+|-----------|-------------------------------|---------------------------------------------------------------------|
+| exception | PhpXmlRpc\Exception | Parent class for all exceptions thrown by the library. |
+| | | Its alias PhpXmlRpc\Exception\PhpXmlRpcException is still in place. |
+| exception | PhpXmlRpc\Exception\... | See the list in the appendix of the user manual |
+| trait | PhpXmlRpc\CharsetEncoderAware | |
+| trait | PhpXmlRpc\Server | |
+| trait | PhpXmlRpc\DeprecationLogger | |
+| trait | PhpXmlRpc\ParserAware | |
+| trait | PhpXmlRpc\PayloadBearer | |
+
+New class methods
+-----------------
+
+In case you had extended the classes of the library and added methods to the subclasses, you might find that your
+implementation clashes with the new one if you implemented:
+
+| Class | Method | Notes |
+|-----------|---------------------|-----------|
+| * | __get | |
+| * | __isset | |
+| * | __set | |
+| * | __unset | |
+| Charset | getLogger | |
+| Charset | knownCharsets | |
+| Charset | setLogger | static |
+| Client | getOption | |
+| Client | getOptions | |
+| Client | getUrl | |
+| Client | setOption | |
+| Client | setOptions | |
+| Http | getLogger | |
+| Http | parseAcceptHeader | |
+| Http | setLogger | static |
+| Logger | debug | |
+| Logger | error | |
+| Logger | warning | |
+| PhpXmlRpc | setLogger | static |
+| PhpXmlRpc | useInteropFaults | static |
+| Request | getContentType | |
+| Request | getPayload | |
+| Response | getContentType | |
+| Response | getPayload | |
+| Response | valueType | |
+| Response | xml_header | |
+| Server | getOption | |
+| Server | getOptions | |
+| Server | setDispatchMap | |
+| Server | setOption | |
+| Server | setOptions | |
+| Wrapper | getHeldObject | |
+| Wrapper | holdObject | |
+| XMLParser | getLogger | |
+| XMLParser | setLogger | static |
+| XMLParser | truncateValueForLog | protected |
+
+New class properties
+--------------------
+
+| Class | Property | Default value | Notes |
+|-----------|----------|---------------|-----------|
+| Client | $timeout | 0 | protected |
+
+New static properties
+---------------------
+
+| Class | Property | Default value | Notes |
+|-----------|-------------------------------|---------------------|-----------|
+| Client | $options | see code | protected |
+| Client | $requestClass | \PhpXmlRpc\Request | protected |
+| Client | $responseClass | \PhpXmlRpc\Response | protected |
+| PhpXmlRpc | $xmlrpc_datetime_format | see code | |
+| PhpXmlRpc | $xmlrpc_double_format | see code | |
+| PhpXmlRpc | $xmlrpc_int_format | see code | |
+| PhpXmlRpc | $xmlrpc_methodname_format | see code | |
+| PhpXmlRpc | $xmlrpc_reject_invalid_values | false | |
+| PhpXmlRpc | $xmlrpc_return_datetimes | false | |
+| PhpXmlRpc | $xmlrpc_silence_deprecations | true | |
+
+New constants
+-------------
+
+| Class | Constant | Notes |
+|--------|----------|-----------------------|
+| Client | OPT_* | see code for the list |
+| Server | OPT_* | see code for the list |
+
+Changed methods
+---------------
+
+The following methods acquired new parameters, or accept a wider range of values for existing parameters
+
+| Class | Method | Notes |
+|-----------|----------|-------|
+| PhpXmlRpc | $xmlrpc_ | |
+
+Deprecated methods
+---------------------
+
+| Class | Method | Replacement |
+|---------|-----------------------|----------------------|
+| Charset | isValidCharset | - |
+| Client | prepareCurlHandle | createCURLHandle |
+| Client | sendPayloadCurl | sendViaCURL |
+| Client | sendPayloadSocket | sendViaSocket |
+| Client | setCurlOptions | setOption |
+| Client | setRequestCompression | setOption |
+| Client | setSSLVerifyHost | setOption |
+| Client | setSSLVerifyPeer | setOption |
+| Client | setSSLVersion | setOption |
+| Client | setUseCurl | setOption |
+| Client | setUserAgent | setOption |
+| Server | xml_header | Response::xml_header |
+| Value | serializeData | - |
+
+Deprecated properties
+---------------------
+
+The following properties have now protected access. Replacement accessor for public use are listed.
+
+| Class | Property | Read via | Write via |
+|----------|----------------------------|------------------------|----------------------------------|
+| Client | accepted_charset_encodings | getOption | setOption |
+| Client | accepted_compression | getOption | setOption/setAcceptedCompression |
+| Client | authtype | getOption | setOption/setCredentials |
+| Client | cacert | getOption | setOption/setCaCertificate |
+| Client | cacertdir | getOption | setOption/setCaCertificate |
+| Client | cert | getOption | setOption/setCertificate |
+| Client | certpass | getOption | setOption/setCertificate |
+| Client | cookies | getOption | setOption |
+| Client | debug | getOption | setOption/setDebug |
+| Client | errno | - | - |
+| Client | errstr | - | - |
+| Client | extracurlopts | getOption | setOption |
+| Client | keepalive | getOption | setOption |
+| Client | key | getOption | setOption/setKey |
+| Client | keypass | getOption | setOption/setKey |
+| Client | method | getUrl | __construct |
+| Client | no_multicall | getOption | setOption |
+| Client | password | getOption | setOption/setCredentials |
+| Client | path | getUrl | __construct |
+| Client | port | getUrl | __construct |
+| Client | proxy | getOption | setOption/setProxy |
+| Client | proxy_authtype | getOption | setOption/setProxy |
+| Client | proxy_pass | getOption | setOption/setProxy |
+| Client | proxy_user | getOption | setOption/setProxy |
+| Client | proxyport | getOption | setOption/setProxy |
+| Client | request_charset_encoding | getOption | setOption |
+| Client | request_compression | getOption | setOption |
+| Client | return_type | getOption | setOption |
+| Client | server | getUrl | __construct |
+| Client | sslversion | getOption | setOption |
+| Client | use_curl | getOption | setOption |
+| Client | user_agent | getOption | setOption |
+| Client | username | getOption | setOption/setCredentials |
+| Client | verifyhost | getOption | setOption |
+| Client | verifypeer | getOption | setOption |
+| Request | content_type | getContentType | setPayload |
+| Request | debug | setDebug | - |
+| Request | methodname | method | __construct/method |
+| Request | params | getParam | __construct/addParam |
+| Request | payload | getPayload | setPayload |
+| Response | val | value | __construct |
+| Response | valtyp | valueType | __construct |
+| Response | errno | faultCode | __construct |
+| Response | errstr | faultString | __construct |
+| Response | content_type | getContentType | setPayload |
+| Response | payload | getPayload | setPayload |
+| Server | accepted_charset_encodings | - | - |
+| Server | accepted_compression | getOption | setOption |
+| Server | allow_system_funcs | getOption | setOption |
+| Server | compress_response | getOption | setOption |
+| Server | debug | getOption | setOption/setDebug |
+| Server | exception_handling | getOption | setOption |
+| Server | functions_parameters_type | getOption | setOption |
+| Server | phpvals_encoding_options | getOption | setOption |
+| Server | response_charset_encoding | getOption | setOption |
+| Value | _php_class | - | - |
+| Value | me | scalarVal/array access | __construct |
+| Value | mytype | kindOf | __construct |
+| Wrapper | $objectholder | getHeldObject | holdObject |
case 'dmap':
return $this->dmap;
default:
- $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
- trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' .
- $trace[0]['line'], E_USER_NOTICE);
- return null;
+ return parent::__get($name);
}
}
*/
public function __isset($name)
{
- return $name === 'dmap';
+ return $name === 'dmap' ? true : parent::__isset($name);
}
/// @todo what about __set, __unset?
namespace PhpXmlRpc;
-//use PhpXmlRpc\Helper\Charset;
use PhpXmlRpc\Exception\ValueErrorException;
use PhpXmlRpc\Helper\XMLParser;
+use PhpXmlRpc\Traits\CharsetEncoderAware;
use PhpXmlRpc\Traits\DeprecationLogger;
/**
* Used to represent a client of an XML-RPC server.
+ *
+ * @property int $errno deprecated - public access left in purely for BC.
+ * @property string $errstr deprecated - public access left in purely for BC.
+ * @property string $method deprecated - public access left in purely for BC. Access via getUrl()/__construct()
+ * @property string $server deprecated - public access left in purely for BC. Access via getUrl()/__construct()
+ * @property int $port deprecated - public access left in purely for BC. Access via getUrl()/__construct()
+ * @property string $path deprecated - public access left in purely for BC. Access via getUrl()/__construct()
*/
class Client
{
use DeprecationLogger;
+ //use CharsetEncoderAware;
const USE_CURL_NEVER = 0;
const USE_CURL_ALWAYS = 1;
* @var int
* @deprecated will be removed in the future
*/
- public $errno;
+ protected $errno;
/**
* @var string
* @deprecated will be removed in the future
*/
- public $errstr;
+ protected $errstr;
/// @todo: do all the ones below need to be public?
* @var string
* @internal use getUrl/__construct
*/
- public $method = 'http';
+ protected $method = 'http';
/**
* @var string
* @internal use getUrl/__construct
*/
- public $server;
+ protected $server;
/**
* @var int
* @internal use getUrl/__construct
*/
- public $port = 0;
+ protected $port = 0;
/**
* @var string
* @internal use getUrl/__construct
*/
- public $path;
+ protected $path;
/**
* @var int
* @internal use setOption/getOption
*/
- public $debug = 0;
+ protected $debug = 0;
/**
* @var string
* @internal use setCredentials/getOption
*/
- public $username = '';
+ protected $username = '';
/**
* @var string
* @internal use setCredentials/getOption
*/
- public $password = '';
+ protected $password = '';
/**
* @var int
* @internal use setCredentials/getOption
*/
- public $authtype = 1;
+ protected $authtype = 1;
/**
* @var string
* @internal use setCertificate/getOption
*/
- public $cert = '';
+ protected $cert = '';
/**
* @var string
* @internal use setCertificate/getOption
*/
- public $certpass = '';
+ protected $certpass = '';
/**
* @var string
* @internal use setCaCertificate/getOption
*/
- public $cacert = '';
+ protected $cacert = '';
/**
* @var string
* @internal use setCaCertificate/getOption
*/
- public $cacertdir = '';
+ protected $cacertdir = '';
/**
* @var string
* @internal use setKey/getOption
*/
- public $key = '';
+ protected $key = '';
/**
* @var string
* @internal use setKey/getOption
*/
- public $keypass = '';
+ protected $keypass = '';
/**
* @var bool
* @internal use setOption/getOption
*/
- public $verifypeer = true;
+ protected $verifypeer = true;
/**
* @var int
* @internal use setOption/getOption
*/
- public $verifyhost = 2;
+ protected $verifyhost = 2;
/**
* @var int
* @internal use setOption/getOption
*/
- public $sslversion = 0; // corresponds to CURL_SSLVERSION_DEFAULT
+ protected $sslversion = 0; // corresponds to CURL_SSLVERSION_DEFAULT
/**
* @var string
* @internal use setProxy/getOption
*/
- public $proxy = '';
+ protected $proxy = '';
/**
* @var int
* @internal use setProxy/getOption
*/
- public $proxyport = 0;
+ protected $proxyport = 0;
/**
* @var string
* @internal use setProxy/getOption
*/
- public $proxy_user = '';
+ protected $proxy_user = '';
/**
* @var string
* @internal use setProxy/getOption
*/
- public $proxy_pass = '';
+ protected $proxy_pass = '';
/**
* @var int
* @internal use setProxy/getOption
*/
- public $proxy_authtype = 1;
+ protected $proxy_authtype = 1;
/**
* @var array
* @internal use setCookie/getOption
*/
- public $cookies = array();
+ protected $cookies = array();
/**
* @var array
* @internal use setOption/getOption
*/
- public $extracurlopts = array();
+ protected $extracurlopts = array();
/**
* @var int
* @internal use setOption/getOption
*/
- public $timeout = 0;
+ protected $timeout = 0;
/**
* @var int
* @internal use setOption/getOption
*/
- public $use_curl = self::USE_CURL_AUTO;
+ protected $use_curl = self::USE_CURL_AUTO;
/**
* @var bool
*
*
* @internal use setOption/getOption
*/
- public $no_multicall = false;
+ protected $no_multicall = false;
/**
* @var array
*
*
* @internal use setAcceptedCompression/getOption
*/
- public $accepted_compression = array();
+ protected $accepted_compression = array();
/**
* @var string|null
*
*
* @internal use setOption/getOption
*/
- public $request_compression = '';
+ protected $request_compression = '';
/**
* @var bool
*
*
* @internal use setOption/getOption
*/
- public $keepalive = false;
+ protected $keepalive = false;
/**
* @var string[]
*
*
* @internal use setOption/getOption
*/
- public $accepted_charset_encodings = array();
+ protected $accepted_charset_encodings = array();
/**
* @var string
*
*
* @internal use setOption/getOption
*/
- public $request_charset_encoding = '';
+ protected $request_charset_encoding = '';
/**
* @var string
*
*
* @internal use setOption/getOption
*/
- public $return_type = XMLParser::RETURN_XMLRPCVALS;
+ protected $return_type = XMLParser::RETURN_XMLRPCVALS;
/**
* @var string
*
*
* @internal use setOption/getOption
*/
- public $user_agent;
+ protected $user_agent;
/**
* CURL handle: used for keep-alive
/**
* @var array
*/
- protected $options = array(
+ protected static $options = array(
self::OPT_ACCEPTED_CHARSET_ENCODINGS,
self::OPT_ACCEPTED_COMPRESSION,
self::OPT_AUTH_TYPE,
$this->accepted_charset_encodings = array('UTF-8', 'ISO-8859-1', 'US-ASCII');
// NB: this is disabled to avoid making all the requests sent huge... mbstring supports more than 80 charsets!
- //$ch = Charset::instance();
+ //$ch = $this->getCharsetEncoder();
//$this->accepted_charset_encodings = $ch->knownCharsets();
// initialize user_agent string
*/
public function setOption($name, $value)
{
- switch ($name) {
- case self::OPT_ACCEPTED_CHARSET_ENCODINGS:
- $this->accepted_charset_encodings = $value;
- break;
- case self::OPT_ACCEPTED_COMPRESSION:
- $this->accepted_compression = $value;
- break;
- case self::OPT_AUTH_TYPE:
- $this->authtype = $value;
- break;
- case self::OPT_CA_CERT:
- $this->cacert = $value;
- break;
- case self::OPT_CA_CERT_DIR:
- $this->cacertdir = $value;
- break;
- case self::OPT_CERT:
- $this->cert = $value;
- break;
- case self::OPT_CERT_PASS:
- $this->certpass = $value;
- break;
- case self::OPT_COOKIES:
- $this->cookies = $value;
- break;
- case self::OPT_DEBUG:
- $this->debug = $value;
- break;
- case self::OPT_EXTRA_CURL_OPTS:
- $this->extracurlopts = $value;
- break;
- case self::OPT_KEEPALIVE:
- $this->keepalive = $value;
- break;
- case self::OPT_KEY:
- $this->key = $value;
- break;
- case self::OPT_KEY_PASS:
- $this->keypass = $value;
- break;
- case self::OPT_NO_MULTICALL:
- $this->no_multicall = $value;
- break;
- case self::OPT_PASSWORD:
- $this->password = $value;
- break;
- case self::OPT_PROXY:
- $this->proxy = $value;
- break;
- case self::OPT_PROXY_AUTH_TYPE:
- $this->proxy_authtype = $value;
- break;
- case self::OPT_PROXY_PASS:
- $this->proxy_pass = $value;
- break;
- case self::OPT_PROXY_PORT:
- $this->proxyport = $value;
- break;
- case self::OPT_PROXY_USER:
- $this->proxy_user = $value;
- break;
- case self::OPT_REQUEST_CHARSET_ENCODING:
- $this->request_charset_encoding = $value;
- break;
- case self::OPT_REQUEST_COMPRESSION:
- $this->request_compression = $value;
- break;
- case self::OPT_RETURN_TYPE:
- $this->return_type = $value;
- break;
- case self::OPT_SSL_VERSION:
- $this->sslversion = $value;
- break;
- case self::OPT_TIMEOUT:
- $this->timeout = $value;
- break;
- case self::OPT_USERNAME:
- $this->username = $value;
- break;
- case self::OPT_USER_AGENT:
- $this->user_agent = $value;
- break;
- case self::OPT_USE_CURL:
- $this->use_curl = $value;
- break;
- case self::OPT_VERIFY_HOST:
- $this->verifyhost = $value;
- break;
- case self::OPT_VERIFY_PEER:
- $this->verifypeer = $value;
- break;
- default:
- throw new ValueErrorException("Unsupported option '$name'");
+ if (in_array($name, static::$options)) {
+ $this->$name = $value;
+ return $this;
}
- return $this;
+ throw new ValueErrorException("Unsupported option '$name'");
}
/**
*/
public function getOption($name)
{
- switch ($name) {
- case self::OPT_ACCEPTED_CHARSET_ENCODINGS:
- return $this->accepted_charset_encodings;
- case self::OPT_ACCEPTED_COMPRESSION:
- return $this->accepted_compression;
- case self::OPT_AUTH_TYPE:
- return $this->authtype;
- case self::OPT_CA_CERT:
- return $this->cacert;
- case self::OPT_CA_CERT_DIR:
- return $this->cacertdir;
- case self::OPT_CERT:
- return $this->cert;
- case self::OPT_CERT_PASS:
- return $this->certpass;
- case self::OPT_COOKIES:
- return $this->cookies;
- case self::OPT_DEBUG:
- return $this->debug;
- case self::OPT_EXTRA_CURL_OPTS:
- return $this->extracurlopts;
- case self::OPT_KEEPALIVE:
- return $this->keepalive;
- case self::OPT_KEY:
- return $this->key;
- case self::OPT_KEY_PASS:
- return $this->keypass;
- case self::OPT_NO_MULTICALL:
- return $this->no_multicall;
- case self::OPT_PASSWORD:
- return $this->password;
- case self::OPT_PROXY:
- return $this->proxy;
- case self::OPT_PROXY_AUTH_TYPE:
- return $this->proxy_authtype;
- case self::OPT_PROXY_PASS:
- return $this->proxy_pass;
- case self::OPT_PROXY_PORT:
- return $this->proxyport;
- case self::OPT_PROXY_USER:
- return $this->proxy_user;
- case self::OPT_REQUEST_CHARSET_ENCODING:
- return $this->request_charset_encoding;
- case self::OPT_REQUEST_COMPRESSION:
- return $this->request_compression;
- case self::OPT_RETURN_TYPE:
- return $this->return_type;
- case self::OPT_SSL_VERSION:
- return $this->sslversion;
- case self::OPT_TIMEOUT:
- return $this->timeout;
- case self::OPT_USERNAME:
- return $this->username;
- case self::OPT_USER_AGENT:
- return $this->user_agent;
- case self::OPT_USE_CURL:
- return $this->use_curl;
- case self::OPT_VERIFY_HOST:
- return $this->verifyhost;
- case self::OPT_VERIFY_PEER:
- return $this->verifypeer;
- default:
- throw new ValueErrorException("Unsupported option '$name'");
+ if (in_array($name, static::$options)) {
+ return $this->$name;
}
+
+ throw new ValueErrorException("Unsupported option '$name'");
}
/**
public function getOptions()
{
$values = array();
- foreach ($this->options as $opt) {
+ foreach (static::$options as $opt) {
$values[$opt] = $this->getOption($opt);
}
return $values;
* @param array $opts the keys/values match self::getOptions
* @return \CurlHandle|resource|false
*/
- protected function createCurlHandle($req, $method, $server, $port, $path, $opts)
+ protected function createCURLHandle($req, $method, $server, $port, $path, $opts)
{
if ($port == 0) {
if (in_array($method, array('http', 'http10', 'http11', 'h2c'))) {
{
$this->logDeprecationUnlessCalledBy('sendViaCURL');
- return $this->createCurlHandle($req, $method, $server, $port, $this->path, array(
+ return $this->createCURLHandle($req, $method, $server, $port, $this->path, array(
'accepted_charset_encodings' => $this->accepted_charset_encodings,
'accepted_compression' => $this->accepted_compression,
'authtype' => $authType,
'verifypeer' => $this->verifypeer,
));
}
+
+ // we have to make this return by ref in order to allow calls such as `$resp->_cookies['name'] = ['value' => 'something'];`
+ public function &__get($name)
+ {
+ if (in_array($name, static::$options)) {
+ $this->logDeprecation('Getting property Client::' . $name . ' is deprecated');
+ return $this->$name;
+ }
+
+ switch ($name) {
+ case 'errno':
+ case 'errstr':
+ case 'method':
+ case 'server':
+ case 'port':
+ case 'path':
+ $this->logDeprecation('Getting property Client::' . $name . ' is deprecated');
+ return $this->$name;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ $result = null;
+ return $result;
+ }
+ }
+
+ public function __set($name, $value)
+ {
+ if (in_array($name, static::$options)) {
+ $this->logDeprecation('Setting property Client::' . $name . ' is deprecated');
+ $this->$name = $value;
+ return;
+ }
+
+ switch ($name) {
+ case 'errno':
+ case 'errstr':
+ case 'method':
+ case 'server':
+ case 'port':
+ case 'path':
+ $this->logDeprecation('Setting property Client::' . $name . ' is deprecated');
+ $this->$name = $value;
+ return;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __set(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ }
+ }
+
+ public function __isset($name)
+ {
+ if (in_array($name, static::$options)) {
+ $this->logDeprecation('Checking property Client::' . $name . ' is deprecated');
+ return isset($this->$name);
+ }
+
+ switch ($name) {
+ case 'errno':
+ case 'errstr':
+ case 'method':
+ case 'server':
+ case 'port':
+ case 'path':
+ $this->logDeprecation('Checking property Client::' . $name . ' is deprecated');
+ return isset($this->$name);
+ default:
+ return false;
+ }
+ }
+
+ public function __unset($name)
+ {
+ if (in_array($name, static::$options)) {
+ $this->logDeprecation('Unsetting property Client::' . $name . ' is deprecated');
+ unset($this->$name);
+ return;
+ }
+
+ switch ($name) {
+ case 'errno':
+ case 'errstr':
+ case 'method':
+ case 'server':
+ case 'port':
+ case 'path':
+ $this->logDeprecation('Unsetting property Client::' . $name . ' is deprecated');
+ unset($this->$name);
+ return;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __unset(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ }
+ }
}
* @todo if iconv() or mb_string() are available, we could allow to convert the received xml to a custom charset encoding
* while parsing, which is faster than doing it later by going over the rebuilt data structure
* @todo rename? This is an xml-rpc parser, not a generic xml parser...
+ *
+ * @property array $xmlrpc_valid_parents deprecated - public access left in purely for BC
+ * @property int $accept deprecated - (protected) access left in purely for BC
*/
class XMLParser
{
/**
* @var array[]
- * @internal
*/
- public $xmlrpc_valid_parents = array(
+ protected $xmlrpc_valid_parents = array(
'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'),
'BOOLEAN' => array('VALUE'),
'I4' => array('VALUE'),
$this->xmlrpc_se($parser, $name, $attrs, true);
}
+ public function &__get($name)
+ {
+ switch ($name) {
+ case 'xmlrpc_valid_parents':
+ $this->logDeprecation('Getting property XMLParser::' . $name . ' is deprecated');
+ return $this->$name;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ $result = null;
+ return $result;
+ }
+ }
+
public function __set($name, $value)
{
switch ($name) {
$this->logDeprecation('Setting property XMLParser::' . $name . ' is deprecated');
$this->current_parsing_options['accept'] = $value;
break;
+ case 'xmlrpc_valid_parents':
+ $this->logDeprecation('Setting property XMLParser::' . $name . ' is deprecated');
+ $this->$name = $value;
+ break;
default:
/// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
case 'accept':
$this->logDeprecation('Checking property XMLParser::' . $name . ' is deprecated');
return isset($this->current_parsing_options['accept']);
+ case 'xmlrpc_valid_parents':
+ $this->logDeprecation('Checking property XMLParser::' . $name . ' is deprecated');
+ return isset($this->$name);
default:
return false;
}
$this->logDeprecation('Unsetting property XMLParser::' . $name . ' is deprecated');
unset($this->current_parsing_options['accept']);
break;
+ case 'xmlrpc_valid_parents':
+ $this->logDeprecation('Unsetting property XMLParser::' . $name . ' is deprecated');
+ unset($this->$name);
+ break;
default:
/// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
{
$reflection = new \ReflectionClass('PhpXmlRpc\PhpXmlRpc');
foreach ($reflection->getStaticProperties() as $name => $value) {
- $GLOBALS[$name] = $value;
+ if (!in_array($name, array('xmlrpc_return_datetimes', 'xmlrpc_reject_invalid_values', 'xmlrpc_datetime_format',
+ 'xmlrpc_int_format', 'xmlrpc_double_format', 'xmlrpc_methodname_format', 'xmlrpc_silence_deprecations'))) {
+ $GLOBALS[$name] = $value;
+ }
}
// NB: all the variables exported into the global namespace below here do NOT guarantee 100% compatibility,
}
}
+ /// @todo mke it possible to inject the XMLParser and Charset, as we do in other classes
+
$parser = new Helper\XMLParser();
- $reflection = new \ReflectionClass('PhpXmlRpc\Helper\XMLParser');
- foreach ($reflection->getProperties(\ReflectionProperty::IS_PUBLIC) as $name => $value) {
- if (in_array($value->getName(), array('xmlrpc_valid_parents')))
- {
- $GLOBALS[$value->getName()] = $value->getValue($parser);
- }
- }
+ $GLOBALS['xmlrpc_valid_parents'] = $parser->xmlrpc_valid_parents;
$charset = Charset::instance();
$GLOBALS['xml_iso88591_Entities'] = $charset->getEntities('iso88591');
* @return void
*
* @deprecated
+ *
+ * @todo this function does not import back xmlrpc_valid_parents and xml_iso88591_Entities
*/
public static function importGlobals()
{
$reflection = new \ReflectionClass('PhpXmlRpc\PhpXmlRpc');
- $staticProperties = $reflection->getStaticProperties();
- foreach ($staticProperties as $name => $value) {
- if (isset($GLOBALS[$name])) {
- self::$$name = $GLOBALS[$name];
+ foreach ($reflection->getStaticProperties() as $name => $value) {
+ if (!in_array($name, array('xmlrpc_return_datetimes', 'xmlrpc_reject_invalid_values', 'xmlrpc_datetime_format',
+ 'xmlrpc_int_format', 'xmlrpc_double_format', 'xmlrpc_methodname_format', 'xmlrpc_silence_deprecations')))
+ {
+ if (isset($GLOBALS[$name])) {
+ self::$$name = $GLOBALS[$name];
+ }
}
}
}
* A client sends a PhpXmlrpc\Request to a server, and receives back an PhpXmlrpc\Response.
*
* @todo feature creep - add a protected $httpRequest member, in the same way the Response has one
+ *
+ * @property string $methodname deprecated - public access left in purely for BC. Access via method()/__construct()
+ * @property Value[] $params deprecated - public access left in purely for BC. Access via getParam()/__construct()
+ * @property int $debug deprecated - public access left in purely for BC. Access via .../setDebug()
+ * @property string $payload deprecated - public access left in purely for BC. Access via getPayload()/setPayload()
+ * @property string $content_type deprecated - public access left in purely for BC. Access via getContentType()/setPayload()
*/
class Request
{
use ParserAware;
use PayloadBearer;
- /// @todo: do these need to be public?
- /** @internal */
- public $methodname;
- /** @internal */
- public $params = array();
+ /** @var string */
+ protected $methodname;
+ /** @var Value[] */
+ protected $params = array();
/** @var int */
- public $debug = 0;
+ protected $debug = 0;
- // holds data while parsing the response. NB: Not a full Response object
- /** @deprecated will be removed in a future release */
+ /**
+ * holds data while parsing the response. NB: Not a full Response object
+ * @deprecated will be removed in a future release
+ */
protected $httpResponse = array();
/**
$this->debug = $level;
return $this;
}
+
+ // *** BC layer ***
+
+ // we have to make this return by ref in order to allow calls such as `$resp->_cookies['name'] = ['value' => 'something'];`
+ public function &__get($name)
+ {
+ switch ($name) {
+ case 'me':
+ case 'mytype':
+ case '_php_class':
+ case 'payload':
+ case 'content_type':
+ $this->logDeprecation('Getting property Request::' . $name . ' is deprecated');
+ return $this->$name;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ $result = null;
+ return $result;
+ }
+ }
+
+ public function __set($name, $value)
+ {
+ switch ($name) {
+ case 'methodname':
+ case 'params':
+ case 'debug':
+ case 'payload':
+ case 'content_type':
+ $this->logDeprecation('Setting property Request::' . $name . ' is deprecated');
+ $this->$name = $value;
+ break;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __set(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ }
+ }
+
+ public function __isset($name)
+ {
+ switch ($name) {
+ case 'methodname':
+ case 'params':
+ case 'debug':
+ case 'payload':
+ case 'content_type':
+ $this->logDeprecation('Checking property Request::' . $name . ' is deprecated');
+ return isset($this->$name);
+ default:
+ return false;
+ }
+ }
+
+ public function __unset($name)
+ {
+ switch ($name) {
+ case 'methodname':
+ case 'params':
+ case 'debug':
+ case 'payload':
+ case 'content_type':
+ $this->logDeprecation('Unsetting property Request::' . $name . ' is deprecated');
+ unset($this->$name);
+ break;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __unset(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ }
+ }
}
* Server-side, a server method handler will construct a Response and pass it as its return value.
* An identical Response object will be returned by the result of an invocation of the send() method of the Client class.
*
- * @property array $hdrs deprecated, use $httpResponse['headers']
- * @property array _cookies deprecated, use $httpResponse['cookies']
- * @property string $raw_data deprecated, use $httpResponse['raw_data']
+ * @property Value|string|mixed $val deprecated - public access left in purely for BC. Access via value()/__construct()
+ * @property string $valtyp deprecated - public access left in purely for BC. Access via valueType()/__construct()
+ * @property int $errno deprecated - public access left in purely for BC. Access via faultCode()/__construct()
+ * @property string $errstr deprecated - public access left in purely for BC. Access faultString()/__construct()
+ * @property string $payload deprecated - public access left in purely for BC. Access via getPayload()/setPayload()
+ * @property string $content_type deprecated - public access left in purely for BC. Access via getContentType()/setPayload()
+ * @property array $hdrs deprecated. Access via httpResponse()['headers'], set via $httpResponse['headers']
+ * @property array _cookies deprecated. Access via httpResponse()['cookies'], set via $httpResponse['cookies']
+ * @property string $raw_data deprecated. Access via httpResponse()['raw_data'], set via $httpResponse['raw_data']
*/
class Response
{
use DeprecationLogger;
use PayloadBearer;
- /// @todo: do these need to be public?
- /** @internal */
- public $val = 0;
- /** @internal */
- public $valtyp;
- /** @internal */
- public $errno = 0;
- /** @internal */
- public $errstr = '';
+ /** @var Value|string|mixed */
+ protected $val = 0;
+ /** @var string */
+ protected $valtyp;
+ /** @var int */
+ protected $errno = 0;
+ /** @var string */
+ protected $errstr = '';
protected $httpResponse = array('headers' => array(), 'cookies' => array(), 'raw_data' => '', 'status_code' => null);
public function &__get($name)
{
switch ($name) {
+ case 'val':
+ case 'valtyp':
+ case 'errno':
+ case 'errstr':
+ case 'payload':
+ case 'content_type':
+ $this->logDeprecation('Getting property Response::' . $name . ' is deprecated');
+ return $this->$name;
case 'hdrs':
$this->logDeprecation('Getting property Response::' . $name . ' is deprecated');
return $this->httpResponse['headers'];
public function __set($name, $value)
{
switch ($name) {
+ case 'val':
+ case 'valtyp':
+ case 'errno':
+ case 'errstr':
+ case 'payload':
+ case 'content_type':
+ $this->logDeprecation('Setting property Response::' . $name . ' is deprecated');
+ $this->$name = $value;
+ break;
case 'hdrs':
$this->logDeprecation('Setting property Response::' . $name . ' is deprecated');
$this->httpResponse['headers'] = $value;
public function __isset($name)
{
switch ($name) {
+ case 'val':
+ case 'valtyp':
+ case 'errno':
+ case 'errstr':
+ case 'payload':
+ case 'content_type':
+ $this->logDeprecation('Checking property Response::' . $name . ' is deprecated');
+ return isset($this->$name);
case 'hdrs':
$this->logDeprecation('Checking property Response::' . $name . ' is deprecated');
return isset($this->httpResponse['headers']);
public function __unset($name)
{
switch ($name) {
+ case 'val':
+ case 'valtyp':
+ case 'errno':
+ case 'errstr':
+ case 'payload':
+ case 'content_type':
+ $this->logDeprecation('Setting property Response::' . $name . ' is deprecated');
+ unset($this->$name);
+ break;
case 'hdrs':
$this->logDeprecation('Unsetting property Response::' . $name . ' is deprecated');
unset($this->httpResponse['headers']);
/**
* Allows effortless implementation of XML-RPC servers
+ *
+ * @property string[] $accepted_compression deprecated - public access left in purely for BC. Access via getOption()/setOption()
+ * @property bool $allow_system_funcs deprecated - public access left in purely for BC. Access via getOption()/setOption()
+ * @property bool $compress_response deprecated - public access left in purely for BC. Access via getOption()/setOption()
+ * @property int $debug deprecated - public access left in purely for BC. Access via getOption()/setOption()
+ * @property int $exception_handling deprecated - public access left in purely for BC. Access via getOption()/setOption()
+ * @property string $functions_parameters_type deprecated - public access left in purely for BC. Access via getOption()/setOption()
+ * @property array $phpvals_encoding_options deprecated - public access left in purely for BC. Access via getOption()/setOption()
+ * @property string $response_charset_encoding deprecated - public access left in purely for BC. Access via getOption()/setOption()
*/
class Server
{
*
* @todo create class constants for these
*/
- public $functions_parameters_type = 'xmlrpcvals';
+ protected $functions_parameters_type = 'xmlrpcvals';
/**
* @var array
* when the functions_parameters_type member is set to 'phpvals'.
* @see Encoder::encode for a list of values
*/
- public $phpvals_encoding_options = array('auto_dates');
+ protected $phpvals_encoding_options = array('auto_dates');
/**
* @var int
* 2 =
* 3 =
*/
- public $debug = 1;
+ protected $debug = 1;
/**
* @var int
* 2 = allow the exception to float to the upper layers
* Can be overridden per-method-handler in the dispatch map
*/
- public $exception_handling = 0;
+ protected $exception_handling = 0;
/**
* @var bool
* for compression in the request.
* Automatically set at constructor time.
*/
- public $compress_response = false;
+ protected $compress_response = false;
/**
* @var string[]
* List of http compression methods accepted by the server for requests. Automatically set at constructor time.
* NB: PHP supports deflate, gzip compressions out of the box if compiled w. zlib
*/
- public $accepted_compression = array();
+ protected $accepted_compression = array();
/**
* @var bool
* Shall we serve calls to system.* methods?
*/
- public $allow_system_funcs = true;
+ protected $allow_system_funcs = true;
/**
* List of charset encodings natively accepted for requests.
* Set at constructor time.
- * UNUSED so far...
+ * @deprecated UNUSED so far...
*/
- public $accepted_charset_encodings = array();
+ protected $accepted_charset_encodings = array();
/**
* @var string
* - 'auto' (use client-specified charset encoding or same as request if request headers do not specify it (unless request is US-ASCII: then use library default anyway).
* NB: pretty dangerous if you accept every charset and do not have mbstring enabled)
*/
- public $response_charset_encoding = '';
+ protected $response_charset_encoding = '';
+
+ protected static $options = array(
+ self::OPT_ACCEPTED_COMPRESSION,
+ self::OPT_ALLOW_SYSTEM_FUNCS,
+ self::OPT_COMPRESS_RESPONSE,
+ self::OPT_DEBUG,
+ self::OPT_EXCEPTION_HANDLING,
+ self::OPT_FUNCTIONS_PARAMETERS_TYPE,
+ self::OPT_PHPVALS_ENCODING_OPTIONS,
+ self::OPT_RESPONSE_CHARSET_ENCODING,
+ );
/**
* @var mixed
*/
protected $dmap = array();
- protected $options = array(
- self::OPT_ACCEPTED_COMPRESSION,
- self::OPT_ALLOW_SYSTEM_FUNCS,
- self::OPT_COMPRESS_RESPONSE,
- self::OPT_DEBUG,
- self::OPT_EXCEPTION_HANDLING,
- self::OPT_FUNCTIONS_PARAMETERS_TYPE,
- self::OPT_PHPVALS_ENCODING_OPTIONS,
- self::OPT_RESPONSE_CHARSET_ENCODING,
- );
-
/**
* Storage for internal debug info.
*/
{
switch ($name) {
case self::OPT_ACCEPTED_COMPRESSION :
- $this->accepted_charset_encodings = $value;
- break;
case self::OPT_ALLOW_SYSTEM_FUNCS:
- $this->allow_system_funcs = $value;
- break;
case self::OPT_COMPRESS_RESPONSE:
- $this->compress_response = $value;
- break;
case self::OPT_DEBUG:
- $this->debug = $value;
- break;
case self::OPT_EXCEPTION_HANDLING:
- $this->exception_handling = $value;
- break;
case self::OPT_FUNCTIONS_PARAMETERS_TYPE:
- $this->functions_parameters_type = $value;
- break;
case self::OPT_PHPVALS_ENCODING_OPTIONS:
- $this->phpvals_encoding_options = $value;
- break;
case self::OPT_RESPONSE_CHARSET_ENCODING:
- $this->response_charset_encoding = $value;
+ $this->$name = $value;
break;
default:
throw new ValueErrorException("Unsupported option '$name'");
{
switch ($name) {
case self::OPT_ACCEPTED_COMPRESSION:
- return $this->accepted_compression;
case self::OPT_ALLOW_SYSTEM_FUNCS:
- return $this->allow_system_funcs;
case self::OPT_COMPRESS_RESPONSE:
- return $this->compress_response;
case self::OPT_DEBUG:
- return $this->debug;
case self::OPT_EXCEPTION_HANDLING:
- return $this->exception_handling;
case self::OPT_FUNCTIONS_PARAMETERS_TYPE:
- return $this->functions_parameters_type;
case self::OPT_PHPVALS_ENCODING_OPTIONS:
- return $this->phpvals_encoding_options;
case self::OPT_RESPONSE_CHARSET_ENCODING:
- return $this->response_charset_encoding;
+ return $this->$name;
default:
throw new ValueErrorException("Unsupported option '$name'");
}
public function getOptions()
{
$values = array();
- foreach($this->options as $opt) {
+ foreach(static::$options as $opt) {
$values[$opt] = $this->getOption($opt);
}
return $values;
return "<?xml version=\"1.0\"?" . ">\n";
}
}
+
+ // we have to make this return by ref in order to allow calls such as `$resp->_cookies['name'] = ['value' => 'something'];`
+ public function &__get($name)
+ {
+ switch ($name) {
+ case self::OPT_ACCEPTED_COMPRESSION :
+ case self::OPT_ALLOW_SYSTEM_FUNCS:
+ case self::OPT_COMPRESS_RESPONSE:
+ case self::OPT_DEBUG:
+ case self::OPT_EXCEPTION_HANDLING:
+ case self::OPT_FUNCTIONS_PARAMETERS_TYPE:
+ case self::OPT_PHPVALS_ENCODING_OPTIONS:
+ case self::OPT_RESPONSE_CHARSET_ENCODING:
+ $this->logDeprecation('Getting property Request::' . $name . ' is deprecated');
+ return $this->$name;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ $result = null;
+ return $result;
+ }
+ }
+
+ public function __set($name, $value)
+ {
+ switch ($name) {
+ case self::OPT_ACCEPTED_COMPRESSION :
+ case self::OPT_ALLOW_SYSTEM_FUNCS:
+ case self::OPT_COMPRESS_RESPONSE:
+ case self::OPT_DEBUG:
+ case self::OPT_EXCEPTION_HANDLING:
+ case self::OPT_FUNCTIONS_PARAMETERS_TYPE:
+ case self::OPT_PHPVALS_ENCODING_OPTIONS:
+ case self::OPT_RESPONSE_CHARSET_ENCODING:
+ $this->logDeprecation('Setting property Request::' . $name . ' is deprecated');
+ $this->$name = $value;
+ break;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __set(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ }
+ }
+
+ public function __isset($name)
+ {
+ switch ($name) {
+ case self::OPT_ACCEPTED_COMPRESSION :
+ case self::OPT_ALLOW_SYSTEM_FUNCS:
+ case self::OPT_COMPRESS_RESPONSE:
+ case self::OPT_DEBUG:
+ case self::OPT_EXCEPTION_HANDLING:
+ case self::OPT_FUNCTIONS_PARAMETERS_TYPE:
+ case self::OPT_PHPVALS_ENCODING_OPTIONS:
+ case self::OPT_RESPONSE_CHARSET_ENCODING:
+ $this->logDeprecation('Checking property Request::' . $name . ' is deprecated');
+ return isset($this->$name);
+ default:
+ return false;
+ }
+ }
+
+ public function __unset($name)
+ {
+ switch ($name) {
+ case self::OPT_ACCEPTED_COMPRESSION :
+ case self::OPT_ALLOW_SYSTEM_FUNCS:
+ case self::OPT_COMPRESS_RESPONSE:
+ case self::OPT_DEBUG:
+ case self::OPT_EXCEPTION_HANDLING:
+ case self::OPT_FUNCTIONS_PARAMETERS_TYPE:
+ case self::OPT_PHPVALS_ENCODING_OPTIONS:
+ case self::OPT_RESPONSE_CHARSET_ENCODING:
+ $this->logDeprecation('Unsetting property Request::' . $name . ' is deprecated');
+ unset($this->$name);
+ break;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __unset(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ }
+ }
}
trait PayloadBearer
{
/** @var string */
- public $payload;
+ protected $payload;
/** @var string */
- public $content_type = 'text/xml';
+ protected $content_type = 'text/xml';
/**
* @internal
/**
* This class enables the creation of values for XML-RPC, by encapsulating plain php values.
+ *
+ * @property Value[]|mixed $me deprecated - public access left in purely for BC. Access via scalarVal()/__construct()
+ * @property int $params $mytype - public access left in purely for BC. Access via kindOf()/__construct()
+ * @property string|null $_php_class deprecated - public access left in purely for BC.
*/
class Value implements \Countable, \IteratorAggregate, \ArrayAccess
{
"null" => 1,
);
- /// @todo: do these need to be public?
/** @var Value[]|mixed */
- public $me = array();
+ protected $me = array();
/**
* @var int 0 for undef, 1 for scalar, 2 for array, 3 for struct
- * @internal
*/
- public $mytype = 0;
+ protected $mytype = 0;
/** @var string|null */
- public $_php_class = null;
+ protected $_php_class = null;
/**
* Build an xml-rpc value.
return count($this->me['struct']);
}
+
+ // we have to make this return by ref in order to allow calls such as `$resp->_cookies['name'] = ['value' => 'something'];`
+ public function &__get($name)
+ {
+ switch ($name) {
+ case 'me':
+ case 'mytype':
+ case '_php_class':
+ $this->logDeprecation('Getting property Value::' . $name . ' is deprecated');
+ return $this->$name;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ $result = null;
+ return $result;
+ }
+ }
+
+ public function __set($name, $value)
+ {
+ switch ($name) {
+ case 'me':
+ case 'mytype':
+ case '_php_class':
+ $this->logDeprecation('Setting property Value::' . $name . ' is deprecated');
+ $this->$name = $value;
+ break;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __set(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ }
+ }
+
+ public function __isset($name)
+ {
+ switch ($name) {
+ case 'me':
+ case 'mytype':
+ case '_php_class':
+ $this->logDeprecation('Checking property Value::' . $name . ' is deprecated');
+ return isset($this->$name);
+ default:
+ return false;
+ }
+ }
+
+ public function __unset($name)
+ {
+ switch ($name) {
+ case 'me':
+ case 'mytype':
+ case '_php_class':
+ $this->logDeprecation('Unsetting property Value::' . $name . ' is deprecated');
+ unset($this->$name);
+ break;
+ default:
+ /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
+ trigger_error('Undefined property via __unset(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
+ }
+ }
}