1с web сервисы, web сервисы 1с 8.2, 1с soap, 1c php exchange - 1С-ИнтеГрация

1с web сервисы, web сервисы 1с 8.2, 1с soap, 1c php exchange



Быстрый старт. С чего начать ?


Пункт №0. Прежде всего, необходимо выбрать (определиться) с технологией интеграции и понять "суть" - т.е как это будет работать.
Иначе говоря, нужно ответить на два вопроса:
Какая база 1С (или другая программа) будет выступать в роли клиента, и какая в роли сервера;
При определении того, что будет клиентом, а что сервером можно руководствоваться простым правилом: клиент может "вызвать" (управлять) сервером, а обратный вызов не возможен.
Какая технология взаимодействия клиента и сервера более подходит вам и будет использоваться.
Свои рекомендации по выбору технологии я изложил выше.

Пункт №1.
Итак, "суть" клиент-серверного взаимодействия - осознана. Технология взаимодействия - определена. Теперь следует создать "полигон", на котором и будет осуществляться разработка.

В данной статье, на примерах будут рассмотрены две технологии:

Работа с механизмом WEB -сервисов.

Будут рассмотрены примеры работы со стороны 1С 8 и PHP;

Работа с механизмом http-запросов (REST Web-сервисы).

Так же будут рассмотрены примеры работы со стороны 1С 8 и PHP;
В задачах, связанных с WEB-разработкой, традиционно принято:
Создавать "полигон" для разработки и отладки на локальном WEB-сервере программиста (localhost);
После того, как разработка завершена, результаты необходимо перенести на "боевой" WEB-сервер.


На практике (особенно когда начинаешь "знакомство" с технологией WEB-сервисов) при создании "полигона", а так же при переносе проекта на "боевой" сервер, возникает много "грабель".

Так вот, что бы «не убить» много времени на "борьбу" c настройками IIS (Internet Information Server) / освоение сервера apache, и настройку прав доступа Windows, я рекомендую следующее:

(1) "Полигон" создавать на вашей локальной рабочей машине. Операционная система - Windows 7 (проф или максимальная). Все работу - выполнять под учетной записью администратора.
(2) Базу 1С 8 развернуть в клиент-серверном режиме (MS SQL сервер, рекомендую 2008 R2). Использование 1С 8 в режиме клиент-сервера снимет необходимость выполнять доп. настройки по правам доступа к базе 1С со стороны WEB-сервера.
(3) Установить IIS, если он отсутствует. В windows его можно штатно "доустановить"


"Галочки" для опций установки компонентов IIS можно ставить "по умолчанию".
Существенным, на что требуется обратить внимание, это следующие опции (расширения ISAPI - это нужно для работы soap-соединений в WEB-сервисах, и CGI - это потребуется для работы PHP)

После завершения установки IIS убедимся, что он заработал. Для этого, в адресной строке WEB-браузера введем:

(4) Публикация (подключение) базы 1С на WEB-сервере.

И так, WEB-сервер IIS установлен и работает. Опубликуем нашу базу 1С и проверим, что теперь доступ к ней возможен и через WEB-клиента тоже.

Публиковать на WEB-сервере целесообразно ту базу 1С, в которой предусмотрена работа в режиме управляемого приложения (тонкого клиента).

Публикация базы 1С выполняется так:
В режиме конфигуратора, нужно вызвать пункт "Публикация на веб-сервере"


б) Указать параметры публикации:

Т.е в каталоге (папке) wwwroot вашего IIS нужно создать отдельную папку (каталог) для публикации вашей базы 1С.

каталог wwwroot будет создан автоматически, при установке IIS
Cоздадим и выберем такую папку (wsBase10), укажем имя для публикации (тоже назовем ee wsBase10).

После этого, нажмем на "Опубликовать".

Если, вдруг, в ответ вы получите сообщение,

то не пугайтесь. smile:-)

Механизм публикации 1С весьма капризный. Попробуйте нажать на "Опубликовать" еще раз.

И если в результате вы получите сообщение,

то значит все заработало.

Очень важно понимать, что при публикаации базы 1С и ее WEB-сервисов на "боевом" сервере (на пример, Windows 2008 R2) часто возникают ошибки, если вы решите использовать web-cервер IIS.

Cовет: не ставьте на "боевой" сервер IIS! Установите apache.

Это оградит вам от многих системеных ошибок. И публикация (перепубликация - при изменениях в конфигурации) будет проходить для apache гладко, без необходимости "ковыряться" в vrd - файликах и настройках IIS.

В данной статьe я не будут рассматривать процесс установки и настройки apache. На эту тему существует другие источники.

Однако, для совместной работы apache c базой 1С (и web-сервисами) есть несколько очень важных требований, которые нужно знать (донесите это до вашего системного администратора).


1. При установке apache обязательно включите поддержку расширений ISAPI.

