Before I start anything, I'd like to acknowledge the work of Alain M. Samoun.
His articles on phpBuilder.com and phpclasses.org were fundamental in figuring out
how to interface to COM componentry, so thank you VERY much Alain!
The steps being followed in this tutorial are:
- Check pre-requisites
- Check and modify php.ini settings.
- Modify COM permissions to allow PHP to use the COM interface
- Modify the applications COM permissions to allow the use of the interface.
- Run test script
In the example I'm going to be detailing here, we will interface with a Excel
spreadsheet using its COM/DCOM interface in PHP.
The reason I chose Excel as the application to hook up with is as its one of the
more problematic programs to interface with, and if you can interface to Excel, you
can pretty much interface with ANYTHING!
Pre-Requisites
Seeing as the title of this article is how to interface with COM objects with
PHP under Windows NT/2k/XP, you will need the following components:
- Windows NT/2000/XP. I've tested this on Windows NT and XP so, Windows 2000 should be fine
- IIS / Apache / web server of some type
- PHP with COM support built in. I'm using version 4.3.1
- Excel installed. I've tested this with Excel 98 and Excel 2000
Check and modify php.ini settings.
Open up your php.ini file. This should be located in your windows or windows\system directory.
Search for the section with the title [com]
Within this section, set the following:
; allow Distributed-COM calls
com.allow_dcom = true
; autoregister constants of a components typlib on com_load()
com.autoregister_typelib = true
; register constants casesensitive
;com.autoregister_casesensitive = false
; show warnings on duplicate constat registrations
com.autoregister_verbose = true
Modify COM permissions to Allow PHP to Use the COM Interface
From the Start menu, select run and type
dcomcnfg, as in the image below :
Depending on the version of windows you are running, a screen which resembles the one below will appear.
Double click on Component services, then My Computer. You should see a screen similar to the one below:
From here, click on the button highlighted in red:
You should see the following box appear:
Select the Default COM Security tab and click the button marked "Edit Default" in the Launch Permissions section (the highlighted box below)
You will see a box which looks like this :
This is the default set of users that can use the DCOM/COM interfaces to the system. You will need to
add the "IIS Anonymous User" which allows PHP to actually begin using the
DCOM/COM interface. Select Add from the Launch Permissions box and then the Advanced button.
You should see a dialog box which looks like below:
Making sure that the local machine is selected in the location tab (area in green),
click on the Find now button(highlighted in red). You will see the dialog box populate as
below. Select the
IUSR_MACHINE_NAME name and press ok.
The add user dialog should now look as below:
Select ok to this and then again ok to close launch permissions. Finally, select ok to close the
permissions tab for the computer.
Modify the applications COM permissions to allow the use of the interface.
On the left hand side of the dialog box which came up when
dcomcnfg was run, navigate to ConsoleRoot->ComponentServices->Computers->MyComputer->DCOMConfig->MicrosoftExcelApplication, as below.
Right click on the Microsoft Excel Application, highlighted in red above. Select Properties.
In the dialog box that comes up, navigate to the Security Tab. Under the Access permissions section,
select the Edit button(highlighted in red below).
Add the
IUSR_MACHINE_NAME user to the list shown as described in
the method on the previous page, so that the box looks as below.
Now, select the Identity tab on the Microsoft Excel Application Properties box,
and select the interactive user as being the account running the application.
Running the Test Script
Now, we come back to the work of Alain M. Samoun, as mentioned at the start of this article.
A nice quick example of verifying whether this has worked is by doing this example:
An abbreviated example would be to run this:
Please note that I've lifted this directly from page 3 of the above tutorial.
Hope this helps.
/Sid
<?php
#Set the workbook to use and its sheet. In this example we use a spreadsheet that
#comes with the Excel installation called: SOLVSAMP.XLS
$workbook = "C:\Program Files\Microsoft office\Office\Samples\SOLVSAMP.XLS";
$sheet = "Quick Tour";
#Instantiate the spreadsheet component.
$ex = new COM("Excel.sheet") 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>";
#Open the workbook that we want to use.
$wkb = $ex->application->Workbooks->Open($workbook) or Die ("Did not open");
#Create a copy of the workbook, so the original workbook will be preserved.
$ex->Application->ActiveWorkbook->SaveAs("Ourtest");
#$ex->Application->Visible = 1; #Uncomment to make Excel visible.
# Read and write to a cell in the new sheet
# We want to read the cell E11 (Advertising in the 4th. Quarter)
$sheets = $wkb->Worksheets($sheet); #Select the sheet
$sheets->activate; #Activate it
$cell = $sheets->Cells(11,5) ; #Select the cell (Row Column number)
$cell->activate; #Activate the cell
print "Old Value = {$cell->value} <BR>"; #Print the value of the cell:10000
$cell->value = 15000; #Change it to 15000
print "New value = {$cell->value}<BR> ";#Print the new value=15000
#Eventually, recalculate the sheet with the new value.
$sheets->Calculate; #Necessary only if calc. option is manual
#And see the effect on total cost(Cell E13)
$cell = $sheets->Cells(13,5) ; #Select the cell (Row Column number)
$number = Number_format($cell->value);
print "New Total cost =\$$number - was \$47,732 before.<BR>";
#Should print $57,809 because the advertising affects the Corporate overhead in the
# cell formula.
#Example of use of the built-in functions in Excel:
#Function: PMT(percent/12 months,Number of payments,Loan amount)
$pay = $ex->application->pmt(0.08/12,10,10000);
$pay = sprintf("%.2f",$pay);
print "Monthly payment for $10,000 loan @8% interest /10 months: \$ $pay<BR>";
#Should print monthly payment = $ -1,037.03
#Optionally, save the modified workbook
$ex->Application->ActiveWorkbook->SaveAs("Ourtest");
#Close all workbooks without questioning
$ex->application->ActiveWorkbook->Close("False");
unset ($ex);
?>