Я пытаюсь использовать сервер XML-RPC в моем бэкэнде Drupal (PHP), чтобы моему бэкэнду Perl было легче общаться с ним. Однако я столкнулся с проблемой, и я не уверен, какие части, если таковые имеются, являются ошибками. По сути, некоторые из переменных, которые мне нужно передать в Drupal, представляют собой строки, которые иногда представляют собой строки, заполненные числами, и сервер Drupal XML-RPC возвращает ошибку, заключающуюся в том, что, когда строка заполнена числами, она неправильно сформирована.
Мой код Perl сейчас выглядит примерно так.
use strict;
use warnings;
use XML::RPC;
use Data::Dumper;
my $xmlrpc = XML::RPC->new(URL);
my $result = $xmlrpc->call( FUNCTION, 'hello world', '9876352345');
print Dumper $result;
Результат:
$VAR1 = {
'faultString' => 'Server error. Invalid method parameters.',
'faultCode' => '-32602'
};
Когда сервер Drupal XML-RPC распечатывает полученные данные, я замечаю, что второй аргумент набирается как i4:
<param>
<value>
<i4>9876352345</i4>
</value>
Я думаю, что когда Drupal завершает обработку элемента, он набирает эту переменную как int вместо строки. Это означает, что когда Drupal позже попытается проверить правильность формирования значения переменной для строки, PHP-функция is_string вернет false.
foreach ($signature as $key => $type) {
$arg = $args[$key];
switch ($type) {
case 'int':
case 'i4':
if (is_array($arg) || !is_int($arg)) {
$ok = FALSE;
}
break;
case 'base64':
case 'string':
if (!is_string($arg)) {
$ok = FALSE;
}
break;
case 'boolean':
if ($arg !== FALSE && $arg !== TRUE) {
$ok = FALSE;
}
break;
case 'float':
case 'double':
if (!is_float($arg)) {
$ok = FALSE;
}
break;
case 'date':
case 'dateTime.iso8601':
if (!$arg->is_date) {
$ok = FALSE;
}
break;
}
if (!$ok) {
return xmlrpc_error(-32602, t('Server error. Invalid method parameters.'));
}
}
В чем я не уверен, так это в том, на какой стороне разделения стоит проблема или есть ли что-то еще, что мне следует использовать. Должен ли запрос со стороны Perl вводить содержимое в виде строки вместо i4 или сторона запроса Drupal является слишком строгой для строкового типа? Я предполагаю, что проблема в последнем, но я недостаточно знаю, как должен работать сервер XML-RPC, чтобы знать наверняка.





Число 9876352345 слишком велико для 32-битного целого числа. Это могло вызвать проблему.
вы используете границу? возможно, вы могли бы явно объявить строку?
my $result =
$xmlrpc->call( FUNCTION, 'hello world', $xmlrpc->string('9876352345') );
информация из клиентские документы:
By default, you may pass ordinary Perl values (scalars) to be encoded. RPC2 automatically converts them to XML-RPC types if they look like an integer, float, or as a string. This assumption causes problems when you want to pass a string that looks like "0096", RPC2 will convert that to an because it looks like an integer.
У меня нет опыта работы с пакетом XML :: RPC, но я являюсь автором модуля RPC :: XML CPAN. Как и в случае с пакетом Frontier, я предоставляю способ принудительно присвоить значение определенному типу, когда в противном случае по умолчанию было бы установлено что-то другое.
Если бы мне пришлось угадывать, я бы сказал, что используемый вами пакет simple сопоставляет данные с регулярным выражением, чтобы решить, как их набрать. У меня была аналогичная проблема с моим пакетом, и, учитывая то, как Perl обрабатывает скалярные значения, единственный реальный способ обойти это - заставить его явным объявлением. Как указывал предыдущий ответчик, рассматриваемое значение фактически выходит за пределы диапазона типа <i4> (который является 32-битным значением со знаком). Таким образом, даже если вы предполагали, что это будет целочисленное значение, оно было бы недопустимым по отношению к спецификации XML-RPC.
Я бы порекомендовал переключиться на один из других пакетов XML-RPC, которые имеют более четкие способы явного ввода данных. Согласно документации для XML :: RPC, можно принудительно ввести данные, но я обнаружил, что это неясно и не очень хорошо объяснено.
Спасибо! Раньше я использовал библиотеку RPC :: XML, и я вернусь к ней.
Спасибо, Оуэн. Эта информация как раз то, что мне было нужно.