barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

воскресенье, 20 ноября 2011 г.

Как мне НЕ удалось подружить WSO2 WSF/PHP 2.1.0 и 1С-Битрикс Веб-Окружение 2.1.

Собственно возникла необходимость использования внутри компонента 1С-Битрикс функционала SOAP-клиента, и для этого был выбран WSO2 WSF/PHP (http://wso2.org/library/wsf/php).
Для начала был скачан бинарник WSF/PHP версии 2.1.0, распакован (в директорию "F:\Install\wso2-wsf-php-bin-2.1.0-win32\"), wsf.dll был положен в папку "apache2\zendserver\lib\phpext\" относительно директории установки окружения 1С-Битрикс. В php.ini Битрикса (apache2\zendserver\etc\php.ini) были внесены следующие изменения:
...
[Zend]
include_path=".;F:\Install\wso2-wsf-php-bin-2.1.0-win32\scripts"
...
extension=php_xsl.dll
extension=wsf.dll
...
wsf.home="F:\Install\wso2-wsf-php-bin-2.1.0-win32\wsf_c"
wsf.log_path="F:\Install\wso2-wsf-php-bin-2.1.0-win32\wsf_c\logs"
wsf.log_level=3
wsf.rm_db_dir="F:\Install\wso2-wsf-php-bin-2.1.0-win32\wsf_c"
...
Однако при попытке запустить битрикс стала появляться ошибка о том, что не найден файл "php5ts.dll". Действительно, в директории apache2\zendserver\bin можно найти только php5.dll, т.к. php в Битриксе видимо не-threadsafe. Ладно, попробуем подложить туда ещё и php5ts.dll (взят он был из php 5.3.5). Теперь сообщение об отсутствующем php5ts.dll ушло, однако расширение wsf все равно не подключается, а в логах видим:
[20-Nov-2011 17:23:36] PHP Warning:  PHP Startup: wsf: Unable to initialize module
Module compiled with build ID=API20090626,TS,VC9
PHP    compiled with build ID=API20090626,NTS,VC9
These options need to match
 in Unknown on line 0
Теперь build ID модуля конфликтует с версией битриксовского php - у битрикса php non-threadsafe, о чем говорит аббревиатура NTS, а модуль собран для threadsafe (TS). 
Придется видимо собирать WSF из сорцов, благо они есть на wso2.org.
Помимо самих сорцов, пришлось скачать и установить Win32 OpenSSL (http://www.slproweb.com/products/Win32OpenSSL.html), ну и конечно же, понадобилась Visual Studio. Лучше девятка (2008). У меня была только 2010, что в дальнейшем и послужило граблями. Также понадобились исходники и бинарники php, которые были скачаны с php.net (бинарники, правда, были взяты threadsafe, что в дальнейшем послужило проблемой). В принципе, в качестве бинарников можно было взять php из самого Битрикса, однако их там в явном виде не присутствует, т.к. в основе окружения битрикса лежит Zend Server, так что пришлось брать со стороны.
Для того, чтобы собрать не-threadsafe версию WSF/PHP, нужно в configure.in распакованных исходников закомментировать строку:
# ZTS =1
Далее в этом же файле нужно прописать путь к директории установки Open SSL, к исходниками и бинарникам php. В моём случае это выглядело так:
OPENSSL_BIN_DIR = E:\Programs\OpenSSL-Win32
PHP_SRC_DIR = F:\Install\php-5.3.8-src
PHP_BIN_DIR = C:\php\php5.3.8
Перед сборкой необходимо проверить, что директория VC\bin относительно директории установки Visual Studio включена в PATH.
Пробуем собрать, запуская build.bat в директории исходников WSF/PHP, однако получаем ошибку:
f:\install\php-5.3.8-src\zend\zend_config.w32.h(25) : fatal error C1083: Cannot open
include file: '../main/config.w32.h': No such file or directory
Оказывается, прежде чем выполнять build.bat исходников WSF/PHP, нужно запустить в директории исходников php:
buildconf.bat
cscript configure.js
После этого при запуске cscript вылезла ошибка "Отсутствует исполняющее ядро для расширения имени файла ".js"" - см. http://barbitoff.blogspot.com/2011/11/cscript-js.html, потом -  "The application has failed to start bacause mspdb100.dll was not found ..." при попытке вызова cl.exe, пришлось предварительно запустить vcvars32.bat из Visual Studio (см. http://barbitoff.blogspot.com/2011/11/ms-visual-studio-clexe-mspdb100dll-not.html).
Но и тут ждет неудача:
ERROR: bison is required
Идем на http://gnuwin32.sourceforge.net/packages/bison.htm, качаем и устанавливаем Бизон, добавляем путь к его исполняемым файлам (расположены в bin директории) в PATH.
После этого configure.js отработал удачно, создав недостающий ранее файл "main/config.w32.h".
Возвращаемся в исходники WSF/PHP, жмем build.bat, но снова ошибка:
LINK : fatal error LNK1181: cannot open input file 'php5.lib'
Библиотеку линкер ищет в бинарниках php, и, естественно, там её не находит, т.к. бинарники threadsafe, и там есть только php5ts.lib. Берем php5.lib из "apache2\zendserver\bin" Битрикса, кладем в папку dev бинарников php. Снова делаем build.bat... и ура, WSF собрался.
Кладем wsf.dll куда надо, меняем пути в php.ini к новым, только что собранным директориям. Пытаемся запустить Битрикс, и видим в логах:
[20-Nov-2011 21:21:12] PHP Warning:  PHP Startup: wsf: Unable to initialize module
Module compiled with build ID=API20090626,NTS,VC10
PHP    compiled with build ID=API20090626,NTS,VC9
These options need to match
 in Unknown on line 0
Да, теперь не совпадает версия студии. И на этом моменте надо было бы поискать 2008 студию, но я решил обмануть php. В Zend\zend_build.h исходников php поправил 
#define ZEND_BUILD_SYSTEM "," PHP_COMPILER_ID
на 
#define ZEND_BUILD_SYSTEM ",VC9"
Пересобрал WSF/PHP. Модуль наконец-таки загрузился, вот только примеры из дистрибутива не работают, php падает молча, а в логах винды видно:
Имя сбойного приложения: php-cgi.exe, версия: 5.3.2.0, отметка времени: 0x4c0b8710
Имя сбойного модуля: MSVCR90.dll, версия: 9.0.30729.4974, отметка времени 0x4b7a226f
Код исключения: 0xc0000005
Смещение ошибки: 0x0003ae7a
Идентификатор сбойного процесса: 0x20fc
Время запуска сбойного приложения: 0x01cca817c8b93692
Путь сбойного приложения: E:\Programs\Bitrix Environment\Apache2\ZendServer\bin\php-cgi.exe
Путь сбойного модуля: C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4974_none_50940634bcb759cb\MSVCR90.dll
Код отчета: 0845dff7-140b-11e1-8fee-fcf4765882af
Мда, придется все-таки пересобрать 9ой студией, вдруг поможет.
2008 студия поставлена, теперь нужно перезапустить config.js исходников php (на всякий случай), для этого потребуется, чтобы в PATH были директории "Common7\Tools" и "VC\bin" 2008 студии, причем в таком порядке и перед путями к 2010 студии (удобнее менять в данном случае не глобальный PATH системы, а устанавливать PATH командой set).

И да, слеши в путях в php.ini пришлось поставить в другую сторону, как в Unix ("/"), т.к. глупый WSF использует "/" независимо от платформы, конкатенируя свои пути с путями из php.ini.

Однако и после всех этих манипуляций собранная 2008-ой студией библиотека WSF работать отказалась, с теми же сообщениями в логах, что и собранная 2010-ой.

Плюнув на самостоятельную сборку non-threadsafe библиотеки WSF, я развернул битрикс не в его родном веб-окружении, а на wamp 2.2a, благо там php threadsafe и собран 2008-ой студией, т.е. бинарник WSF должен подойти. Собственно, ожидания оправдались, WSF подключился, тестовые примеры заработали.

Дальше правда всё снова стало грустно: при попытке создать клиент по моей wsdl WSF стал молча виснуть, ничего не говоря в логи, после чего я забил на него и воспользовался стандартной php-шной библиотекой php_soap, которая, по крайней мере по функционалу soap-клиента, ничем не хуже WSF.

4 комментария:

  1. Тоже промучался с WSO2, но заставить работать корректно так и не получилось, php_soap конечно неплохо работает, но передачу файлов в сообщениях не поддерживает. Так работающую библиотеку, умеющую передавать файлы по MTOM, под PHP найти так и не удалось.

    ОтветитьУдалить
  2. пользуюсь nusoap, очень удобно, сама генерит wsdl и вообще :)

    ОтветитьУдалить
  3. Респект кстати за проделанную работу, + еще и описание всех граблей, я тоже с этим nts php попарился когда настраивал wso/php.
    Смотрю у тебя есть опыт работы с СМЭВ/ЕГПУ, сейчас стоит такая задача:
    есть готовый сервис как раз на nusoap/php, но без ws-security.
    Чтобы не переписывать все с нуля есть мысль запустить его через wso2/esb и сделать секюрити на уровне шины.
    Ты я так понял его неплохо знаешь, подскажи, реально или нет, есть ли тут грабли и как их обойти :)
    Извини за объем, не понял как тут в личку написать :)

    ОтветитьУдалить
    Ответы
    1. Да, насчет esb мысль хорошая. Мы так и делали, правда в роли шины был IBM DataPower.
      Если тебе нужна ГОСТовая ЭЦП, то встроенные средства WSO2 не подойдут (вероятнее всего), но можно встроить проверку / формирование подписи как кастомный медиатор (если используется Java-криптопровайдер) или как внешний веб-сервис, который будет дергаться при медиации сообщения (мы так делали в случае с DataPower).
      ЗЫ если что, можешь писать в gtalk или на почту aspirin.spb@gmail.com

      Удалить