Как мне обращаться со строками цифр в XML :: RPC и Drupal?

Я пытаюсь использовать сервер 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, чтобы знать наверняка.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 126
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Число 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.

Спасибо, Оуэн. Эта информация как раз то, что мне было нужно.

Tracy Hurley 04.11.2008 16:37
Ответ принят как подходящий

У меня нет опыта работы с пакетом XML :: RPC, но я являюсь автором модуля RPC :: XML CPAN. Как и в случае с пакетом Frontier, я предоставляю способ принудительно присвоить значение определенному типу, когда в противном случае по умолчанию было бы установлено что-то другое.

Если бы мне пришлось угадывать, я бы сказал, что используемый вами пакет simple сопоставляет данные с регулярным выражением, чтобы решить, как их набрать. У меня была аналогичная проблема с моим пакетом, и, учитывая то, как Perl обрабатывает скалярные значения, единственный реальный способ обойти это - заставить его явным объявлением. Как указывал предыдущий ответчик, рассматриваемое значение фактически выходит за пределы диапазона типа <i4> (который является 32-битным значением со знаком). Таким образом, даже если вы предполагали, что это будет целочисленное значение, оно было бы недопустимым по отношению к спецификации XML-RPC.

Я бы порекомендовал переключиться на один из других пакетов XML-RPC, которые имеют более четкие способы явного ввода данных. Согласно документации для XML :: RPC, можно принудительно ввести данные, но я обнаружил, что это неясно и не очень хорошо объяснено.

Спасибо! Раньше я использовал библиотеку RPC :: XML, и я вернусь к ней.

Tracy Hurley 04.11.2008 15:11

Другие вопросы по теме