PHP  
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
search for in the  
<ccvs_voidCOM>
view the version of this page
Last updated: Thu, 21 Aug 2003

VIII. COM support functions for Windows

Introduction

COM is a technology which allows the reuse of code written in any language (by any language) using a standard calling convention and hiding behind APIs the implementation details such as what machine the Component is stored on and the executable which houses it. It can be thought of as a super Remote Procedure Call (RPC) mechanism with some basic object roots. It separates implementation from interface.

COM encourages versioning, separation of implementation from interface and hiding the implementation details such as executable location and the language it was written in.

Requirements

COM functions are only available on the Windows version of PHP.

Installation

There is no installation needed to use these functions; they are part of the PHP core.

The windows version of PHP has built in support for this extension. You do not need to load any additional extension in order to use these functions.

Runtime Configuration

The behaviour of these functions is affected by settings in php.ini.

Table 1. Com configuration options

NameDefaultChangeable
com.allow_dcom"0"PHP_INI_SYSTEM
com.autoregister_typelib"0"PHP_INI_SYSTEM
com.autoregister_verbose"0"PHP_INI_SYSTEM
com.autoregister_casesensitive"1"PHP_INI_SYSTEM
com.typelib_file""PHP_INI_SYSTEM
For further details and definition of the PHP_INI_* constants see ini_set().

Predefined Constants

The constants below are defined by this extension, and will only be available when the extension has either been compiled into PHP or dynamically loaded at runtime.

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)

See Also

For further information on COM read the COM specification or perhaps take a look at Don Box's Yet Another COM Library (YACL)

Table of Contents
COM -- COM class
VARIANT -- VARIANT class
com_addref --  Increases the components reference counter.
com_get --  Gets the value of a COM Component's property
com_invoke --  Calls a COM component's method.
com_isenum -- Grabs an IEnumVariant
com_load_typelib -- Loads a Typelib
com_load --  Creates a new reference to a COM component
com_propget -- Alias of com_get()
com_propput -- Alias of com_set()
com_propset -- Alias of com_set()
com_release --  Decreases the components reference counter.
com_set --  Assigns a value to a COM component's property


add a note add a note User Contributed Notes
COM support functions for Windows
superzouz is at hotmail
11-Oct-2003 07:46
-- Catching COM events --
Hello everyone.
Anyone who did VB + COM would know something is missing here: events!
Here's how to catch IE events using some undocumented functions:
----------
class ieSinker {
    var $terminated = false;
    function TitleChange($text) {
          echo("title has changed: $test \n");
          }
    function OnQuit() {
           echo "Quit!\n";
           $this->terminated = true;
           }
    }

$ie = new COM("InternetExplorer.Application");
$ieSink =& new ieSinker();
com_event_sink($ie, $ieSink, "DWebBrowserEvents2");
$ie->navigate(' PATH TO YOUR HTML FILE GOES HERE! ');
$ie->visible = True;
while(!$ieSink->terminated) {
    com_message_pump(10);
    }
----------
Works perfect for me with php 4.3
You can find more info on the undocumented functions in the YACL documentation.
Note the "DWebBrowserEvents2" interface. You can find more information about these in the microsoft platform SDK documentation, under "web development". Or maybe they have a smaller web development SDK? I wasn't able to use any other interface, so what I do is send messages from IE to the PHP script by changing the title of the html document with JavaScript.
By the way, I cant take credit for the above code, I stole it from some website of which I lost the address.
Thats it... bye...
04-Oct-2003 02:55
Convert Microsoft word document .DOC to adobe acrobat .PS or .PDF files:

Drawback: if any dialog boxes pop up, the conversion will become non-automated.

<?
// You must have word and adobe acrobat distiller on
// your system, although theoretically any printer driver
// that makes .PS files would work.

// starting word
$word = new COM("word.application") or die("Unable to instanciate Word");
print 
"Loaded Word, version {$word->Version}\n";

// bring it to front
$word->Visible 1;

