Как это должно быть в 1С (подключение не буду описывать, там надо всего-навсего указать wsdl-файл):
Прокси = WSСсылки.Перл.СоздатьWSПрокси("http://it.selenia.ru/", "AWK", "AWK");
Результат = Прокси.pregMatch(Строка, Шаблон);
И написал я такой нехитрый PHP-код:
class AWKService { function pregMatch($str, $tmpl) { $res_str = ""; preg_match($tmpl, $str, $res); foreach( $res as $line ) { $res_str .= "" . $line . ""; } $res_str .= ""; return $res_str; } } $server = new SoapServer("./services.wsdl"); $server->setClass("AWKService"); $server->handle(); ?>
И wsdl:
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmln <wsdl:types> <xsd:schema targetNamespace="urn:pregwsdl"> <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/"/> <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/"/> </xsd:schema> </wsdl:types> <wsdl:message name="pregMatchRequest"> <wsdl:part name="str" type="xsd:string"/> <wsdl:part name="tmpl" type="xsd:sring"/></message> <wsdl:message name="pregMatchResponse"> <wsdl:part name="return" type="xsd:string"/></message> <wsdl:portType name="pregwsdlPortType"> <wsdl:operation name="pregMatch"> <wsdl:documentation>see preg_Match</documentation> <wsdl:input message="tns:pregMatchRequest"/> <wsdl:output message="tns:pregMatchResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="pregwsdlBinding" type="tns:pregwsdlPortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="pregMatch"> <soap:operation soapAction="urn:pregwsdl#pregMatch" style="rpc"/> <wsdl:input><soap:body use="encoded" namespace="urn:pregwsdl" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>< <wsdl:output><soap:body use="encoded" namespace="urn:pregwsdl" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </wsdl:operation> </binding> <wsdl:service name="pregwsdl"> <wsdl:port name="pregwsdlPort" binding="tns:pregwsdlBinding"> <soap:address location="http://it.selenia.ru/services.php"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
И получил от 1С при подключении: "Неверный формат", хотя на http://soapclient.com/SoapTest.html и формат прочитали и запрос выполнили. И пошел я другим путем. Воспользовался nuSOAP (мало ли я wsdl писать не умею):
// Подключаем код NuSOAP require_once('lib/nusoap.php'); // Создаем экземпляр сервера $server = new soap_server(); $server->configureWSDL('AWK','http://it.selenia.ru'); $server->register('pregMatch', array('str' => 'xsd:string', 'tmpl' => 'xsd:string'), array('result' => 'xsd:string'), 'http://it.selenia.ru', 'http://it.selenia.ru#pregMatch', 'rpc', 'encoded', 'Уфф...'); // Определяем метод как функцию PHP function pregMatch($str, $tmpl) { $res_str = ""; preg_match($tmpl, $str, $res); foreach( $res as $line ) { $res_str .= "" . $line . ""; } $res_str .= ""; return $res_str; } // Используем HTTP-запрос чтобы вызвать сервис $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ''; $server->service($HTTP_RAW_POST_DATA); ?>
Но опять, при подключении http://it.selenia.ru/services.php?wsdl - "Неверный формат".
Не буду вас долго мучить и приведу работающий код:
// Подключаем код NuSOAP require_once('lib/nusoap.php'); // Создаем экземпляр сервера $server = new soap_server(); $server->configureWSDL('AWK','http://it.selenia.ru'); $server->wsdl->addComplexType( 'ArrayOfString', 'complexType', 'array', 'all', '', array( 'dn' => array('name' => 'dn', 'type' => 'xsd:string', 'minOccurs' => '0', 'maxOccurs' => 'unbounded') ) ); $server->register('pregMatch', array('str' => 'xsd:string', 'tmpl' => 'xsd:string'), array('result' => 'tns:ArrayOfString'), 'http://it.selenia.ru', 'http://it.selenia.ru#pregMatch', 'rpc', 'encoded', 'Уфф...'); // Определяем метод как функцию PHP function pregMatch($str, $tmpl) { preg_match($tmpl, $str, $res); return $res; } // Используем HTTP-запрос чтобы вызвать сервис $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ''; $server->service($HTTP_RAW_POST_DATA); ?>
А теперь можно поразмыслить на тему: "Где еще, кроме SQL, напортачил 1С?"
P.S. По мотивам комментариев.
Если вы думаете, что после этого удалось нормально пользоваться web-сервисом, то вы ошибаетесь. Были и еще пляски с бубном.
И огромную благодарность я выражаю всем, кто принял участие в тестировании. Отдельная благодарность Трактор и dushelov за их помощь в получении конечного положительного результата.
Итак, код, который можно нормально использовать:
<?php // Подключаем код NuSOAP require_once('lib/nusoap.php'); // Создаем экземпляр сервера $server = new soap_server(); // Вместо document можно использовать rpc, но у меня не прошло $server->configureWSDL('AWK','[url]http://it.selenia.ru[/url]','','document'); $server->decode_utf8 = false; $server->soap_defencoding = 'UTF-8'; //Определяем массив $server->wsdl->addComplexType( 'ArrayOfString', 'complexType', 'array', '', 'SOAP-ENC:Array', array(), array( array('ref'=>'SOAP-ENC:Array', 'wsdl:arrayType' => 'SOAP-ENC:string[]', 'arrayType' => 'SOAP-ENC:string[]', 'nillable'=>'true' )), 'SOAP-ENC:string' ); // Регистрируем метод $server->register('pregMatch', array('str' => 'xsd:string', 'tmpl' => 'xsd:string'), array('return' => 'tns:ArrayOfString'), '', '', 'document', 'literal'); // Определяем метод как функцию PHP function pregMatch($str, $tmpl) { if (preg_match('@^(.).*\1.?$@i',$tmpl) == 0) { return new soap_fault('SERVER', '', 'bad template',$tmpl); } else { preg_match($tmpl, $str, $res); } return $res; } // Используем HTTP-запрос чтобы вызвать сервис $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ''; $server->service($HTTP_RAW_POST_DATA); ?>
Баги есть в релизе 8.2.9.356 - в 8.2.10.73 они исправлены.
И еще. Если вы при подключении получите 407 ошибку, то скорее всего в этом виноват прокси-сервер. Я из-за него долго не мог получить результат, так как 1С просто вылетала. Спасибо Visual Studio - оно дало и описание ошибки и направление его исправления. Если у вас стоит SQUID, то лечится это добавлением сторочки в squid.conf (ignore_expect_100 on). На этом вроде бы все.