Конструктор вебсервисов для 1с - Примеры

Простой вызов метода

На php:

    /**
     * функция без параметров
     */
    function test1() {
        // можно что-нибудь сделать с базой
    }

    $ws = new WS1c('http://foo.bar/wsfor1c', 'wsfor1c');
    $ws->methods[] = new ReflectionFunction('test1');

Со стороны 1с:

    Определение = Новый WSОпределения(АдресWSDL);
    Прокси = Новый WSПрокси(Определение, ПространствоИменСервиса, ИмяСервиса, ИмяТочкиПодключения);
    Прокси.test1();

Вызов метода с параметрами и возвращаемым значением примитивного типа

Поддерживаются типы decimal, int, float string, date, dateTime. Поскольку в php нет типа даты, в него прилетает строка, возвращать можно как datetime, так и строку. Так сделано для более простого взаимодействия с mysql, в которой пустая дата кодируется датой 0000-00-00 00:00:00

На php:

    /**
     * 
     * @param string $msg
     * @return string описание возвращаемого параметра
     */
    function test2($msg) {
        return "Запрос был: \"".$msg."\"";
    }

    $ws = new WS1c('http://foo.bar/wsfor1c', 'wsfor1c');
    $ws->methods[] = new ReflectionFunction('test2');

Со стороны 1с (преобразование примитивных типов происходит автоматически):

    Определение = Новый WSОпределения(АдресWSDL);

    Прокси = Новый WSПрокси(Определение, ПространствоИменСервиса, ИмяСервиса, ИмяТочкиПодключения);
    Результат2 = Прокси.test2(Параметр2);

Вызов метода с изменяемыми параметрами

Поддерживается передача параметров на вход и на вход-выход, передача параметров только на выход не поддерживается, пользуйтесь возвращаемым значением функции. Также в данном примере показана работа с датой.Если необходимо переопределить правила преобразования значений, то это делается в функции XDTOPacket->makeSimpleValue.

На php (направление передачи параметра определяется передачей его "по ссылке" или нет):

/**
 * 
 * @param decimal $a
 * @param decimal $b
 * @param dateTime $c
 * @return int
 */
function test3($a, $b, &$c) {
    $res = $a*$b;
    $c = new DateTime($c);
    $c->add(new DateInterval('P1D'));
    return $res; 
}

Со стороны 1с (Параметр33 является двусторонним, дата увеличивается на один день при каждом вызове):

    Определение = Новый WSОпределения(АдресWSDL);

    Прокси = Новый WSПрокси(Определение, ПространствоИменСервиса, ИмяСервиса, ИмяТочкиПодключения);
    Результат3 = Прокси.test3(Параметр31, Параметр32, Параметр33);

Передача сложных структур

Поддерживается двусторонняя передача сложных струкутр, включая вложенные. Типы данных определяются через указание класса у функции и через phpdoc.

На php:

class TestClass41 {

    /**
     * @var decimal
     */
    var $a;
    
    /**
     * @var decimal
     */
    var $b;
    
    /**
     * @var decimal
     */
    var $res;
    
    function mul() {
        $this->res = $this->a * $this->b;
    }
}

class TestClass42 {
    /**
     * @var decimal
     */
    var $res;
    
    public function __construct($res) {
        $this->res = $res * $res;
    }
}

/**
 * 
 * @param TestClass41 $par
 * @return TestClass42
 */
function test4(TestClass41 &$par) {
    $par->mul();
    $res = new TestClass42($par->res);
    return $res;
}

Со стороны 1с (параметр является двусторонним):

    Определение = Новый WSОпределения(АдресWSDL);

    Прокси = Новый WSПрокси(Определение, ПространствоИменСервиса, ИмяСервиса, ИмяТочкиПодключения);
    Фабрика = Определение.ФабрикаXDTO;

    ОбъектСервиса = Фабрика.Создать(Фабрика.Тип(ПространствоИменСервиса, "TestClass41"));
    ОбъектСервиса.a = Параметр41;
    ОбъектСервиса.b = Параметр42;
    ОбъектСервиса.res = 0;
    ОбъектРезультат = Прокси.test4(ОбъектСервиса);

    Результат41 = ОбъектСервиса.res;
    Результат42 = ОбъектРезультат.res;

Передача массивов

Поддерживается двусторонняя передача массивов примитивных типов и структур. То, что это массив определяется у свойства через phpdoc указанием @minOccurs и @maxOccurs.

На php:

class TestClass51 {
    
    /**
     * 
     * @minOccurs 0
     * @maxOccurs unbounded
     * @var TestClass52
     */
    var $arr;
}

class TestClass52 {
    
    /**
     * 
     * @var decimal
     */
    var $a;
    /**
     * 
     * @var decimal
     */
    var $b;
    /**
     * 
     * @var string
     */
    var $action;
}

class TestClass53 {
    
    /**
     * 
     * @minOccurs 0
     * @maxOccurs unbounded
     * @var decimal
     */
    var $res = array();
    
}

/**
 * 
 * @param TestClass51 $par
 * @return TestClass53
 */
function test5(TestClass51 $par) {
    $res = new TestClass53;
    foreach($par->arr as $el) {
        /* @var $el TestClass52 */
        switch ($el->action) {
            case 'mul': $res->res[] = $el->a * $el->b;
                break;
            case 'sum': $res->res[] = $el->a + $el->b;
                break;
            case 'div': $res->res[] = $el->a / $el->b;
                break;
            case 'sub': $res->res[] = $el->a - $el->b;
                break;

            default: $res->res[] = 0;
                break;
        }
    }
        
    return $res;
}

Со стороны 1с:

    Определение = Новый WSОпределения(АдресWSDL);

    Прокси = Новый WSПрокси(Определение, ПространствоИменСервиса, ИмяСервиса, ИмяТочкиПодключения);
    Фабрика = Определение.ФабрикаXDTO;

    ОбъектСервиса = Фабрика.Создать(Фабрика.Тип(ПространствоИменСервиса, "TestClass51"));
    Для Каждого Стр Из Параметр5 Цикл
            Элемент = Фабрика.Создать(Фабрика.Тип(ПространствоИменСервиса, "TestClass52"));
            ЗаполнитьЗначенияСвойств(Элемент, Стр);
            ОбъектСервиса.arr.Добавить(Элемент);
    КонецЦикла;
    ОбъектРезультат = Прокси.test5(ОбъектСервиса);
    Результат5.Очистить();
    Для каждого ЭлементРезультата Из ОбъектРезультат.res Цикл
            Результат5.Добавить().res = ЭлементРезультата;
    КонецЦикла;