ConFoo 2025

PHP и COM

На платформах Win32 языком PHP пользуются для доступа к COM- и DCOM-объектам.

  1. Я собрал DLL-библиотеку для вычислений. Каким способом запустить DLL-файл под PHP?
  2. Что значит 'Unsupported variant type: xxxx (0xxxxx)'?
  3. Возможно ли манипулирование визуальными объектами в PHP?
  4. Можно ли сохранять COM-объект в сессии?
  5. Как отлавливать ошибки COM?
  6. Можно ли генерировать DLL-файлы из PHP-скриптов так, как это делают в языке Perl?
  7. Что значит 'Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'?
  8. Как COM-объекты запускают с удалённого сервера?
  9. Я получаю 'DCOM is disabled in C:\path...\scriptname.php on line 6', что делать?
  10. Умеет ли PHP загружать и манипулировать объектом ActiveX на странице?
  11. Можно ли получить экземпляр компонента, который выполняется?
  12. Как обработать событие, которое отправил COM-объект?
  13. При попытке вызвать метод COM-объекта возникли проблемы, который даёт больше одного интерфейса. Что делать?
  14. Итак, PHP работает с моделью COM, а что насчёт технологии COM+?
  15. Раз PHP умеет манипулировать COM-объектами, можно ли представить, что служба MTS управляет ресурсами компонентов в сочетании PHP?
Я собрал DLL-библиотеку для вычислений. Каким способом запустить DLL-файл под PHP?

PHP пока не умеет запускать просто DLL-библиотеки, но если DLL-файл содержит COM-сервер и библиотека реализует интерфейс IDispatch, для PHP откроется доступ к такому серверу.

Что значит 'Unsupported variant type: xxxx (0xxxxx)'?

В конкретных языках программирования определяют десятки типов данных VARIANT и их комбинаций. Бо́льшую часть вариантов PHP уже поддерживает, но отдельные варианты в языке по-прежнему не реализовали. Массивы поддерживаются не на 100 %. Между PHP и COM разрешается передавать только одномерные индексные массивы. Пожалуйста, сообщите о других типах как об ошибке, если не сделали это раньше, если обнаружите типы, которые PHP не поддерживает, и дайте как можно больше информации.

Возможно ли манипулирование визуальными объектами в PHP?

Да, PHP умеет манипулировать визуальными объектами, но поскольку PHP чаще работает как язык веб-скриптов и запускается в контексте веб-сервера, визуальные объекты не появятся на рабочем столе сервера. Доступ и манипулирование визуальными объектами через COM не ограничиваются, когда на PHP пишут приложения, например, в связке с модулем PHP-GTK.

Можно ли сохранять COM-объект в сессии?

Нет, нельзя, поскольку экземпляры COM рассматриваются как ресурсы, они доступны только в контексте одного скрипта.

Как отлавливать ошибки COM?

Модуль COM выбрасывает исключение com_exception, которое перехватывают, а затем проверяют в исключении свойство code, чтобы понять, что делать дальше.

Можно ли генерировать DLL-файлы из PHP-скриптов так, как это делают в языке Perl?

Нет, для PHP такого инструмента нет.

Что значит 'Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'?

Эта ошибка возникает по разным причинам:

  • неправильный ключ CLSID
  • DLL-библиотека, которую запросили, отсутствует
  • компонент, который запросили, не реализует интерфейс IDispatch

Как COM-объекты запускают с удалённого сервера?

Точно так же, как запускают локальные объекты. Потребуется только передать IP-адрес удалённой машины как второй параметр конструктора COM.

Убедитесь, что включили директиву com.allow_dcom=true в файле php.ini

Я получаю 'DCOM is disabled in C:\path...\scriptname.php on line 6', что делать?

Отредактируйте файл php.ini и включите директиву com.allow_dcom=true.

Умеет ли PHP загружать и манипулировать объектом ActiveX на странице?

Это не имеет отношения к PHP. Объекты ActiveX загружаются на стороне клиента, если их запросил HTML-документ. Связи с PHP-скриптом здесь нет, поэтому прямое взаимодействие со стороны сервера невозможно.

Можно ли получить экземпляр компонента, который выполняется?

Экземпляр получают через моникеры (англ. monikers). Экземпляр создают вот так, когда требуется получить больше одной ссылки на один и тот же экземпляр Word:

<?php

$word
= new COM("C:\docs\word.doc");

?>

Код создаст новый экземпляр, если нет доступного запущенного экземпляра, или вернёт дескриптор запущенного экземпляра, если экземпляр доступен.

Как обработать событие, которое отправил COM-объект?

Приёмник события определяют и привязывают функцией com_event_sink(). Скелет класса приёмника событий функция в PHP генерирует функция com_print_typeinfo().

При попытке вызвать метод COM-объекта возникли проблемы, который даёт больше одного интерфейса. Что делать?

Ответ настолько же простой, насколько и неудовлетворительный. Точно не известно, но, скорее всего, ничего сделать невозможно.

Итак, PHP работает с моделью COM, а что насчёт технологии COM+?

Технология COM+ расширяет модель COM за счёт платформы управления компонентами через службу MTS и MSMQ-очередь, но PHP не поддерживает ничего отдельно, чтобы работать с такими компонентами.

Раз PHP умеет манипулировать COM-объектами, можно ли представить, что служба MTS управляет ресурсами компонентов в сочетании PHP?

Сам PHP пока не обрабатывает транзакции. Поэтому, если возникает ошибка, откат не инициируется. При работе с компонентами, которые поддерживают транзакции придётся реализовать управление транзакциями самому.

Добавить

Примечания пользователей 3 notes

up
10
Anonymous
19 years ago
Re: The Windows English CHM Sample with MS Word Automation.

I see that $Word->Release() is called after $Word->Quit().
This seems to be erroneous. Actually, $Word->Release() should not have to be called if proper COM garbage collection is taking place. Release() is a C++ construction not used in either Visual Basic or VBScript or even MS-JScript. Just to be sure, however, I ran the sample through php.exe (5.04 CLI on Windows XP SP1 with Office 2003) and got a RPC failed error on the line containing $Word->Release(). The rest of the sample works fine, and the results are as expected. So, I propose 2 scenarios:
1.There is a problem with the documentation (more likely).
2.There is a problem with PHP504 itself, as this problem is reproduced with any COM Automation call, not just Word.
up
9
junk.ghost@virgin dOtt net
20 years ago
It may be obvious to everyone else but...

If you want to write your own COM DLL in MSVC++6 and you want to pass it a string, you need the following in your .idl file:

HRESULT function_name([in] BSTR parameter_name,
[retval, out] BSTR * retval);

retval is the result of your function as a string to be passed back.

BSTR is an unsigned short *, so if you want to use your string with STL string etc. you may need to convert parameters to and from char *.

The burden of my message is that from PHP

$comThing = new COM("comThing.comThing");
print $comThing->function_name("Jeremy");

Jeremy will be marshalled as wide chars, which match BSTR.
up
4
codeslinger at compsalot dot com
17 years ago
in response to item #1 above: "If this is a simple DLL there is no way yet to run it from PHP."

Answer: There are several different packages/add-ons to php that enable low level access to the windows api. One of the most popular of these packages is available at http://www.winbinder.org

Winbinder does have the ability to load a dll and call it's functions. Winbinder also provides a large set of windows apis for creating windows and controls. This is useful for creating stand-alone desktop apps. It is a possible alternative to php-gtk.

I've had mixed results with Winbinder, some things work very well, others are buggy; source code is available. It's worth a look, Evaluate carefully.
To Top