PHP と COM
PHP は Win32 プラットフォーム上で COM と DCOM オブジェクトに アクセスすることができます。
- とある計算を行う DLL を作成しました。これを PHP で実行させる方法は ありますか?
- 'Unsupported variant type: xxxx (0xxxxx)'とはどういう意味ですか?
- PHP でビジュアルオブジェクトを操作できますか?
- COM オブジェクトをセッション情報として保存できますか?
- COM の出力するエラーをトラップできますか?
- PHP スクリプトから DLL を作成することはできますか? Perl では できるのですが。
- 'Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'とはどういう意味ですか?
- COM オブジェクトをリモートサーバーから実行するにはどうすればよいですか?
- 'DCOM is disabled in C:\path...\scriptname.php on line 6' という エラーが発生しました。どうすればよいですか?
- PHP を使用したページで ActiveX オブジェクトをロード/操作することは できますか?
- 実行中のコンポーネントのインスタンスを取得することはできますか?
- COM オブジェクトから送られてくるイベントを扱う方法はありますか?
- 2 つ以上のインターフェイスを公開している COM オブジェクトのメソッドを 呼び出そうとして困っています。どうすればよいですか?
- PHP は COM を扱えるということは分かりました。では COM+ については どうですか?
- PHP が COM オブジェクトを操作することができるということは、MTS を 使ってコンポーネントリソースを扱えると考えてもよいということですか?
- とある計算を行う DLL を作成しました。これを PHP で実行させる方法は ありますか?
-
もしそれが普通の DLL なら、現在のところ PHP からそれを実行する手段は ありません。DLL が COM サーバーを含んでいて IDispatch インターフェイスが 実装されている場合、PHP からアクセスすることができます。
- 'Unsupported variant type: xxxx (0xxxxx)'とはどういう意味ですか?
-
多くの VARIANT タイプとその組み合わせがあり、そのほとんどは サポートされていますが、残りのいくつかは未だ実装されていません。 また配列も完全にサポートされているわけではなく、PHP と COM の間で 受け渡しが可能なのは 1 次元の添字付配列のみです。もしこの他に サポートされていないタイプを見つけた場合は(既知でなければ)、 できる限りの情報を添えてバグとして報告してください。
- PHP でビジュアルオブジェクトを操作できますか?
-
基本的には可能です。しかし PHP はほとんどの場合ウェブスクリプティングの 言語として使用されウェブサーバー上で実行されるため、ビジュアルオブジェクトが サーバーのデスクトップに現れることはありません。もし PHP を アプリケーション作成に使用する、すなわち PHP-GTK と合わせて 使用する場合にはアクセスに制限はありません。COM を通じて ビジュアルオブジェクトを操作することができます。
- COM オブジェクトをセッション情報として保存できますか?
-
できません。COM インスタンスはリソースとして扱われるため、1 つの スクリプトを実行している間のみ使用可能です。
- COM の出力するエラーをトラップできますか?
-
COM 拡張モジュールは
com_exception
例外をスローします。これをキャッチし、code
メンバを調べることで次にすべきことを決定できます。
- PHP スクリプトから DLL を作成することはできますか? Perl では できるのですが。
-
いいえ、残念ながら PHP にはそのようなツールはありません。
- 'Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'とはどういう意味ですか?
-
このエラーが発生する理由はいくつかあります。
- CLSID が正しくない
- 要求された DLL が無い
- 要求されたコンポーネントが IDispatch インターフェイスを実装していない
- COM オブジェクトをリモートサーバーから実行するにはどうすればよいですか?
-
ローカルオブジェクトを実行するのと全く同様です。ただ、COM コンストラクタの 2 番目のパラメータにリモートマシンの IP アドレスを 渡すだけです。
php.ini に com.allow_dcom
=
true
をセットするのを忘れないでください。
- 'DCOM is disabled in C:\path...\scriptname.php on line 6' という エラーが発生しました。どうすればよいですか?
-
php.ini を編集して com.allow_dcom
=
true
. としてください。
- PHP を使用したページで ActiveX オブジェクトをロード/操作することは できますか?
-
これは PHP とは関係ありません。ActiveX オブジェクトは、HTML ドキュメントから要求があった場合にクライアント側でロードされます。 PHP スクリプトとは関係が無く、従ってサーバー側と直接やりとりすることも できません。
- 実行中のコンポーネントのインスタンスを取得することはできますか?
-
モニカーを使用すれば可能です。同じ Word インスタンスに対して複数の 参照を取得したい場合は、以下のようにしてインスタンスを生成します。
<?php $word = new COM("C:\docs\word.doc"); ?>
こうすれば、実行中のインスタンスが無い、もしくはインスタンスの 取得が不可能だった場合には新規に生成され、インスタンスが取得できた 場合にはそのハンドルを返します。
- COM オブジェクトから送られてくるイベントを扱う方法はありますか?
-
イベントシンクを定義し、com_event_sink() を使用してそれをバインドすることが可能です。PHP でイベントシンククラスの 雛形を作成するために com_print_typeinfo() を 使用することが可能です。
- 2 つ以上のインターフェイスを公開している COM オブジェクトのメソッドを 呼び出そうとして困っています。どうすればよいですか?
-
この問題に対する答えは、簡単ですが残念なものです。正確には わかりませんが、おそらく打つ手はありません。
- PHP は COM を扱えるということは分かりました。では COM+ については どうですか?
-
COM+ とは MTS(Microsoft Transaction Server) と MSMQ(Microsfot Message Queue Service) を通じてコンポーネントを操作する フレームワークによって COM を拡張したものです。が、PHP がそういった コンポーネントをサポートするにあたって特別に必要なことはありません。
- PHP が COM オブジェクトを操作することができるということは、MTS を 使ってコンポーネントリソースを扱えると考えてもよいということですか?
-
PHP それ自体はまだトランザクションをサポートしていません。従って エラーが発生してもロールバック処理は行われません。もし トランザクションをサポートするコンポーネントを使用する場合は、 自分でトランザクション処理を実装する必要があります。
User Contributed Notes 3 notes
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.
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.
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.