XV. COM と .Net (Windows)

導入

COM は Component Object Model の略語であり、 DCE RPC (オープンスタンダード) の最上位のオブジェクト指向レイヤーです。 COM はコール手順を共通化し、あらゆる言語でコードを記述し、 (COM に対応した)他の言語で書かれたコードをコール、相互運用することを可能にします。 あらゆる言語で書くことを可能にするだけではなく、 同じ実行形式の一部となることすら不要です。 コードは、同じマシンで実行される他のプロセスのコードである DLL からロードしたり、 または、リモートマシン上の他のプロセスにあるコードを DCOM (分散 COM) で 利用することができます。 この場合、コードの中では、コンポーネントの存在する場所を意識する必要はありません。

OLE オートメーションと呼ばれる COM のサブセットがあります。 これは、COM オブジェクトに祖な結合を行うことができる COM インターフェイスを 提供します。これにより、コンパイル時にオブジェクトの動作を知ることなく、 実行時にコールを行うことができるようになります。 PHP COM 拡張モジュールは、OLE オートメーションを使用して スクリプトから互換性のあるオブジェクトを作成/コールすることができます。 技術的に述べると、 全ての COM オブジェクトが OLE 互換であるというわけではないため、 実際には、この拡張モジュールは "PHP の OLE オートメーション 拡張モジュール" と呼ばれるべきものです。

ところで、なぜ COM を使用する必要があるのでしょう? COM は、 Windows 環境でアプリケーションとコンポーネントを結び付ける代表的な手法の一つで、 COM を使用して Microsoft Word を起動し、 ドキュメントテンプレートを埋めて、Word 文書として結果を保存し、Web サイトの 訪問者に送信することができます。 また COM を使用して、ネットワークの管理タスクを処理したり IIS を設定したりすることができます。これらは最も一般的な使用法にすぎません。 COM でできることはまだまだたくさんあります。

PHP 5 以降、この拡張モジュール(とこの文書)は最初から書き直され、 古い紛らわしい部分は削除されました。さらに Microsoft により提供された COM との相互運用レイヤーを用いて .Net アセンブリのインスタンス化と生成をサポートしました。

PHP 5 におけるこの拡張モジュールの変更点の概要については、 この文章 を参照してください。

要件

COM 関数は、Windows 版の PHP でのみ利用可能です。

.Net サポートは、PHP 5 と .Net ランタイムを必要とします。

インストール手順

PHP コアに含まれるため、 追加のインストール無しで使用できます。

Windows 版の PHP には この拡張モジュールのサポートが組み込まれています。これらの関数を使用 するために拡張モジュールを追加でロードする必要はありません。

あなたには、(MS Word のような)使用する様々な COM オブジェクトのインストールを正しく 行っておく責任があります。 PHP にこれら全てをバンドルすることはできません。

foreach

PHP 5 以降、標準的な COM/OLE IEnumVariant の内容について、 PHP の foreach 命令を使用した反復処理を行うことができます。分かりやすく言うと、 これは、VB/ASP のコードで For Each を使用できる場所には foreach を使用できるということを意味します。

例 1. ASP における For Each

<% Set domainObject = GetObject("WinNT://Domain") For Each obj in domainObject   Response.Write obj.Name & "<br />" Next %>

例 2. PHP 4 におけるwhile() ... Next()

<?php
$domainObject
= new COM ( "WinNT://Domain" );
while (
$obj = $domainObject -> Next ()) {
   echo
$obj -> Name . "<br />" ;
}
?>

例 3. PHP 5 における foreach

<?php
$domainObject
= new COM ( "WinNT://Domain" );
foreach (
$domainObject as $obj ) {
   echo
$obj -> Name . "<br />" ;
}
?>

配列と配列形式の COM プロパティ

多くの COM オブジェクトは、プロパティを配列で公開したり 配列形式を使用してアクセスできるようにしています。 PHP 4 では、PHP の配列構文を使用してこれらのプロパティに対する読み書きが できますが、1 次元の配列のみがサポートされます。多次元のプロパティを 読み込みたい場合は、プロパティへのアクセスを関数コールに組み込んで 各パラメータを入れtうの各次元に対応させるという方法が可能ですが、 そのようなプロパティに対する書き込みの手段はありません。

PHP 5 では以下の新機能を用いることで多少ましになりました。

  • 多次元配列・複数パラメータを要求する COM プロパティへの PHP の配列構文を使用したアクセス。 書き込みやプロパティの設定にもこの技法が使用可能です。

  • foreach 項第16章 制御構造を使用した SafeArrays ("真の" 配列) の値の取得。SafeArrays が自分自身の サイズについての情報を含んでいることからこれが可能となります。 配列形式のプロパティが IEnumVariant を実装している場合は、その プロパティに対しても foreach が使用可能です。この項目についての 詳細な情報は、 foreach をごらんください。