2. Включите поддержку cgi-bin, если вам предстоит работать с PHP;

3. В базу 1С потребуется ввести специального «пользователя»…

У этого пользователя должна быть аутентификация операционной системы. И нужно указать того пользователя, от имени которого и запускается apache.

... С apache закончили и снова вернемся на наш "Полигон".

После того, как база 1С опубликовалась, убедимся, что доступ к ней через WEB-браузер работает. Для этого в адресной строке введем следующий URL:

Вот видим – 1С запускается. WEB-сервер совместно с 1С - заработал.
4. Установить службу PHP для WINDOWS.

Она понадобиться, если в рамках вашей задачи необходимо разрабатывать клиентские (web-страницы доступа к 1С) или серверные (сценарии обработки http-запросов со стороны 1С) на PHP.

Скачать диструбутив PHP для Windows рекомендую здесь:

5 Добавим в IIS каталог wsClient10, в котором будут работать наши PHP-скрипты.

PHP скрипты мы будем использовать:
Для создания клиентской части, при разработке WEB-сервисов 1С;
Для разработки серверной части, при разработке REST web сервисов (http-запросы).

6. Установим программу Notepap++. Эту компактую и удобную программу советую использоваться для редактирования PHP-скриптов.

После установки Notepad++ сразу же проверим, что PHP у нас работает. Создадим для этого простейший скрипт hello.php. Разместим его в каталоге wsClient и запустим скрипт из браузера:

Все ОК. PHP заработал. Тестовый "Полигон" полностью готов.

3. Создание WEB-сервиса, soap запросы, XDTO и JSON. Примеры 1С и PHP. 

На данном этапе "Полигон" должен быть у вас готов и можно приступать к разработке WEB-сервисов.

- С чего же начать изучение этой технологии? Конечно же, с классической задачки типа "Hello word"!

1. Задача создания простейшего WEB -сервиса. Рассмотрим примеры на 1С и PHP.

1.1. Добавим в базу (wsBase10) web-сервис "_РасчетыПоТарифам"

Имя файла публикации зададим "calcOrder10.1cws". URI-пространство имен так же необходимо указать. В принципе, можно указать любое имя.

1.2. Добавим в рамках web-сервиса "_РасчетыПоТарифам" операцию "getHello".

Суть выполнения операции будет простейшая - принять на входе (с клиента) три параметра (строки, числа) и вернуть ему назад (в виде результата) объединяющую строку. Тип возвращаемого значения будет примитивный - string.

Галочку "В транакции" ставить не будем, так как операция не будет изменять данные в самой базе 1С.

Если бы наша операция изменяла данные в базе 1С, то установка данной галочки имела бы смысл.
Имя метода (функции), которая будет обрабатывать входящие данные (и возвращать результат) зададим - "getHello".

1.3. Добавим для операции "getHello" входящие параметры.

Направление передачи - "входной". Т.е передаются с клиента на сервер.

1.4. В модуле web-сервиса напишем обработчик операции "getHello"
//////////////////////////////////////////////////////////////////////////////

Функция getHello(strParametr, floatParametr, integerParametr)
// Вставить содержимое обработчика.
возврат strParametr+строка(floatParametr+integerParametr)
КонецФункции

///////////////////////////////////////////////////////////////////////////////

1.5. На этом, работа по созданию простейшего WEB-сервиса завершена. И теперь, необходимо опубликовать WEB-сервис "_РасчетыПоТарифам".

Раннее, мы опубликовали на WEB-сервере базу wsBase10. Но WEB-сервисов у нас на тот момент не было. Пора опубликовать их.

Перед тем как публиковать на "полигоне" web-сервис, удалим всех пользователей из списка пользователей нашей информационной базы. Т.е список пользователей сделаем "пустым".

- Зачем это делать ?

На "полигоне" подключаться к WEB-сервисам будет только разработчик, а по этому обеспечивать аутентификацию пользователя при подключения к WEB-сервису – нет смысла.

Т.е мы осознано упростим себе работу с WEB-сервисами на тестовом "полигоне".

Нам не нужно будет указывать логин и пароль при устновке соединения.
А вот на "боевом" сервере обеспечивать аутентификацию, разумеется, придется.
Для этого (как уже было сказана ранее) в "боевой" базе нужно будет отдельно создать пользователя, от имени которого запускается сам WEB-сервер. И тогда, при установлении соединения с WEB-сервисом (soap соединение) нужно будет еще указывать логин и пароль данного пользователя.

1.6. И так, опубликуем WEB-сервис:

Замечу, что устанавливать флажок "Использовать аутентификацию операционной системы на веб-сервере" нам не придется. Это потому, что данный режим предусмотрен только для WEB-сервера IIS, а на "боевом" сервере будет работать Apache.

1.7. Создадим клиенскую часть и протестируем работу WEB-сервера.