// Select the acrobat distiller as the active printer.
// I presume that you could also use the Acrobat PDF writer // driver that comes with Acrobat full version.
$word->ActivePrinter "Acrobat Distiller";

// Open a word document, or anything else that word
// can read
$word->Documents->Open($input);

// This will create a .PS file called $output
$word->ActiveDocument->PrintOut(000$output);

// If you need a .pdf instead, use the acrobat
// distiller's watched folder option.

// closing word
$word->Quit();

// free the object
$word->Release();
$word null;

?>
court shrock
26-Sep-2003 07:24
took me a while until I found out how to loop through COM objects in PHP.... in ASP, you use something like:

<%
set domainObject = GetObject("WinNT://Domain")

for each obj in domainObject
  Response.write obj.Name & "<br>"
next

%>

I finally found a note in a PHP bogus bug report that said you needed to do something like this (this is using ADSI):

<?php
$adsi 
= new COM("WinNT://Domain");

while(
$obj $adsi->Next()) {
  echo 
$obj->Name.'<br>';
}
// while

// will list all the names of all objects in the domain 'Domain'
?>

Also, you can access the IIS metabase by doing something like the following:

<?php
$iis 
= new COM("IIS://localhost/w3svc");

while(
$obj $iis->Next()) {
  if (
$obj->Class == 'IISWebServer') {
   
$site = new COM("IIS://Localhost/w3svc/".$obj->Name);
    echo 
'serviceID ('.$obj->Name.'): '.$site->ServerComment.'<br>';
   
$bindings $site->ServerBindings;
   
    echo 
'<ul>';
    foreach(
$bindings as $binding) {
      list(
$ip$port$hostHeader) = explode(':'$binding);
      echo 
"<li>$ip:$port -- $hostHeader</li>";
    }
// foreach
   
echo '</ul>';

   
// hint: ssl bindings are in $site->SecureBindings

   
unset($site);

  }
// if
 
}// while
unset($iis);

// will list all the sites and their bindings on 'localhost'
?>
mkcostello at hotmail dot com
22-Sep-2003 11:35
Took me a while to work this out as there is very little help available. Accessing com variables that are multi arrays can prove tricky.

e.g.
$ex = new COM("application");

$ex->Stock->stSalesBands
is an array A-H [stPrice,stCurrency]

php chucks out an error on this:
$ex->Stock->stSalesBands(C)->stPrice;

so, you have to do this
$tmp = $ex->Stock->stSalesBands(C);
echo $tmp->stPrice;
unset($tmp)
php at dictim dot com
07-Sep-2003 03:17
This took me days to work out how to do so I gotta share it:

How to get the word count from a MS Word Document:

#Instantiate the Word component.

$word = new COM("word.application") or die("Unable to instantiate Word");

$word->Visible = 1;

$word->Documents->Open("c:/anydocument.doc");
$temp = $word->Dialogs->Item(228);
$temp->Execute();
$numwords = $temp->Words();

echo $numwords;

$word->Quit();

Note that this is the only way to get the word count accurately:
$word->ActiveDocument->Words->Count;
Will see all carriage returns and punctuation as words so is wildy innaccurate.
seidenberg at cf-mail dot net
12-Jul-2003 05:36
open PDF Documents with Internet Explorer

$browser = new COM("InternetExplorer.Application");
$browser->Visible = true;
$browser->Navigate("path_to_your_pdf_document");

this works for me with php-gtk
tomas dot pacl at atlas dot cz
16-Jun-2003 08:07
Passing parameters by reference in PHP 4.3.2 (and in a future releases of PHP )

In PHP 4.3.2 allow_call_time_pass_reference option is set to "Off" by default and future versions may not support this option any longer.
Some COM functions has by-reference parameters. VARIANT object must be used to call this functions, but it would be passed without an '&' before variable name.

Example:

$myStringVariant = new VARIANT("over-write me", VT_BSTR);

/* works */
$result = $comobj->DoSomethingTo($myStringVariant );

/* works only with allow_call_time_pass_reference option set to "On" and may not work in a future release of PHP */
$result = $comobj->DoSomethingTo(&$myStringVariant );