例外 (PHP 5)

COM から致命的なエラーが報告された場合、この拡張モジュールは com_exception クラスのインスタンスをスローします。 すべての COM 例外は code という定義済みの プロパティを保持しており、これは COM 操作が返す HRESULT 値に対応します。 プログラム上での例外の処理方法を決定するために、この値を使用する ことができます。

実行時設定

php.ini の設定により動作が変化します。

表 1. COM 設定オプション

名前 デフォルト 変更の範囲 変更履歴
com.allow_dcom "0" PHP_INI_SYSTEM PHP 4.0.5 以降で使用可能です。
com.autoregister_typelib "0" PHP_INI_ALL PHP 4 では PHP_INI_SYSTEM です。PHP 4.1.0 以降で使用可能です。
com.autoregister_verbose "0" PHP_INI_ALL PHP 4 では PHP_INI_SYSTEM です。PHP 4.1.0 以降で使用可能です。
com.autoregister_casesensitive "1" PHP_INI_ALL PHP 4 では PHP_INI_SYSTEM です。PHP 4.1.0 以降で使用可能です。
com.code_page "" PHP_INI_ALL PHP 5.0.0 以降で使用可能です。
com.typelib_file "" PHP_INI_SYSTEM PHP 4.0.5 以降で使用可能です。
PHP_INI_* 定数の詳細および定義については 付録G を参照してください。

以下に設定ディレクティブに関する 簡単な説明を示します。

com.allow_dcom

これを on にすると、PHP が D-COM (分散 COM) クライアントとして動作することを許可し、 PHP スクリプトがリモートサーバ上に COM オブジェクトを生成することを 許可します。

com.autoregister_typelib

これを on にすると、生成したオブジェクトのタイプライブラリから取得した 定数を PHP に登録しようと試みます。ただし、それはオブジェクトが 当該情報を取得するためのインターフェースを提供している場合のみです。 登録する定数の大文字小文字を区別するかどうかについては、 com.autoregister_casesensitive 設定ディレクティブで 制御します。

com.autoregister_verbose

これを on にすると、オブジェクト生成時のタイプライブラリの読み込み中に 発生したすべての問題が PHP のエラー機構を用いて報告されます。 デフォルトは off で、この場合はタイプライブラリの検索や読み込みの際の エラーは一切報告されません。

com.autoregister_casesensitive

これを on にすると (デフォルト)、自動読み込みされた タイプライブラリ中に見つかった定数が、大文字小文字を区別して 登録されます。詳細は com_load_typelib() を参照ください。

com.code_page

これは、COM オブジェクトとの文字列の受け渡しに使用するデフォルトの 文字セットコードページを制御します。空の文字列が設定された場合、 PHP は CP_ACP が指定されたと仮定します。 これは、デフォルトのシステム ANSI コードページです。

スクリプト中のテキストがデフォルトとは異なるエンコーディング/ 文字セットを使用している場合、このディレクティブを設定することで COM クラスのコンストラクタのパラメータとして コードページを指定する必要がなくなります。 (他の PHP 設定ディレクティブとともに) このディレクティブを使用すると、 PHP スクリプトの移植可能性が悪くなることに注意しましょう。 できる限り、COM のコンストラクタにパラメータを指定する方式をとるべきです。

注意: この設定ディレクティブは PHP 5 以降で使用可能です。

com.typelib_file

このパラメータでは、起動時に読み込まれるタイプライブラリの一覧を 含むファイルへのパスを保持します。このファイル内の各行が タイプライブラリ名として扱われ、 com_load_typelib() をコールした際にそれが読み込まれます。登録された定数は永続的に 保持されるので、ライブラリの読み込みは一度だけでよくなります。 タイプライブラリの名前が #cis あるいは #case_insensitive で終わる場合は、そのライブラリから 読み込まれた定数は大文字小文字を区別せずに登録されます。

定義済み定数

以下の定数が定義されています。 この関数の拡張モジュールが PHP 組み込みでコンパイルされているか、 実行時に動的にロードされている場合のみ使用可能です。

CLSCTX_INPROC_SERVER ( integer )

CLSCTX_INPROC_HANDLER ( integer )

CLSCTX_LOCAL_SERVER ( integer )

CLSCTX_REMOTE_SERVER ( integer )

CLSCTX_SERVER ( integer )

CLSCTX_ALL ( integer )

VT_NULL ( integer )

VT_EMPTY ( integer )

VT_UI1 ( integer )

VT_I2 ( integer )

VT_I4 ( integer )

VT_R4 ( integer )

VT_R8 ( integer )

VT_BOOL ( integer )

VT_ERROR ( integer )