а) Сначала, осуществим клиентский вызов из 1С.

Поступим просто. В любой другой базе 1с, которая у вас есть, создадим внешнюю обработку. В этот обработке подключимся к WEB-сервису, воспользуется операцией "getHello", передадим туда параметры и получим ответ от сервера.
Код на "1С" будет примерно таким:

///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура ВыполнитьЗапрос10(Команда)
// Вставить содержимое обработчика.
СтрокаРезультат = СЕРВЕР_ВыполнитьWSЗапрос10();
Предупреждение(СтрокаРезультат);
КонецПроцедуры
&НаСервереБезКонтекста
Функция СЕРВЕР_ВыполнитьWSЗапрос10()
// Аутентификацию на тестовом полигоне осуществлять не будем!
ИмяПользователя = неопределено;
Пароль = неопределено;
//
Определения = новый WSОпределения("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl",ИмяПользователя,Пароль);
Прокси = новый WSПрокси(Определения,"www.URI.com","_РасчетыПоТарифам","_РасчетыПоТарифамSoap" );
Прокси.Пользователь = ИмяПользователя;
Прокси.Пароль = Неопределено;
strРезультат = Прокси.getHello("Иванов",100.35,20);
возврат strРезультат;
КонецФункции 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Протестируем работу функции СЕРВЕР_ВыполнитьWSЗапрос10().

Ок. Работает!
б) Теперь осуществим клиентский вызов web-сервиса из PHP.
Код скрипта PHP будет примерно таким:

//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

<?php
error_reporting( E_ERROR ); // 1. Отключаем лишние сообщения
// 2. Отключаем кэширование для SOAP. Если этого не сделать,
// функции веб-сервисов будут работать некорректно.
ini_set("soap.wsdl_cache_enabled", "0" );
// 3. Устанавливаем soap-соединение
$client = new SoapClient("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl",
array(
'login' => null, //логин, аутентификацию выполнять не будем
'password' => null, //пароль
'trace' => true,
'features' => SOAP_USE_XSI_ARRAY_TYPE,
//'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5
)
);
// 4. Заполнием массив передаваемых параметров
$params["strParametr"] = "test_Soap10:";
$params["floatParametr"] = 10.34;
$params["integerParametr"] = 12;
// 5. Выполняем операцию getHello
$result = $client->getHello($params);
// 6. Выводим результат на экран
var_dump($result);
?>

///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

Вызовем скрипт из браузера и проверим его работу:

Все отлично, вызов 1С из WEB-страницы - работает!

Подведем некоторые итоги:
Задача по простейшему WEB-сервису решена. И теперь, можно браться за создание более сложных WEB-сервисов.

А усложнение будет в том, что (пока) мы оперировали только с примитивными типами данных. Разумеется, нам необходимо будет передавать/принимать и объектные (агрегированные) типы данных.

2. Задача создания WEB -сервиса, использующего XDTO -пакеты.

Как и ранее, рассмотрим примеры на 1С и PHP.

Поставим себе такую задачу: WEB-сервис должен возвращать нам не строку, а объектные данные - "таблицу значений" (а точнее говоря, это будет массив объектов!).

Для того, что бы описывать разнообразные структуры данных (которые потребуются при приеме/передаче на WEB-сервер) в платформе 1С:8 предусмотрен механизм XDTO-пакетов.

Т.е. сначала описываем все необходимые нам типы данных, а затем уже укажем:
C какими пакетами XDTO может работать наш WEB-сервис (можно указать как один, так и перечень пакетов);
Для каждого параметра операции и возвращаемого ею результата можно указать: какого типа данных (из пакета XDTO) он будет.
Далее, работу с XDTO рассмотрим на примере получения с сервере некой «таблицы тарифов»:

Создадим операцию GetTzTariffs_0, которая будет возвращать данные типа tzTariffs.

На рисунке показано, что tzTariffs включает в себя неограниченное количество объектов el. Фактически, tzTariffs - это таблица объектов типа el.

- Как это увидеть ?
Если параметр "максимальное" указан как "-1", то значит количество этих объектов не ограничено (таблица с неограниченным количеством строк);
Если же таблица нам не нужна, а нужна просто структура (одна строка), то максимальное и минимальное значение нужно указать равными "1".
В свою очередь, объект el представляет из себя структуру, в которой есть реквизит объектного типа (eTariff) и реквизиты примитивного типа (cPrice, comment).

Продвигаясь по иерархии вниз, можно увидеть, что тип tariff является структурой (максимальное и минимально количество = 1), в один из реквизитов которой входит тип kindOfTariff.

Итого: пакет XDTO позволяет наглядно описать иерархию типов данных, которые будут использоваться далее при взаимодействии в WEB-сервисом.