The value in the variant can be retrieved by:
$theActualValue = $myStringVariant->value;
php at racinghippo dot co dot uk
23-Mar-2003 09:47
PASSING/RETURNING PARAMETERS BY REFERENCE
=========================================

Some COM functions not only return values through the return value, but also act upon a variable passed to it as a parameter *By Reference*:

RetVal = DoSomethingTo (myVariable)

Simply sticking an '&' in front of myVariable doesn't work - you need to pass it a variant of the correct type, as follows:

  $myStringVariant = new VARIANT("over-write me", VT_BSTR);
  $result = $comobj->DoSomethingTo( &$myStringVariant );

The value in the variant can then be retrieved by:

  $theActualValue = $myStringVariant->value;

Other types of variant can be created as your needs demand - see the preceding section on the VARIANT type.
alex at domini dot net
05-Mar-2003 06:55
To manage the Windows Register at HKEY_LOCAL_MACHINE\SOFTWARE\ use these functions:

<?php

/**
 * @return string
 * @param aplicacio string
 * @param nom string
 * @desc Retorna el valor del registre HKEY_LOCAL_MACHINE\SOFTWARE\aplicacio\nom
 */
function rtv_registre($aplicacio$nom)
{
    Global 
$WshShell;
   
$registre "HKEY_LOCAL_MACHINE\SOFTWARE\\" $aplicacio "\\"  $nom;
   
$valor $WshShell->RegRead($registre);
    return(
$valor);
   
   
}

/**
 * @return string
 * @param aplicacio string
 * @param nom string
 * @param valor string
 * @param tipus string
 * @desc Actualitza el valor del registre HKEY_LOCAL_MACHINE\SOFTWARE\aplicacio\nom
 */
function put_registre($aplicacio$nom$valor$tipus="REG_SZ")
{
    Global 
$WshShell;
   
$registre "HKEY_LOCAL_MACHINE\SOFTWARE\\" $aplicacio "\\"  $nom;
   
$retorn $WshShell->RegWrite($registre$valor$tipus);
    return(
$retorn);
   
   
}

//
// Creem una instè·£cia del COM que ens serveix per
// accedir al registre de Windows, i la mantenim.
// D'aquesta manera millorem el rendiment.
$WshShell = new COM("WScript.Shell");
?>
richard dot quadling at carval dot co dot uk
26-Feb-2003 09:51
With thanks to Harald Radi and Wez Furlong.

Some VBA functions have optional parameters. Sometimes the parameters you want to pass are not consecutive.

e.g.