VT_CY ( integer )

VT_DATE ( integer )

VT_BSTR ( integer )

VT_DECIMAL ( integer )

VT_UNKNOWN ( integer )

VT_DISPATCH ( integer )

VT_VARIANT ( integer )

VT_I1 ( integer )

VT_UI2 ( integer )

VT_UI4 ( integer )

VT_INT ( integer )

VT_UINT ( integer )

VT_ARRAY ( integer )

VT_BYREF ( integer )

CP_ACP ( integer )

CP_MACCP ( integer )

CP_OEMCP ( integer )

CP_UTF7 ( integer )

CP_UTF8 ( integer )

CP_SYMBOL ( integer )

CP_THREAD_ACP ( integer )

VARCMP_LT ( integer )

VARCMP_EQ ( integer )

VARCMP_GT ( integer )

VARCMP_NULL ( integer )

NORM_IGNORECASE ( integer )

NORM_IGNORENONSPACE ( integer )

NORM_IGNORESYMBOLS ( integer )

NORM_IGNOREWIDTH ( integer )

NORM_IGNOREKANATYPE ( integer )

NORM_IGNOREKASHIDA ( integer )

DISP_E_DIVBYZERO ( integer )

DISP_E_OVERFLOW ( integer )

MK_E_UNAVAILABLE ( integer )

参考

COM についてのより詳細な情報は COM 仕様 を読むか、あるいは Don Box の Yet Another COM Library (YACL) をごらんください。その他の有用な情報が、 第57章 の FAQ からも得られるでしょう。 MS Office アプリケーションをサーバサイドで使用しようと考えておられるなら、 Considerations for Server-Side Automation of Office の情報も読んでおくべきでしょう。

目次
COM  -- COM クラス
DOTNET  -- DOTNET クラス
VARIANT  -- VARIANT クラス
com_addref  --  コンポーネントの参照カウンタを増やす [非推奨]
com_create_guid  --  グローバルユニーク ID (GUID) を生成する
com_event_sink  --  COM オブジェクトのイベントを PHP オブジェクトに接続する
com_get_active_object  --  すでに実行中の COM オブジェクトのインスタンスへのハンドルを返す
com_get  --  COM コンポーネントのプロパティの値を得る [非推奨]
com_invoke  --  COM コンポーネントのメソッドをコールする [非推奨]
com_isenum  --  COM オブジェクトが IEnumVariant インターフェースを実装しているかどうかを 示す [非推奨]
com_load_typelib  -- タイプライブラリを読み込む
com_load  --  COM コンポーネントへの新規リファレンスを作成する [非推奨]
com_message_pump  --  COM メッセージを処理し、timeoutms ミリ秒の間待つ
com_print_typeinfo  --  ディスパッチインターフェースのために、PHP のクラス定義を出力する
com_propget  --  com_get() のエイリアス
com_propput  --  com_set() のエイリアス
com_propset  --  com_set() のエイリアス
com_release  --  コンポーネントリファレンスカウンタを減らす [廃止]
com_set  --  COM コンポーネントのプロパティに値を代入する
variant_abs  --  variant の絶対値を返す
variant_add  --  2 つの variant 値を「加算」し、結果を返す
variant_and  --  2 つの variant の論理積を計算し、結果を返す
variant_cast  --  variant を、別の型の新しい variant に変換する
variant_cat  --  2 つの variant 値を連結し、その結果を返す
variant_cmp  --  2 つの variant を比較する
variant_date_from_timestamp  --  unix タイムスタンプを、日付形式の variant で返す
variant_date_to_timestamp  --  日付/時刻の variant 値を unix タイムスタンプに変換する
variant_div  --  2 つの variant の除算結果を返す
variant_eqv  --  2 つの variant のビット値が等しいかどうかを調べる
variant_fix  --  variant の整数部を返す
variant_get_type  -- variant オブジェクトの型を返す
variant_idiv  --  variants を整数に変換し、除算の結果を返す
variant_imp  --  2 つの variant のビット implication を行う
variant_int  --  variant の整数部を返す
variant_mod  --  2 つの variant の除算を行い、剰余を返す
variant_mul  --  2 つの variant の乗算を行い、その結果を返す
variant_neg  --  variant の論理否定演算を行う
variant_not  --  variant のビット否定演算を行う
variant_or  --  2 つの variant の論理和を計算する
variant_pow  --  2 つの variant の累乗計算を行い、その結果を返す
variant_round  --  指定した桁で variant を丸める
variant_set_type  --  variant を「その場で」別の型に変換する
variant_set  --  variant オブジェクトに新しい値を代入する
variant_sub  --  左の variant から右の variant を引き、その結果を返す
variant_xor  --  2 つの variant の排他的論理和を計算する