Cовет: Лучше использовать для web -сервиса один пакет XDTO , что бы не усложнять и избежать ошибок проектирования.
Идем далее... После того, как:
Пакет XTDO cоздан;
Все типы данных описаны;
Для WEB-сервиса указано использование данного пакета;
Для параметров и результатов операций выбраны соответствующие типы (из пакета XDTO)

то можно переходить к "наполнению" объектов (структур, массивов структур) данными.

В нашем примере операция GetTzTariffs_0 должна возвращать массив строк, cодержащих объекты Tariffs.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Функция GetTzTariffs_0()
// Вставить содержимое обработчика.
Возврат ПолучитьТЗТарифов_0();
КонецФункции

Функция ПолучитьТЗТарифов_0()
tzTariffsТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "tzTariffs" );
tzTariffs = ФабрикаXDTO.Создать(tzTariffsТип);
elementTZТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "elementTZ" );
tariffТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "tariff" );
kindOfTariffТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "kindOfTariff" );
// Заполнение ТЗ
// 1-я строка
//
kindOfTariff = ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = "Перевозка";
kindOfTariff.active = ложь;
//
tariff = ФабрикаXDTO.Создать(tariffТип);
tariff.fullName = "Тариф 1";
tariff.begdate = ТекущаяДата();
tariff.kind = kindOfTariff;
//
elementTZ = ФабрикаXDTO.Создать(elementTZТип);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 100;
elementTZ.comment = "Описание тарифа 1";
// Добавляем 1-ю строку в таблицу
tzTariffs.el.Добавить(elementTZ);
//
// 2-я строка
//
kindOfTariff = ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = "Доставка";
kindOfTariff.active = истина;
//
tariff = ФабрикаXDTO.Создать(tariffТип);
tariff.fullName = "Тариф 2";
tariff.begdate = ТекущаяДата();
tariff.kind = kindOfTariff;
//
elementTZ = ФабрикаXDTO.Создать(elementTZТип);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 200;
elementTZ.comment = "Описание тарифа 2";
// Добавляем 2-ю строку в таблицу
tzTariffs.el.Добавить(elementTZ);
//
Возврат tzTariffs;
КонецФункции

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Далее, приведем пример вызова операции "GetTzTariffs_0" с клиентской части, из 1С.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура ВыполнитьЗапрос20(Команда)
// Вставить содержимое обработчика.
Предупреждение(СЕРВЕР_ВыполнитьWSЗапрос20());
КонецПроцедуры
&НаСервереБезКонтекста
Функция СЕРВЕР_ВыполнитьWSЗапрос20()
Определения = новый WSОпределения("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl" );
Прокси = новый WSПрокси(Определения,"www.URI.com","_РасчетыПоТарифам","_РасчетыПоТарифамSoap" );
XDTOРезультат = Прокси.GetTzTariffs_0();
ПримерРезультат_НаименованиеВидаТарифа = XDTOРезультат.el[0].eTariff.kind.name;
// Обратимся к строке по индексу ноль, далее к рекизиту eTariff, далее к вложенному реквизиту kind, далее к вложенному реквизиту name.
Возврат ПримерРезультат_НаименованиеВидаТарифа;
КонецФункции

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Аналогичный вызов из PHP и обработка результатов XDTO будет такой:
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

<?php
error_reporting( E_ERROR ); // Отключаем сообщения
// Отключаем кэширование для SOAP. Если этого не сделать,
// функции веб-сервисов будут работать некорректно.
ini_set("soap.wsdl_cache_enabled", "0" );
$client = new SoapClient("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl" );
$result = $client->GetTzTariffs_0();
$mResult = $result->return->el;
// mResult - массив объектов. Обойдем элементы массива и выведем результаты на экран
for ($i=0; $i<count($mResult); $i++)
{
echo "";
$eTariff = iconv('utf-8','cp1251',$mResult[$i]->eTariff->fullName);
var_dump($eTariff);
//
$cPrice = $mResult[$i]->cPrice;
var_dump($cPrice);
//
$cComment = $mResult[$i]->cComment;
var_dump($cComment);
//
echo "";
}
?>

//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

Теперь еще усложним задачу. Передадим с клиента на WEB-сервис (в качестве параметра) то же объектный тип данных. Пусть это будет tzKind.
Для этого сначала опишем этот тип в пакете dataTariffs, а затем добавим операцию GetTzTariffs_1.

Укажем тип параметра tzKind.