GoTo What:=wdGoToBookmark, Name="BookMarkName"
GoTo(wdGoToBookmark,,,"BookMarkName)

In PHP, the "blank" parameters need to be empty.

Which is ...

<?php
// Some servers may have an auto timeout, so take as long as you want.
set_time_limit(0);

// Show all errors, warnings and notices whilst developing.
error_reporting(E_ALL);

// Used as a placeholder in certain COM functions where no parameter is required.
$empty = new VARIANT();

// Load the appropriate type library.
com_load_typelib('Word.Application');

// Create an object to use.
$word = new COM('word.application') or die('Unable to load Word');
print 
"Loaded Word, version {$word->Version}\n";

// Open a new document with bookmarks of YourName and YourAge.
$word->Documents->Open('C:/Unfilled.DOC');

// Fill in the information from the form.
$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourName'); // Note use of wdGoToBookmark, from the typelibrary and the use of $empty.
$word->Selection->TypeText($_GET['YourName']);

$word->Selection->GoTo(wdGoToBookmark,$empty,$empty,'YourAge');
$word->Selection->TypeText($_GET['YourAge']);

// Save it, close word and finish.
$word->Documents[1]->SaveAs("C:/{$_GET['YourName']}.doc");
$word->Quit();
$word->Release();
$word null;
print 
"Word closed.\n";
?>

The example document is ...

Hello [Bookmark of YourName], you are [Bookmark of YourAge] years old.

and it would be called ...

word.php?YourName=Richard%20Quadling&YourAge=35

Regards,

Richard.
pchason at juno dot com
12-Dec-2002 03:23
Searched for days on how to set up a multi-column html output grid that didn't use an array when creating an ADODB connection. Couldn't find one so I figured it out myself. Pretty simple. Wish I would have tried it myself sooner. Commented code with database connection is below...

<html>
<body>
<table>
<?php 
//create the database connection
$conn = new COM("ADODB.Connection"); 
$dsn "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" realpath("mydb.mdb"); 
$conn->Open($dsn); 
//pull the data through SQL string
$rs $conn->Execute("select clients from web"); 
$clients $rs->Fields(1); 
//start the multicolumn data output
$i 0;
$columns 5
while (!
$rs->EOF){
//if $i equals 0, start a row
if($i == 0){ 
echo 
"<tr>"
}
//then start writing the cells in the row, increase $i by one, and move to the next record
echo "<td>" $clients->value "</td>"
$i++;
$rs->movenext();
//once $i increments to equal $columns, end the row,
//and start the process over by setting $i to 0
if($i == $columns || $rs->EOF) { 
echo 
"</tr>";
$i 0;
    } 
}
//end multicolumn data output

//close the ADO connections and release resources
$rs->Close(); 
$conn->Close(); 
$rs null
$conn null?> 
</table>
</body>
</html>
daveNO at SPAMovumdesign dot com
27-Sep-2002 11:52
The documentation for this feature is a bit redundant. It mentions that COM performs and encourages information hiding (a.k.a. encapsulation) three times. Perhaps instead it could expand a bit on what COM is useful for, and particularly why combining it with PHP can be beneficial.

The contributed examples above do a nice job of illustrating the benefits of PHP+COM. In a nutshell, many Windows applications (especially office suites and databases) expose useful functionality through the COM interface.

For example, Microsoft Word can read RTF files and (of course) write Word Documents. You could use PHP to generate RTF and then use Microsoft Word via PHP's COM interface to convert the RTF to a DOC. The amazing thing about this is that you can actually insert PHP (or template) code into Word itself, because RTF files are text-based like HTML. Throw Distiller into the mix and you've got a web-based, template-driven, maybe even database-driven PDF generator!

Have fun,
Dave
tedknightusa at hotmail dot com
26-Sep-2002 11:29
A Notes example:

$session = new COM "Lotus.NotesSession" );
$session->Initialize($password);
   
$someDB = "C:\Lotus\Notes\Data\somedb.nsf";
$db = $session->GetDatabase("", $someDB) or die("Cannot get someDB.nsf");
$view = $db->GetView("some_view") or die("Some View not found");

$doc = $view->GetFirstDocument() or die("Unable to get Initial Some Document");

// loop through
while($doc){
  $col_vals = $doc->ColumnValues();
  echo $col_vals[0];
  $doc = $view->GetNextDocument($doc);
}
dwt at myrealbox dot com
27-Aug-2002 05:31
When first writing applications instancing COM objects I always faced the problem of the instanced program not terminating correctly although everything else worked fine. In fact the process had to be killed manually by using the task manager. When experimenting a bit I was able to isolate the cause for this peculiar behaviour to be illustrated by the sample code below:

<?php

//Accessing arrays by retrieving elements via function ArrayName(Index) works, but certainly is neither efficient nor good style
$excel=new COM("Excel.Application");
$excel->sheetsinnewworkbook=1;
$excel->Workbooks->Add();

$book=$excel->Workbooks(1);
$sheet=$book->Worksheets(1);

$sheet->Name="Debug-Test";
$book->saveas("C:\\debug.xls");

$book->Close(false);
unset(
$sheet);
unset(
$book);
$excel->Workbooks->Close();
$excel->Quit();
unset(
$excel);

//Accessing arrays as usual (using the [] operator) works, buts leads to the application not being able to terminate by itself
$excel=new COM("Excel.Application");
$excel->sheetsinnewworkbook=1;
$excel->Workbooks->Add();