Пример работы WEB-сервиса с входящим параметром XDTO:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Функция ПолучитьТЗТарифов_1(tzKind)
tzTariffsТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "tzTariffs" );
tzTariffs = ФабрикаXDTO.Создать(tzTariffsТип);
elementTZТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "elementTZ" );
tariffТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "tariff" );
kindOfTariffТип = ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "kindOfTariff" );
// Заполнение ТЗ
// 1-я строка
//
kindOfTariff = ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = "Перевозка";
kindOfTariff.active = ложь;
//
tariff = ФабрикаXDTO.Создать(tariffТип);
tariff.fullName = "Тариф 1";
tariff.begdate = ТекущаяДата();
tariff.kind = kindOfTariff;
//
elementTZ = ФабрикаXDTO.Создать(elementTZТип);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 100;
elementTZ.comment = "Описание тарифа 1";
// Добавляем 1-ю строку в таблицу
tzTariffs.el.Добавить(elementTZ);
//
// 2-я строка
//
kindOfTariff = ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = "Доставка";
kindOfTariff.active = истина;
//
tariff = ФабрикаXDTO.Создать(tariffТип);
tariff.fullName = "Тариф 2";
tariff.begdate = ТекущаяДата();
tariff.kind = kindOfTariff;
//
elementTZ = ФабрикаXDTO.Создать(elementTZТип);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 200;
elementTZ.comment = "Описание тарифа 2";
// Добавляем 3-ю строку в таблицу (заполним ее по входящим данным)
tzTariffs.el.Добавить(elementTZ);
//
// 3-я строка
//
kindOfTariff = ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = tzKind.el[0].eKind.name;
kindOfTariff.active = tzKind.el[0].eKind.active;
//
tariff = ФабрикаXDTO.Создать(tariffТип);
tariff.fullName = "Тариф 3";
tariff.begdate = ТекущаяДата();
tariff.kind = kindOfTariff;
//
elementTZ = ФабрикаXDTO.Создать(elementTZТип);
elementTZ.eTariff = tariff;
elementTZ.cPrice = 300;
elementTZ.comment = "Описание тарифа 3";
// Добавляем 3-ю строку в таблицу
tzTariffs.el.Добавить(elementTZ);
//
Возврат tzTariffs;
КонецФункции

//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

Cо стороны клиента "1С" нам потребуется подготовить данные типа tzKind и передать их на WEB-cервис.