$excel->Workbooks[1]->Worksheets[1]->Name="Debug-Test";
$excel->Workbooks[1]->saveas("C:\\debug.xls");

$excel->Workbooks[1]->Close(false);
$excel->Workbooks->Close();
$excel->Quit();
unset(
$excel);

?>

The sample code performs the same action twice and each time the file is properly created. Yet for some mysterious reason the instanced excel process won't terminate once you've accessed an array the way most programmers (especially those who do a lot of oop in c++) do! Therefore until the PHP developers become aware of this problem we'll have to use the inefficient coding style illustrated in the first example.
nospam at bol dot com dot br
21-Aug-2002 05:30
This is a sample to make a parametrized query using ADO via COM, this sample was used with Foxpro but will work's with most ADO complient databases. This was tested on IIS with WIN XP pro.

<?
// Create the main connection
$dbc = new COM("ADODB.Connection")  or die ("connection create fail");
$dbc->Provider "MSDASQL";
$dbc->Open("FoxDatabase");
// Creates a temporary record set
$RSet = new COM("ADODB.Recordset");
// Create one ADO command
$cm   = new COM("ADODB.Command");
$cm->Activeconnection $dbc;
// the ? inside values will be the parameters $par01 and $par02
$cm->CommandText "Insert Into testtable ( mycharfield,mymemofield) VALUES (?,?)" ;
$cm->Prepared TRUE;
// Creates and append 2 parameters
$par01 $cm->CreateParameter('ppar01',129,1,50,'ABCDEFGHIKL');
$cm->Parameters->Append($par01);
$par02 $cm->CreateParameter('ppar01',129,1,50,'123456789012346789');
$cm->Parameters->Append($par02);
// Call 10 times the exec comand to show 10 different queries
for ($i 1$i <= 10$i++) {
 
$par01->Value 'Count '.$i;
 
$par02->Value 'Passing here'.$i.' times';
 
$RSet $cm->Execute;
}
$RSet $dbc->Execute("select * from testtable");
while (!
$RSet->EOF){
  echo 
$RSet->fields["mycharfield"]->value.' ' ;
  echo 
$RSet->fields["mymemofield"]->value ;
  echo 
'<BR>';
 
$RSet->movenext();
}
$RSet->close;
$dbc->close;
$cm->close;   
$RSet null;
$dbc null;
$cm null;
?>
paulo at Ihatespam dot com
29-Jun-2002 12:48
Complementing Alex's Excell Example, let's print the SpreadSheet to a PDF file using Acrobat Distiller:

$wkb->PrintOut(NULL, NULL, NULL, NULL, "Acrobat Distiller");

There you go!!!
admin at purplerain dot org
19-Apr-2002 06:34
an easy way to convert your file from .doc to .html

// starting word
$word = new COM("word.application") or die("Unable to instanciate Word");

// if you want see thw World interface the value must be '1' else '0'
$word->Visible = 1;

//doc file location
$word->Documents->Open("E:\\first.doc");

//html file location  '8' mean HTML format
$word->Documents[1]->SaveAs("E:\\test_doc.html",8);

//closing word
$word->Quit();

//free the object from the memory
$word->Release();
$word = null;
admin at purplerain dot org
02-Apr-2002 06:01
An easy way to send e-mail using your default Outlook account:
<?
$objApp 
= new COM("Outlook.Application");
$myItem $objApp->CreateItem(olMailItem);
$a=$myItem->Recipients->Add("admin@purplerain.org");
$myItem->Subject="Subject";
$myItem->Body="This is a Body Section now.....!";
$myItem->Display();
$myItem->Send();
?>
madon at cma-it dot com
08-Mar-2002 04:59
I thought this excel chart example could be useful.

Note the use of Excel.application vs Excel.sheet.

<pre>
<?php
   
print "Hi";
#Instantiate the spreadsheet component.
#    $ex = new COM("Excel.sheet") or Die ("Did not connect");
$exapp = new COM("Excel.application") or Die ("Did not connect");

#Get the application name and version   
print "Application name:{$ex->Application->value}<BR>" 
print 
"Loaded version: {$ex->Application->version}<BR>"

$wkb=$exapp->Workbooks->add();
#$wkb = $ex->Application->ActiveWorkbook or Die ("Did not open workbook");
print "we opened workbook<BR>";

$ex->Application->Visible 1#Make Excel visible.
print "we made excell visible<BR>";

$sheets $wkb->Worksheets(1); #Select the sheet
print "selected a sheet<BR>";
$sheets->activate#Activate it
print "activated sheet<BR>";

#This is a new sheet
$sheets2 $wkb->Worksheets->add(); #Add a sheet
print "added a new sheet<BR>";
$sheets2->activate#Activate it
print "activated sheet<BR>";

$sheets2->name="Report Second page";

$sheets->name="Report First page";
print 
"We set a name to the sheet: $sheets->name<BR>";

# fills a columns
$maxi=20;
for (
$i=1;$i<$maxi;$i++) {
   
$cell $sheets->Cells($i,5) ; #Select the cell (Row Column number)
   
$cell->activate#Activate the cell
   
$cell->value $i*$i#Change it to 15000
}

$ch $sheets->chartobjects->add(5040400100); # make a chartobject

$chartje $ch->chart# place a chart in the chart object
$chartje->activate#activate chartobject
$chartje->ChartType=63;
$selected $sheets->range("E1:E$maxi"); # set the data the chart uses
$chartje->setsourcedata($selected); # set the data the chart uses
print "set the data the chart uses <BR>";

$file_name="D:/apache/Apache/htdocs/alm/tmp/final14.xls";
if (
file_exists($file_name)) {unlink($file_name);}
#$ex->Application->ActiveWorkbook->SaveAs($file_name); # saves sheet as final.xls
$wkb->SaveAs($file_name); # saves sheet as final.xls
print "saved<BR>";

#$ex->Application->ActiveWorkbook->Close("False");   
$exapp->Quit();
unset(
$exapp);
?>

</pre>

Alex Madon
darkwings at 263 dot net
28-Feb-2002 01:11
now in PHP >=4.0.6
programming in window can use the
ADO through the COM like this:
$dbconn=new COM ("ADODB.Connection") or die ("connection create fail");
 $dbconn->Open("Provider=sqloledb;Data Source=ndht;Initial Catalog=printers;User Id=printers;Password=printers;");
 $rec=new COM("ADODB.Recordset") or die ("create Recordset error");
 while (!$rec->EOF)
 {
echo $rec->fields["fieldname"]->value."<br>";
$rec->movenext();
 }
 $rec->close();
 $dbconn->close();

but there's still a little question of working with the image field of mssql server.
kevin at vcconcepts dot com
01-Apr-2001 07:37
I thought i'd share with those of you unfamiliar with one of the cool things
about developing php on win32 systems..

http://www.phpbuilder.net/columns/alain20001003.php3

This is a good article, but i don't think the author hit the nail on the
head showing how useful this can be.

Now, checkout this article:
http://www.4guysfromrolla.com/webtech/040300-1.shtml

Notice how he describes 1) how to build a com object & 2) how to call and
use the com object from ASP.

In php, this is how you would call the same object:

<?
$instance 
= new COM("Checkyear.LeapYear");
$isleapyear $instance->IsLeapYear($year);
$instance->close();
if(
$isleapyear) {
echo 
"The <b>$year</b> is a leap year";
}
else {
echo 
"The <b>$year</b> is not a leap year";
}
?>

I hope this helps someone.. you can contact me at kevin@vcconcepts.com if
you would like to discuss this further.

<ccvs_voidCOM>
 Last updated: Thu, 21 Aug 2003
show source | credits | sitemap | mirror sites 
Copyright © 2001-2003 The PHP Group
All rights reserved.
This mirror generously provided by: http://php.mirrors.ilisys.com.au/
Last updated: Sat 01 Nov 2003 04:13:36 EST EST