Приведу пример такого вызова:
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура ВыполнитьЗапрос30(Команда)
// Вставить содержимое обработчика.
Предупреждение(СЕРВЕР_ВыполнитьWSЗапрос30());
КонецПроцедуры
&НаСервереБезКонтекста
Функция СЕРВЕР_ВыполнитьWSЗапрос30()
Определения = новый WSОпределения("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl" );
Прокси = новый WSПрокси(Определения,"www.URI.com","_РасчетыПоТарифам","_РасчетыПоТарифамSoap" );
// Сформируем таблицу параметров, передаваемых в WS
//
tzKindТип = Прокси.ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "tzKind" );
tzKind = Прокси.ФабрикаXDTO.Создать(tzKindТип);
//
kindOfTariffТип = Прокси.ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "kindOfTariff" );
kindOfTariff = Прокси.ФабрикаXDTO.Создать(kindOfTariffТип);
kindOfTariff.name = "Тестовый вид тарифа";
kindOfTariff.active = ложь;
//
elementKindТип = Прокси.ФабрикаXDTO.Тип("http://www.vnedrenie-upp.ru/tariffs", "elementKind" );
elementKind = Прокси.ФабрикаXDTO.Создать(elementKindТип);
elementKind.eKind = kindOfTariff;
elementKind.qty = 10;
// Добавляем строку в таблицу
tzKind.el.Добавить(elementKind);
//
XDTOРезультат = Прокси.GetTzTzriffs_1(tzKind);
ПримерРезультат_НаименованиеВидаТарифа = XDTOРезультат.el[2].eTariff.kind.name;
Возврат ПримерРезультат_НаименованиеВидаТарифа;
КонецФункции

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Обращу ваше внимание на конструкцию: Прокси.ФабрикаXDTO.Тип("...

Т.е создавая на клиенте объект пакета XDTO мы должны обращаться не к собственной фабрике XDTO!, а через Прокси. Т.е к фабрике XDTO сервера.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
А теперь настала пора задаться вопросом: нет ли альтернативы объектам XDTO ?

Можно ли вообще "не связываться" с фабрикой XDTO , передавать/принимать с WEB -сервиса как-то иначе.. (тем более, если клиент не 1С, а например WEB -страница, приложение на Android , iOS и пр) .

Ответ такой – да, можно!
Например, можно в качестве типов параметров использовать строку. А в нее "упаковывать" (сериализовывать) структуры данных.

Такая технология в WEB-программировании давно разработана и называется JSON.
Большим подспорьем является и то, что в PHP упаковка/извлечение любой структуры/массива строку выполняется в одно действие!
Пример в PHP упаковки объектов в JSON/извлечения, передачи/приемки на WEB-сервис:

///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////

// сериализация массив mDelivery в строку и поместим в параметр delivery
// * Сначала опишем структуру delivery
class delivery {
var $id;
var $checked;
var $value;
}
// Заполним структуру некоторыми данными
$sDelivery = new delivery;
$sDelivery->id = '000000005';
$sDelivery->checked = TRUE;
$sDelivery->value = 0;
// Добавим ее в массив объектов mDelivery
$mDelivery[] = $sDelivery;
// Преобразуем массив mDelivery в JSON строку и поместим результат в параметр delivery
$params["delivery"] = json_encode($mDelivery);
// Вызовем операцию ExitCalcOrder на WEB-сервисе и передадим в нее параметр (строку - delivery);
$result = $client->ExitCalcOrder($params);
// Получим в переменную jsCalcResult (строку) результат выполнения операции ExitCalcOrder
$jsCalcResult = $result->return;
// Выполним обратное преобразование: из строки jsCalcResult в объект (массив объектов, типа соответствие) arrCalcResult
$arrCalcResult = json_decode($jsCalcResult);
// Выведем информацию на экран , об объекте arrCalcResult
var_dump($arrCalcResult);

/////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

- А как же выполнять JSON преобразования в 1С ?
Платформа 1С 8 не поддерживает стандарт JSON, но это - не беда.
Существует, доступна и прекрасно работет обработка преобразования/извлечения из JSON от
// Copyright © 2010-2012 Александр Переверзев
// 1С:JSON. JavaScript Object Notation парсер и сериализатор.

Таким образом, достаточно поместить эту обработку вашу конфигурацию и вы сможете с лекгостью выполнять прямые и обратные JSON-преобразования:
Пример сериализации объекта 1С в JSON строку:

///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

ДанныеПоГрузу = новый Структура;
ДанныеПоГрузу.Вставить("code",КодГруза);
ДанныеПоГрузу.Вставить("number",НомерГруза);
ДанныеПоГрузу.Вставить("plan",КолвоПлан);
ДанныеПоГрузу.Вставить("character",ХарактерГруза);
ДанныеПоГрузу.Вставить("packing",Упаковка);
ДанныеПоГрузу.Вставить("damage",ПовреждениеУпаковки);
ДанныеПоГрузу.Вставить("volume",Объем);
ДанныеПоГрузу.Вставить("weight",Вес);
ДанныеПоГрузу.Вставить("status",Статус);
JSON = Обработки.JSON.Создать();
jsResult = JSON.ЗаписатьJSON(ДанныеПоГрузу); //Преобразуем результат в JSON
Возврат jsResult;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Пример извлечения объекта в 1С из JSON строки:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 1. Восстановим объекты из JSON
JSON = Обработки.JSON.Создать();
мdelivery = JSON.ПрочитатьJSON(delivery);
// в результате, мdelivery - это массив. Элемент массива - соответствие.
// Т.е, например, мdelivery[0].["id"] будет содержать '000000005'

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
В завершении, приведу пример вызова web-сервиса 1с из PHP, c получением возвращаемой JSON структуры ее обратного преобразования в объекты PHP.

Обратим внимание на преобразования iconv('cp1251','utf-8',"
и iconv('utf-8','cp1251', которые потребуются (при взаимодействии PHP - 1 C ) для преобразования строк кириллицы из кодировки cp 1251 в utf -8 и обратно.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

<?php
error_reporting( E_ERROR ); // Отключаем сообщения
// Отключаем кэширование для SOAP. Если этого не сделать,
// функции веб-сервисов будут работать некорректно.
ini_set("soap.wsdl_cache_enabled", "0" );
$client = new SoapClient("http://localhost/wsBase10/ws/wsQuery.1cws?wsdl" );
$params["fname"] = iconv('cp1251','utf-8',"dataFreight" );
$params["param1"] = iconv('cp1251','utf-8',$_GET['code'] );
$params["param2"] = iconv('cp1251','utf-8',$_GET['number'] );
$result = $client->executeQuery($params);
$jsResult = $result->return;
$dataFreight = json_decode($jsResult);
$statusFreight = $dataFreight->codeNm;
$numberFreight = iconv('utf-8','cp1251',$dataFreight->nameRus);
?>

///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////

В заключении данного раздела хочу еще поделиться советом в части отладки WEB -сервисов 1С.

Вероятный сценарий такой: удаленный пользователь из некой своей программы (например, с WEB-сайта, мобильного приложения и др.) вызывает ваш WEB-сервис и… не получает результатов.. Либо получает, но что-то не то. smile:-(

Вопрос: - Как узнать о таких ошибках и отлаживать работу WEB-сервиса?
Рекомендую вам использовать для мониторинга ошибок (и сбора входящих параметров «что привело web-сервис к ошибке) журнал регистрации.

Т.е. в месте возможного возникновения логических ошибок програмно сохранять информацию о входящих параметрах в журнале регистрации (ЗаписьЖурналаРегистрации)

Если вы «боретесь» с «ошибками времени исполнения», то их можно перехватывать (попытка – исключение) и «точечно» протоколировать всю ситуацию.

В итоге, по журналу регистрации вы сможете увидеть информацию об ошибках, воспроизвести параметры возникновения и уже в интерактивном режиме, в отладчике, «победить» ее.

Подведем итоги: Примеры работы с WEB-сервисами из 1С и PHP рассмотрены. Для передачи объектных структур данных между клиентом и сервером мы воспользовались двумя технологиями:
(1) Пакеты XDTO
(2) JSON объекты.


4. Альтернатива - REST Web-сервисы (http-запросы). Примеры реализации в 1С и PHP.
В предыдущем разделе мы подробно рассматривали технологию WEB-сервисов. В этом же разделе рассмотрим альтернативную технологию, т.н. REST Web-сервисы.

Возникает справедливый вопрос: - Зачем ?

WEB-сервисы вполне функциональны и позволяют решать задачи любой сложности.

Что бы понять "зачем", сформулируем базовые различия между этими технологиями.

В основе технологии WEB-сервисов - 2 момента:
(1) Используется SOAP-соединение. Другими словами, выполняется SOAP-запрос.
В "1С" soap соединение форомируется так:
/////////////////////////////////////////////////////////////////////////////////////////

Определения = новый WSОпределения("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl",ИмяПользователя,Пароль);
Прокси = новый WSПрокси(Определения,"www.URI.com","_РасчетыПоТарифам","_РасчетыПоТарифамSoap" );

/////////////////////////////////////////////////////////////////////////////////////////

В PHP так:

/////////////////////////////////////////////////////////////////////////////////////////

$client = new SoapClient("http://localhost/wsBase10/ws/calcOrder10.1cws?wsdl",
array(
'login' => login, //логин,
'password' => pass, //пароль
'trace' => true,
'features' => SOAP_USE_XSI_ARRAY_TYPE,
//'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5
)
);

/////////////////////////////////////////////////////////////////////////////////////////

(2) Для отработки soap-соединения в режиме сервера, в платформе 1С 8 предусмотрен специальный объект метаданных WEB-cервисы.

Более того, если в вашей задаче «1С» должна выступать в роли сервера, то альтернативы технологии WEB-серсивов 1С - нет.

- А когда же возможна альтернатива ?
Во-первых, когда «1С» выступает только в роли клиента;
Во-вторых, когда сервере с которым нужно работать (например сайт или какое-то WEB-приложение), не планируется поддержка SOAP-соединения.

- А какая альтернатива SOAP -соединению возможна ?

Очень "ходовой" вариант - http соединение.

В web-ориентированных системах (PHP, Android, iOS) работать с http-запросами проще, чем в SOAP-запросами. И для не очень сложных проектов технология http-запрос вполне подходит.

Классическим вариантом решения (методом http-запроса) является задача интеграции базы «1С» и WEB-сайта. Например, на сайт передается информацию по номенклатуре и ценам, обратно с сайта - информация о принятых заказах.

Характерно, что в типовых конфигурациях "1С" интеграция с сайтами как раз реализовывается средствами http -запросов.
И так, рассмотрим технологию http -запросов на примере взаимодействия 1С (клиент, 1 C 8 ) и WEB - cайта ( PHP , сервер).

1. Установка соединения и методы передачи параметров в http -запросе
Пример установки соединения с сервером со стороны 1С:
/////////////////////////////////////////////////////////////////////////////

Защищенное = Ложь;
HTTPConnect = новый HTTPСоединение("localhost/wsClient10/json/testHTTPQuery11.php",,,,,Защищенное);

////////////////////////////////////////////////////////////////////////////
Как известно, для передачи параметров от клиента на сервер, по http-протоколу, существуют два метода:

(1) Метод " get ";

Параметры (например, name и password) указываются непосредственно в URL-адресе вызова сервера.

Т.е интерактивный вызов скрипта (непосредственно из WEB-браузера) выглядел бы так:

В 1С:8 для программного вызова сервера (и передачи ему параметров методов Get) предусмотрен метод "Получить".

Пример:
Защищенное = Ложь;
HTTPConnect = новый HTTPСоединение("localhost",,,,,Защищенное);
HTTPConnect.Получить("wsClient10/json/testHTTPQuery11.php?nameVasya&password=123",ИмяВыходногоФайла);


где ИмяВыходногоФайла: Имя файла, в который помещаются данные возвращаемые с сервера.
Т.е в результате отработки запроса сервер возвращает в «1С» результат и далее (автоматически) формируется файл, в котором и содержится результат.

Соответственно, после этого в «1С» необходимо (программно) прочитать данный файл и извлечь из него полученный результат. Вот и все.

(2) Метод "post";

В этом варианте параметры не помещаются в URL-адрес, а передаются отдельно, в теле http соединения.

Понятно, что ключевым ограничение метода get является объем и содержание передаваемых данных. Т.е с помощью get можно передавать только символы, и длина URL-строки ограничена.

Методом post можно передавать данные различного содержания, в т.ч. и произвольные файлы.
Таким образом, post для задач интеграции более функционален и далее, будем работать с ним.

Для приема/передачи данных между «1С» и «WEB-сайтом» мы будет использовать текстовые файлы.
А "упаковывать/извлекать" данные из файлов будет с использование уже знакомой нам технологии JSON! Это практически избавит нас от необходимости "парсить" файл на стороне «1С» и на стороне PHP.

Для вызова сервера и передачи ему параметров методом "post" в 1С:8 предусмотрен метод: ОтправитьДляОбработки

И так, приведем пример, в котором на стороне 1С выполняются все действия по отработке http -запроса:

Сначала, распишем план действий (укрупнено):
Шаг A : Подготовка данных к передаче на сервер;
Шаг B : Установка http-соединения с сервером;
Шаг C : Формирование http-запроса и передача данных (точнее, файла с данными) методом "post";
Шаг D : Получение ответа от сервера (точнее входящего файла) и извеление полученных результатов из файла;
Шаг E : Удаление отработанных временных файлов (они больше нам не нужны smile:-))

А теперь, его программная реализация в «1С:8»

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 1. Заполним структуру передаваемых данных
postDataToPHP = новый Структура;
postDataToPHP.Вставить("param1","ivanon" );
postDataToPHP.Вставить("param2","ivan" );
postDataToPHP.Вставить("param3","ivanovich" );


// 2. Конвертируем данные в JSON строку
JSON = Обработки.JSON.Создать();
jsPostDataToPHP = JSON.ЗаписатьJSON(postDataToPHP);

// 3. Создадим временный исходящий (передаваемый на сервер методом POST)
// файл, поместим в него JSON строку.

тФайл = новый ТекстовыйДокумент;
строкаДанные = jsPostDataToPHP;
тФайл.ДобавитьСтроку(строкаДанные);

// 4. Получим имя для временного иcходящего файла. В нем будут содержаться исходящие данные в виде JSON-строки
ИмяИсходящегоФайла = ПолучитьИмяВременногоФайла(".txt" );
тФайл.Записать(ИмяИсходящегоФайла,КодировкаТекста.UTF);

// 5. Получим имя для временного входящего файла. В нем будет получена JSON-строка: ответ сервера PHP
ИмяВходящегоФайла = ПолучитьИмяВременногоФайла(".txt" );

// 6. Установим HTTP соединение с сервером
Защищенное = Ложь;
HTTPConnect = новый HTTPСоединение("localhost/wsClient10/json/testHTTPQuery10.php",,,,,Защищенное);

// 7. Выполним HTTP - запрос. Передадим на сервер исходящий файл (файл содержит JSON-объект, т.е исходящие параметры)


HTTPConnect.ОтправитьДляОбработки(ИмяИсходящегоФайла,"/json/",ИмяВходящегоФайла);


// И получим ответ от сервера (входящий файл). Файл содержит //JSON-объект (т.в возвращаемые с сервера данные)

// 8. Извелечем полученные от сервера данные из входящего файл
ФайлОтвета = новый ТекстовыйДокумент;
ФайлОтвета.Прочитать(ИмяВходящегоФайла,КодировкаТекста.UTF);
json_Data = ФайлОтвета.ПолучитьСтроку(1);
mData = JSON.ПрочитатьJSON(json_Data);

// 9. Выведем полученные данные для пользователя
Сообщить(mData["v1"] );
Сообщить(mData["v2"] );

// 10. Удалим использованные (не нужные более) временные файлы.
УдалитьФайлы(ИмяИсходящегоФайла);
УдалитьФайлы(ИмяВходящегоФайла);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Ну и наконец, пример на PHP по отработки запроса на стороне сервера:

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

<?php
// 1. Получим строковые данные из входящего файла
$json_filedata = file_get_contents('php://input');
// 2. Отрежем все лишнее (добавляются 2 служебных символа), что // мешает преобразованию из JSON
$jsData = trim(ltrim($json_filedata));
$dlinaStr = strlen($jsData);
$_jsData = '';
$i=1;
while ($i<$dlinaStr) {
if ($i>2) {
$_jsData = $_jsData.substr($jsData, $i, 1);
}
$i++;
}
// 3. Преобразуем данные из JSON в объект (структуру)
$mData = json_decode($_jsData);
// 4. Сформируем другую структуру, которую заполним данными и // вернем в 1С
class returnData {
var $v1;
var $v2;
}
$sReturnData = new returnData;
$sReturnData->v1 = $mData->param1;
$sReturnData->v2 = $mData->param2;
// 5. Преобразуем данные структуры в JSON строку
$json_returnData = json_encode($sReturnData);
// 6. Вернем данные в 1С (выводимые данные будут перенаправлены в файл, который и вернется в 1С)
echo $json_returnData;
?>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


Источник



Назад в раздел