PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

DOTNET> <COM関数
Last updated: Fri, 10 Oct 2008

view this page in

COM

(No version information available, might be only in CVS)

COMCOM クラス

$obj = new COM("Application.ID")

説明

COM クラスにより、OLE 互換の COM オブジェクトのインスタンスを作成し、 そのメソッドをコールしたりそのプロパティにアクセスしたりすることが 可能となります。

メソッド

com COM::COM ( string $module_name [, mixed $server_name [, int $codepage [, string $typelib ]]] )

COM クラスのコンストラクタ。 パラメータには以下のような意味があります。

module_name
ロードするコンポーネントを指定する プログラム ID、クラス ID またはモニカです。 プログラムID は、通常、アプリケーションまたは DLL の名前の後に、 Word.Application のようにピリオドと オブジェクト名を付けたものです。 クラス ID は、指定されたクラスがユニークに定義する UUID です。 モニカは、URL スキームの考え方に似た特別な命名形式です。リソースと、 それがどのように読み込まれるかを指定します。例として、モジュール名に Word ドキュメントのフルパスを指定すると、Word を読み込んで ドキュメントに対応するオブジェクトを取得することができます。 あるいは、LDAP への ADSI インターフェースを指すモニカとして LDAP: を使用することが可能です。
server_name
コンポーネントが読み込んで実行される DCOM サーバの名前です。 NULL の場合、オブジェクトはアプリケーションのデフォルトを 指定して実行されます。典型的なデフォルトは、ローカルマシン上で 実行させることでが、管理者によってはアプリケーションを別の マシン上で実行させるように設定しているかもしれません。 NULL 値をサーバに指定した場合、 実行時設定 設定オプションが TRUE に設定されていない限り PHP はオブジェクトの読み込みを 拒否します。

server_name が配列の場合、以下の要素 (大文字小文字を区別します!)を含まなければなりません。 これらはすべて省略可能であることに注意しましょう (とはいえ、Username および Password は両方指定する必要があります)。 もしサーバ設定を省略した場合は(上で説明した)デフォルトのサーバが 使用され、オブジェクトの生成は 実行時設定 ディレクティブの影響を受けません。

DCOM サーバ名
server_name のキー 説明
Server string サーバの名前。
Username string 接続するユーザ名。
Password string Username に対するパスワード。
Flags integer 以下の定数のうちのひとつまたは複数の論理和。 CLSCTX_INPROC_SERVERCLSCTX_INPROC_HANDLERCLSCTX_LOCAL_SERVERCLSCTX_REMOTE_SERVERCLSCTX_SERVER および CLSCTX_ALL。指定されていない場合の デフォルト値は、Server を省略した場合が CLSCTX_SERVER でサーバ名を指定した場合は CLSCTX_REMOTE_SERVER です。 これらの定数の意味についての詳細な情報を得るには、Microsoft のドキュメントで CoCreateInstance について調べましょう。 通常はこれらを使用する必要はないはずです。

codepage
文字列と Unicode 文字列との相互変換に使用するコードページを指定します。 PHP の文字列と COM オブジェクトのメソッドとの受け渡しの際には、いつも 変換が行われます。PHP 5 では、コードページの扱いは面倒です。というのは、 オブジェクトだけではなくオブジェクトから返される variant にもそれが 影響するからです。 とりうる値は CP_ACP (システムのデフォルト ANSI コードページを使用する - このパラメータが指定されなかった場合の デフォルト)、 CP_MACCPCP_OEMCPCP_SYMBOLCP_THREAD_ACP (現在実行中のスレッドの コードページ/ロケールを使用する)、CP_UTF7 および CP_UTF8 です。コードページに対応する 数値を指定することも可能です。コードページとそれに対応する数値に ついての詳細は、Microsoft のドキュメントを参照ください。

オーバーロードされたメソッド

返されるオブジェクトは、オーバーロードされたものです。つまり、 PHP 側では通常のクラスのメソッドは見えないということです。 その代わりに、プロパティやメソッドへのアクセスは COM を通じて行います。

PHP 5 以降では、参照渡しのパラメータを受け付けるメソッドを PHP が 自動検出するようになりました。それらのメソッドについては、PHP が自動的に 変数を参照渡し形式に変換します。つまり、メソッドのコールをより自然に 行えるということです。コードの中で特別な処理をする必要はありません。

PHP 4 では、パラメータを参照渡しする場合には、そのパラメータをラップする ために VARIANT クラスのインスタンスを生成する 必要があります。

疑似メソッド

PHP 5 より前のバージョンでは、以下のようなメソッド名を COM に渡すことが できず、直接 PHP で扱うことができないというあまりうれしくない出来事が ありました。PHP 5 ではこれらを解決します。スクリプトの修正方法に ついては以下の詳細を参照ください。これらのマジックメソッドの名前は 大文字小文字を区別しません。

void COM::AddRef ( void )

COM オブジェクトの参照カウントを作為的に追加します。

警告

このメソッドを使用することはまずないはずです。 これは、以下で説明する Release() メソッドを論理的に補完するものとして 存在するものです。

void COM::Release ( void )

COM オブジェクトの参照カウントを作為的に削除します。

警告

このメソッドを使用することはまずないはずです。 これは、COM オブジェクトが必要以上に動作を続けてしまうというバグに 対応する方法として PHP に存在するものです。

反復処理のための疑似メソッド

以下の疑似メソッドは、 com_isenum()TRUE を返す場合のみ利用可能で、この場合、これらのメソッドは、 通常は COM オブジェクトにより提供される同じ名前を有する全ての メソッドを隠蔽します。これらのメソッドは PHP 5 では完全に廃止されています。 代わりに を使用してください。

variant COM::All ( void )

10 の要素を保持する SafeArray を表す variant を返します。 個々の要素は empty/null の variant となります。この関数は イテレータからの全ての要素を含む配列を返すことを想定していますが、 決して完了しません。使用しないでください。

variant COM::Next ( void )

イテレータの次の要素を表す variant を返します。要素が もうない場合には FALSE を返します。

variant COM::Prev ( void )

イテレータの前の要素を現す variant を返します。要素が もうない場合には FALSE を返します。

void COM::Reset ( void )

イテレータを最初の場所まで巻き戻します。

COM の例

例1 COM の例 (1)

<?php
// word を起動します
$word = new COM("word.application") or die("Unable to instantiate Word");
echo 
"Loaded Word, version {$word->Version}\n";

// 前面に移動させます
$word->Visible 1;

// 空のドキュメントを開きます
$word->Documents->Add();

// 何か複雑なことを行います
$word->Selection->TypeText("This is a test...");
$word->Documents[1]->SaveAs("Useless test.doc");

// word を閉じます
$word->Quit();

// オブジェクトを開放します
$word null;
?>

例2 COM の例 (2)

<?php

$conn 
= new COM("ADODB.Connection") or die("Cannot start ADO");
$conn->Open("Provider=SQLOLEDB; Data Source=localhost;
Initial Catalog=database; User ID=user; Password=password"
);

$rs $conn->Execute("SELECT * FROM sometable");    // レコードセット

$num_columns $rs->Fields->Count();
echo 
$num_columns "\n";

for (
$i=0$i $num_columns$i++) {
    
$fld[$i] = $rs->Fields($i);
}

$rowcount 0;
while (!
$rs->EOF) {
    for (
$i=0$i $num_columns$i++) {
        echo 
$fld[$i]->value "\t";
    }
    echo 
"\n";
    
$rowcount++;            // 行カウントの加算
    
$rs->MoveNext();
}

$rs->Close();
$conn->Close();

$rs null;
$conn null;

?>



DOTNET> <COM関数
Last updated: Fri, 10 Oct 2008
 
add a note add a note User Contributed Notes
COM
johnno1985 at gmail dot com
21-Aug-2008 11:34
I couldn't find an example anywhere on what I was trying to do.  After taking bits from everyone I ended up with something that worked.

Im using Crystal Reports 10, MS SQL Server 2005, Apache2, and PHP5.

My report uses an SQL Store Procedure and passes some parameter to get the report data, so our PHP must set the database logon info and pass the parameters.

Below is the solution I came up with:

<?php

//------  Variables ------
$my_report = "C:\\Apache2\htdocs\\test\\MyReport.rpt"//This must be the full path to the file
$my_pdf = "C:\\Apache2\htdocs\\test\\MyReport.pdf";

//------ Create a new COM Object of Crytal Reports 10 ------
$ObjectFactory= new COM("CrystalReports10.ObjectFactory.1");

//------ Create a instance of library Application -------
$crapp = $ObjectFactory->CreateObject("CrystalDesignRunTime.Application.10");

//------ Open your rpt file ------
$creport = $crapp->OpenReport($my_report, 1);

//------ Set database logon info ------
$creport->Database->Tables(1)->SetLogOnInfo("MYSERVER", "Database", "user", "password");

//------ Suppress the Parameter field prompt or else report will hang ------
$creport->EnableParameterPrompting = 0;

//------ DiscardSavedData make a Refresh in your data -------
$creport->DiscardSavedData;
$creport->ReadRecords();

//------ Pass formula fields --------
$creport->FormulaFields->Item(1)->Text = ("'My Report Title'");
$creport->ParameterFields(1)->AddCurrentValue ("FirstParameter");
$creport->ParameterFields(2)->AddCurrentValue (2000);

//------ Export to PDF -------
$creport->ExportOptions->DiskFileName=$my_pdf;
$creport->ExportOptions->FormatType=31;
$creport->ExportOptions->DestinationType=1;
$creport->Export(false);

//------ Release the variables ------
$creport = null;
$crapp = null;
$ObjectFactory = null;

//------ Embed the report in the webpage ------
print "<embed src=\"MyReport.pdf\" width=\"100%\" height=\"100%\">"

?>

Obviously there's plenty of room for refinement in there, but it works and should get you going on the right track.  I also found that during testing, the script was hanging before supressing the parameter prompt. Once this had happened, some exports that had been working earlier stopped completely and wouldn't work again untill I restarted Apache.  This might be something worth doing if you keep having issues after a script has hung.
jkruse [at] unlnotes [dot] unl [dot] edu
20-Aug-2008 01:22
This is my first php.net comment so go easy on me :)

I was having trouble using COM to convert from ppt/pptx to an image for every slide (this works for outputting pdf,html,pptx->ppt, etc)

$app = new COM("PowerPoint.application") or die("Unable to instantiate PowerPoint");
$app->Visible = true;
$pres = $app->Presentations->Open("E:/tmp/test.pptx") or die ("Could not open presentation");
$app->Presentations[1]->SaveAs("E:/tmp/outdir",18);
$app->Presentations[1]->Close();
$app->Quit();
$app = null;

This code converts pptx to a png of every frame. Thats what 18 stands for (Its a class constant, you can see all the other formats here: http://msdn.microsoft.com/en-us/library/bb265906.aspx)

Hope this helps someone. Feel free to email me at the address above.
verticka at hotmail dot com
01-Aug-2008 04:38
Voila une deuxime fonction pour excel 2007 et le plugin pdf

<?php
function xls2pdf($doc,$pdf)
{

// Pas de paramétres requis
$empty = new VARIANT();

/* Supression du pdf si il existe */
if(file_exists ($pdf))
@
unlink($pdf);

/* Démarrage de Word */
$w = new COM("excel.application") or die("Impossible d'instancier l'application Word");

/* Test de Word 2007 */
if($w->Version > 11)
{
   
/* Amener Word devant */
   
$w->Visible = 1;

   
/* Test du fichier */
   
if(file_exists ($doc))
       
$w->Workbooks->Open($doc);
    else
        return
false;

   
/* Quelques commandes */
   
$w->Workbooks[1]->ExportAsFixedFormat(0,$pdf);

   
/* Fermeture de word */
   
$w->Workbooks[1]->Close(false);
}   
$w->Quit();

/* Libération des ressources */
$w = null;
unset(
$w);
    
/* Test du fichier */
if(file_exists ($pdf))
    return
true;
else
    return
false;
   
}

if(
xls2pdf("c:\\test.xls","c:\\test.pdf"))
echo
"ok";
else
echo
"nok";
?>

Pour les options d'exportation :
http://msdn.microsoft.com/en-us/library/bb238907.aspx

http://verticka.blogspot.com/
mastrboy.servebeer.com
13-Jun-2008 05:03
quick wmi query example:

<?php
    $obj
= new COM ( 'winmgmts://localhost/root/CIMV2' );
   
$wmi_computersystem =     $obj->ExecQuery("Select * from Win32_ComputerSystem");
   
$wmi_bios             =    $obj->ExecQuery("Select * from Win32_BIOS");
    foreach (
$wmi_computersystem as $wmi_call )
    {
       
$model = $wmi_call->Model;
    }
   
    foreach (
$wmi_bios as $wmi_call )
    {
       
$serial = $wmi_call->SerialNumber;
       
$bios_version = $wmi_call->SMBIOSBIOSVersion;
    }
    echo
"Bios version   : $bios_version\n".
        
"Serial number  : $serial\n".
        
"Hardware Model : $model\n";
?>
mbirth at webwriters dot de
08-Jun-2008 03:19
Using the DynamicWrapper from http://freenet-homepage.de/gborn/WSHBazaar/WSHDynaCall.htm and after registering it via "regsvr32 dynwrap.dll", you can easily set output colors to make colorful CLI scripts even on Windows.

<?php

$dw
= new COM('DynamicWrapper');  // needs dynwrap.dll (regsvr32 dynwrap.dll)

// register needed features
$dw->Register('kernel32.dll', 'GetStdHandle', 'i=h', 'f=s', 'r=l');
$dw->Register('kernel32.dll', 'SetConsoleTextAttribute', 'i=hl', 'f=s', 'r=t');
$dw->Register('kernel32.dll', 'SetConsoleTitle', 'i=s', 'f=s', 'r=l');

// get console handle
$ch = self::$dw->GetStdHandle(-11);  // -11 = STD_OUTPUT_HANDLE

?>

After these initialization steps, you can set the console output color using:

<?php
$dw
->SetConsoleTextAttribute($ch, 14);
echo
'This is yellow text!';
$dw->SetConsoleTextAttribute($ch, 7);
echo
'Back to normal gray!';
?>

Using SetConsoleTitle you can even set the title displayed in the console window.

Color values are 0..7 for dark colors and 8..15 for light colors. Sequence is (black/silver, blue, green, cyan, red, magenta, yellow/brown, white/gray). I also found that if you add 16384 to the value, it should be inverse. 32768 added should get underlined text. But these latter two didn't work for me.
amenthes at NOSPAM dot gmail dot com
03-Mar-2008 10:13
If you ever want to save an Excel(.xls) file into the Office Excel 2003 XML format, just use

$excel->Workbooks[1]->SaveAs('new_file_name.xml', 46);

That's the number you need, 46.
halfer
21-Jun-2007 05:03
Thanks to paul at completewebservices who added a note earlier; I have used his code to solve a particularly difficult issue with the Crystal 9 runtime component. For some reason, VBA/VBS can pass a native Date type as a parameter to a Crystal Report requiring a date, but in PHP I've tried all manner of strings, unix timestamps, COM variant dates etc and all of these resulted in a com_exception.

My solution was to employ VBScript to borrow the CDate function, which works correctly. Not the most elegant of solutions, but this parameterised approach is to be preferred to search-n-replacing the RecordSelectionFormula string. Of course if anyone here has an even better approach, do post it here - I am sure it would be of use.

<?php
// $rptParam is a report parameter object having a type of date
$oScript = new COM("MSScriptControl.ScriptControl");
$oScript->Language = "VBScript";
$oScript->AllowUI = false;
$oScript->AddObject('rptParam', $rptParam, true);
$oScript->AddCode('Function SetDateParameter(strDate)
rptParam.AddCurrentValue(CDate(strDate))
End Function'
);
$oScript->Run("SetDateParameter", "25 April 2006");
?>
hwcshirley at gmail dot com
21-May-2006 10:59
Reply to: djogopatrao at gmail dot com
I have change little bit your code. Its work.

$COM_Object = "CrystalDesignRunTime.Application";
$my_report = "C:\\appserv\\www\\mc\\test.rpt";
$my_pdf = "C:\\appserv\www\\mc\\test.pdf";

$crapp= New COM($COM_Object) or die("Unable to Create Object");
$creport = $crapp->OpenReport($my_report, 1);
$creport->ReadRecords(); // attention!

$creport->ExportOptions->DiskFileName=$my_pdf;
$creport->ExportOptions->PDFExportAllPages=true;
$creport->ExportOptions->DestinationType=1; // Export to File
$creport->ExportOptions->FormatType=31; // Type: PDF
$creport->Export(false);
djogopatrao at gmail dot com
05-Apr-2006 12:25
My previous notes about Crystal Reports have vanished away, but anyway I was up to correct them.

The code above connects to COM (beware of the version number! search on the Registry Editor for the correct name to put in $COM_Object), opens a report from a file ($my_report), reload records from database and then exports it to a PDF file ($my_pdf).

* IMPORTANT * this code, when invoked from the browser (I'm using Apache) AND with a report that connects to a ODBC database, does not work (the problem is specificly the line ReadRecords(), but may arise without it too when data is not saved into the report file).

But when you run this code by PHP-CLI (that is, by the command line), it works ok! I bug-reported this, but have no answer till now ( give it a vote, if you thing it's important: http://bugs.php.net/bug.php?id=36959 ).

Also, exceptions may arise, so put it on a try_catch block.

--------------------------

// by dfcp '06 (djogopatrao@gmail.com)

$COM_Object = "CrystalReports11.ObjectFactory.1";
$my_report = "C:\\report.rpt";
$my_pdf = "C:\\report.pdf";

$ObjectFactory= New COM($COM_Object);
$crapp = $ObjectFactory->CreateObject("CrystalDesignRunTime.Application");
$creport = $crapp->OpenReport($my_report, 1);
$creport->ReadRecords(); // attention!

$creport->ExportOptions->DiskFileName=$my_pdf;
$creport->ExportOptions->PDFExportAllPages=true;
$creport->ExportOptions->DestinationType=1; // Export to File
$creport->ExportOptions->FormatType=31; // Type: PDF
$creport->Export(false);
djogopatrao at gmail dot com
04-Mar-2006 07:27
I found somewhere (http://www.recrystallize.com/merchant/supportfaq/supportfaq0003.htm) a list relating each version of Crystal Reports to its respective progID - it may help some fellows out there.

7          Crystal.CRPE.Application

8.0        CrystalRuntime.Application or CrystalRuntime.Application.8

8.5        CrystalRuntime.Application or CrystalRuntime.Application.8.5

9 (RDC)    CrystalRuntime.Application.9
9 (RAS)    CrystalReports.ObjectFactory.2
10 (RDC)   CrystalRuntime.Application.11
10 (CEE)   CrystalReports10.ObjectFactory.1

 
XI (RDC)   CrystalRuntime.Application.11
XI (RAS)   CrystalReports11.ObjectFactory.1
paul at completewebservices dot com dot au
28-Jan-2006 03:49
It seems that PHP does not support setting of properties with arguments.  This is how I got around the problem:

        // Object with method I want to set
        $auth = new COM("AUTHXOCX.AuthXOCXCtrl.1");

        // ScriptControl
        $oScript = new COM("MSScriptControl.ScriptControl");
        $oScript->Language = "VBScript";
        $oScript->AllowUI = TRUE;

        // Add out object to the control
        $oScript->AddObject('auth', $auth, true);

        // Create a VBScript function that allow me to set them
       $oScript->AddCode(
'Function fixAccess(accessname)
    auth.AuthDataReferrerEnabled(accessname) = 1
    auth.AuthDataAuthentiXDBEnabled(accessname) = 0
End Function');

        // Execute function
        $oScript->Run("fixAccess", $dir);
volker at kybs dot de
07-Oct-2005 12:51
To use the windows speech system install the "Speech SDK 5.1 for Windows applications" from the Microsoft homepage (free download).
Then you can do Text2Speech like this:

$voice = new COM("SAPI.SpVoice");
$voice->Speak("Hello, lets have a conversation");
sadi at unicornsoftbd dot com
06-Oct-2005 01:56
If your PHP is configured as ISAPI module then the COM object you create in ur php page will use the same memory space as the web server. If your COM object takes too much memory then this may force some COM error as PHP does not handle the memory usage of COM itself. And also Web server doesnt know what do to free COM memory. But if you use PHP as CGI then PHP itself handle the memory usage of COM. Once in a script where i used COM and PHP as ISAPI module i got unknown COM error.But when i used PHP as CGI there was no error. So those who want to use COM object in your application please be careful about it.
deletethis@bjoern(at)syltonline(doot)de
15-Sep-2005 07:36
If you can get the old "TaskScheduler.dll" and register it, it is quite simple to handle and start Windows tasks from PHP.
This is extremely useful when you got things to do which must be run in a different user context. Prepare a task with the user and use PHP & Com to build a webinterface for it.

Here is an example how to start a Windows task:

  function start_task ($taskname) {
    $SchedObj = new COM("Scheduler.SchedulingAgent.1");
    foreach ($SchedObj->Tasks as $task) {
      if (strtolower( (string) $task) == strtolower( $taskname.".job" )) {
         $task->Run();
      }
    }
  }

I'm also working on a class to handle infos, adding and removing of tasks via PHP. If you are interested drop me a line.
jbr at ya-right dot com
19-Aug-2005 01:07
Getting * directory * permissions ( attributes ) with COM

PHP (5) example...

<?
    $dir = 'e:/www/docs/www/docs/junk/';

    define ( 'READ_ONLY', 1 );
    define ( 'IS_HIDDEN', 2 );
    define ( 'IS_SYSTEM', 4 );

    $hold = array ();

    $obj = new COM ( 'scripting.filesystemobject' );

    if ( is_object ( $obj ) )
    {
        $all = $obj->getfolder ( $dir );

        foreach ( $all->subfolders AS $directory )
        {
            if ( substr ( $directory->name, - 3 ) != 'cnf' )
            {
                $hold[$dir . $directory->name . '/'] =  array ( 'read_only' => ( ( $directory->Attributes & READ_ONLY ) <> 0 ? 1 : 0 ), 'is_hidden' => ( ( $directory->Attributes & IS_HIDDEN ) <> 0 ? 1 : 0 ), 'is_system' => ( ( $directory->Attributes & IS_SYSTEM ) <> 0 ? 1 : 0 ) );
            }
        }

        $obj = null;
    }
    else
    {
        echo 'sorry can not crate object: file_system_object';
    }

    print_r ( $hold );
?>

To do the same thing for * files * with in the directory named in $dir, change above ( foreach() ) to what is below...

        foreach ( $all->files AS $file )
        {
            $hold[$file->name] =  array ( 'read_only' => ( ( $file->Attributes & READ_ONLY ) <> 0 ? 1 : 0 ), 'is_hidden' => ( ( $file->Attributes & IS_HIDDEN ) <> 0 ? 1 : 0 ), 'is_system' => ( ( $file->Attributes & IS_SYSTEM ) <> 0 ? 1 : 0 ) );
        }

pretty much anything you could think of doing in windows can be done using PHP and COM...

John
csaba at alum dot mit dot edu
03-Mar-2005 05:21
Getting IE to the foreground
If you are using a command line (CLI) version of PHP on a Win32 platform (e.g. XP Pro, SP2), you might want to have output directed to IE (perhaps you'll want to work with the output there) when Popup does not suffice (see my earlier post, below).

It's easy enough to get an instance of IE using $ie = new COM("InternetExplorer.Application");.  The problem is, you don't necessarily see it in the foreground (especially if you already have one open) and who wants to waste keystrokes getting to it?  The code below has been working for me (If you want to do other adjustments (e.g. $ie->Document->ParentWindow->resizeTo(800,500); or $ie->Document->Body->bgColor = "yellow";), doing them before the $ie->Visible = true; line will avoid screen distractions):

<?php
function newIEtoForeground($title, $evtPrefix="") {
   
// brings new instance of IE to foreground with title $title
   
if (!$extPrefix) $ie = new COM("InternetExplorer.Application");
    else
$ie = new COM("InternetExplorer.Application", $evtPrefix);
   
$ie->Navigate2("about:blank");
   
$oWSH = new COM("WScript.Shell");
    while (
$ie->ReadyState!=4) usleep(10000);

   
$ie->Document->Title = ($tmpTitle = mt_rand());  //unique title
   
$ie->Visible = true;
    while (!
$oWSH->AppActivate("$tmpTitle - M")) usleep(10000);

   
$ie->Document->Title = $title;
   
$ie->Document->ParentWindow->opener="me"// allows self.close()
   
return $ie;
}
?>

Csaba Gabor from Vienna
csaba at alum dot mit dot edu
14-Feb-2005 12:22
Basic Windows IO
If you are using a command line (CLI) version of PHP on a Win32 platform, you might like to have a simple graphical interface to get input and output.  The following gives an illustration for both.

<?php
   
// first we get some input
   
$oScript = new COM("MSScriptControl.ScriptControl");
   
$oScript->Language = "VBScript";
   
$title = "I/O Demo: Input half";
   
$initial = "Change this value";
   
$prompt = "Please enter a value";
   
   
$code = <<<EOF
Function getInput()
    inVal = InputBox("$prompt", "$title", "$initial")
    getInput = inVal         'how return values are assigned in VB
End Function
EOF;

   
$oScript->AddCode($code);
   
$input = $oScript->Eval("getInput()");   
    if (
gettype($input)=="NULL") $input = "Input box was cancelled";

   
// now we show some output
   
$oWSH = new COM("WScript.Shell");
   
$title = "I/O Demo: Output half";
   
$timeout = 2;        // 0 for no timeout
   
$style = 0 + 48;    // buttons to show + alert symbol
   
$oWSH->Popup($input, $timeout, $title, $style);
?>

This is example is overblown for illustrative purposes.  The whole input part collapses if the amount of code used is a single statement.  So, this would have sufficed:
$code = "InputBox(\"$prompt\", \"$title\", \"$initial\")";
$input = $oScript->Eval($code);

This technique exposes quite a bit of scripting power tied into the Windows operating system and VBScript.  However, you should have a really specific reason for using it since VBScript tends to be dog slow when compared to PHP in my tests.  Simple IO like this is good, however, and the popup size can be quite large.  Furthermore, this could be a viable route to go for accessing WinAPI's.

http://www.ss64.com/wsh/popup.html shows some documentation for $oWSH->Popup

Csaba Gabor from Vienna
phpguy _from_ toshpro _dot_ com
12-Nov-2004 05:55
if you ever need to connect to an access database (on the server, using the IIS or APACHE user account), here is code below that can help to ease the process.  It is written like this because we have a MySQL as well as an Access database and need to be able to switch back and forth.  The runQuery function will return a 2 dimensional array and can use column names or numbers for the index of the internal arrays.  External arrays are always integer-indexed.  We also have found issues with Access staying open and growing from 7MB to 2.5GB within two hours, so we open and close it each time we run a query.  If it is not a select query it will return TRUE.  if it fails with errors, it will return false.

There is a showErr flag that we mostly only use for MySQL, since you can output MySQL errors without PHP errors.  Access doesn't appear to be that friendly.

<?php

function runQuery(&$conn,
                   
$strSQL,
                   
$associative=true,
                   
$debug=false,
                   
$showSQL=false,
                   
$showErr=false) {    
    return
runMSQuery($conn,$strSQL,$associative,$debug,$showSQL,$showErr);
   
//return runMyQuery($conn,$strSQL,$associative,$debug,$showSQL,$showErr);
}

function
openMSDB($dbfile="c:/path/and/filename.mdb") {
    if (!@
$conn = new COM("ADODB.Connection"))
        exit(
"Unable to create an ADODB connection<br>");
   
$strConn = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=".$dbfile;
    @
$conn->open($strConn);
    if(
$conn->State == 0) return false;
    return
$conn;
}

function
closeMSDB(&$conn) {
    @
$conn->Close();
   
$conn = null;
    return
true;
}

function
runMSQuery(&$conn,
                   
$strSQL,
                   
$associative=true,
                   
$debug=false,
                   
$showSQL=false,
                   
$showErr=false) {
    if(!
is_object($conn)) if(!$conn=openMSDB()) return false;
    if(
$showSQL || $debug ) echo $strSQL."\n<br>\n";
   
$rtn = false;
    if(
$debug) $rs = $conn->execute($strSQL);
    else
$rs = @$conn->execute($strSQL);

    if(!
$rs) {
        if(
$showErr) echo "Error running SQL.<br>\n";
       
closeMSDB($conn);
        return
false;
    }
    if (
$rs->State == 0) {
       
closeMSDB($conn);
        return
true;
    } else {   
       
$rows=0;
        while(!
$rs->EOF) {
            for(
$i=0;$i<$rs->Fields->count;$i++) {
               
$rsf = $rs->Fields($i);
                if(
$associative) $rtn[$rows][$rsf->Name] = $rsf->value;
                else
$rtn[$rows][$i] = $rsf->value;
            }
           
$rows++;
           
$rs->MoveNext();
        }
        if(
$rs->State != 0) $rs->Close();
       
$rs = null;
    }
    if(
$debug) var_dump($rtn);
   
closeMSDB($conn);
    return
$rtn;
}
?>
sodeh at dana dot ir
30-Oct-2004 03:11
for connection to sql server and know the utf-8 code
use this method to connect the database

$db = new COM("ADODB.Connection",NULL, 65001 );
jbr at ya-right dot net
12-May-2004 11:23
"Keeping an instance of a Server object loaded"

When dealing with COM objects like 'Word' or 'Excel' you are pretty
much dealing with personal COM type objects. The reason I say this
is because they in no way have any direct relationship to a real COM
server object. The differences between a 'Server COM Object' and a
'Personal COM Type Object' are great. Server COM objects, do not contain
and properties or methods related to any type of program dialog.

Most Enterprise COM objects are designed to run under IIS where they
are loaded into the server process. So once the first instance call is
made or when the server is started the object loads it properties, methods
and data related to the service the object provides!

Many objects load large data set(s) 10 MB to 200 MB into memory, this makes
any process after the initial loading of the object fast and very system
friendly!

In PHP, when an initial instance of an object is loaded some where in a
PHP script, PHP will check if an instance of the object is already running
if it is, then it will use that instance. If it can not find an instance to
the object running, it will create a new instance to the object!

In the case of personal COM type objects, you can point to a running instance
of an object, and reference that instance...

<?

$obj = new COM ( 'X:\reports\june.doc' );

?>

For Server type COM objects that load large data set(s), you really have no option
because each script run will unload the instance at the end of the script's run time.
Unless another http request is running and the new http request can access the other
object instance, you will have to load all the objects properties and methods and data
set(s) used by the object!

One way to work around this is to write a wrapper that can load the object into the
PHP or the Server process! I did this for the objects I use.

Another unorthodox way is to load your web browser to a PHP script that uses a combination
of ignore_user_abort(), set_time_limit(), load the object, sleep();!

Before I wrote the wrapper for a 'Map Server Object' I use in one of my project. I used
the 'unorthodox way' for almost a year and had over 15,000 object requests a day, and
never did the instance of the object ever have to start a new instance, ie: reload all the properties and methods and data
set(s) used by the object!

Like I said this is a very 'unorthodox way' to keep an object loaded, but it works!

set the object 'My.Object' in the script, call the script from the browser, then close the browser!

<?

    ignore_user_abort ( 'true' );

    set_time_limit ( 0 );

    com_load_typelib ( 'My.Object' ) or die ( 'Could not load TypeLib' );

    $obj = new COM ( 'My.Object' ) or die ( 'Could not load object' );

    $obj = null;

    sleep ( 63166608000 ); // one year

?>

John
flintjt at hotmail dot com
11-Mar-2004 11:45
I have searched for ways to open and read an excel document and I found some information which I thought that I would document.  Information on the object model to help with programming COM objects can be found in your MS Office help files, search for VBA*.chm.
Also, here is a script that I used to pull a cell from each worksheet, complete w/ variable for pathnames & worksheets.  This script also closes excel completely.  The coding might be dirty, but it gets the job done.
--------copy from here-----------
<pre>
<?PHP
$filename
= "c:/spreadhseet/test.xls";
$sheet1 = 1;
$sheet2 = "sheet2";
$excel_app = new COM("Excel.application") or Die ("Did not connect");
print
"Application name: {$excel_app->Application->value}\n" ;
print
"Loaded version: {$excel_app->Application->version}\n";
$Workbook = $excel_app->Workbooks->Open("$filename") or Die("Did not open $filename $Workbook");
$Worksheet = $Workbook->Worksheets($sheet1);
$Worksheet->activate;
$excel_cell = $Worksheet->Range("C4");
$excel_cell->activate;
$excel_result = $excel_cell->value;
print
"$excel_result\n";
$Worksheet = $Workbook->Worksheets($sheet2);
$Worksheet->activate;
$excel_cell = $Worksheet->Range("C4");
$excel_cell->activate;
$excel_result = $excel_cell->value;
print
"$excel_result\n";
#To close all instances of excel:
$Workbook->Close;
unset(
$Worksheet);
unset(
$Workbook);
$excel_app->Workbooks->Close();
$excel_app->Quit();
unset(
$excel_app);
?>
</pre>
----------------------------------
jon at jonroig dot com
03-Dec-2003 12:28
Here's a simple example of printing formatted templates with MS Word.

To begin with, I've already built my invoice in Word and saved it as an RTF file.
In this case, I'm using "sampleInvoice.php"

Fields that will be replaced have been marked as ||CUSTOMER ID|| and so on.

<?php
$dataText
= "";

// open the file
if(!($fp= fopen ("C:\wordTest\sampleInvoice.rtf", "r"))) die ("Can't open");
$dataText = fread($fp, 2000000);
fclose ($fp);

// replace the template fields
$dataText = str_replace ("||CUSTOMER ID||",$customerIDValue, $dataText);

// save the file as an rtf
$timeStamp = time();
$saveFile = "C:/wordTemp/".$timeStamp."-invoice-".$customerIDValue.".rtf";
if(!(
$fq= fopen ($saveFile, "w+"))) die ("Can't open");
fwrite ($fq, $dataText);
fclose ($fq);

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

print
"Loaded word version ($word->Version)\n";
$word->visible = true;
$word->Documents->Add();

// open the file
$word->Documents->Open("$saveFile");

// output the file to the default printer
$word->ActiveDocument->PrintOut(1);

// shutdown word
$word->Quit();
?>
jnv at jnv dot ch
03-Dec-2003 03:42
Be sure you have Word, Excel, .. on your server or it will not work !
drich at nea-online dot net
18-Nov-2003 02:47
Changing Fields (Not FORMFIELDS) In MS Word....

Searched most of the afternoon for this, as it is something needed here for our projects.  Maybe this can help someone else as well.

<?php
$input
= "x:\\path\\to\\test.doc";
$word = @new COM("word.application") or die("Unable to instantiate Word");
print
"Loaded Word, version {$word->Version}\n<br>";
$word->Visible = 1;
print
"Set Word To Visible<br>";
$word->Documents->Open($input);
print
"Opened $input<br>";
$word->Activate;
print
"Activated Word<br>";

print
"Editing Fields<br>";
$Field = $word->ActiveDocument->Fields(1);
$fieldData = $Field->Result;
$fieldData->Text = "Testing";

// Print the document.
$word->Printout();

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

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

?>
Mihael Peternelj; Slovenia
18-Oct-2003 05:22
If you wnat to connect to Access MDB Library you can use this small "progy". It works so, that if someone other accesses the library, it waits for so long to access it again because (as i know) MDB librarys can be accessed only once at the same time.

<?php
function mdb($sql, $array = 0, $base = "Base.mdb", $timelimit = 5)
    {
   
$r_items = array();
   
$c = new COM("ADODB.Connection");
   
$r = false;
   
$time = time();
   
$process = $i = 0;
    while(
$r == false && $process <= $timelimit)
        {
       
$deb = $c->open('DRIVER={Microsoft Access Driver (*.mdb)}; Dbq='. realpath($base) .';');
       
$r = $c->execute($sql);
       
$process = time() - $time;
        }
    if(
$process >= $timelimit) exit("mdbSQL Query Timeout!");
    if(
strtolower(substr($sql, 0, 6)) == "insert" or strtolower(substr($sql, 0, 6)) == "update" or strtolower(substr($sql, 0, 6)) == "delete") return true;
   
$num_fields = $r->fields->count();
    while (!
$r->EOF)
        {
        for(
$j = 0; $j < $num_fields; $j++)
            {
           
$key = $r->Fields($j);
            if(
$array == 0) $r_items[$i][$key->name] = $key->value;
            else
$r_items[$i][$j] = $key->value;
            }
       
$i++;
       
$r->MoveNext();
        }
   
$r->close();
   
$c->close();
   
$r = null;
   
$c = null;
    return
$r_items;
    }
?>

I got the source from the Manual, what i did is that i made it more compatible and user frendly. :)

I hope it could some day help someone so as it did me...

Greetings from Slovenia!

Mihael Peternelj
admin at CdnDomainRegistry dot ca
20-Sep-2003 03:57
Here's an example/comparison of VBScript vs PHP's COM component to connect to an IIS Webserver.
The examples backup the IIS MetaBase (your server's website(s) configuration) in IIS.

VBScript:
  Dim obj, iFlags
  Set obj = GetObject("IIS://LocalHost")
  ' Backup to next available version number.
  ' Set flags to save the metabase first and
  ' force the backup even if save fails.
  iFlags = (MD_BACKUP_SAVE_FIRST or MD_BACKUP_FORCE_BACKUP)
  obj.Backup "MyBackups", MD_BACKUP_NEXT_VERSION, iFlags
  ' Note: The above was copied from Microbucks.
  ' This is how you would have to do it.
  ' i.e. use the actual constant's value.
  iFlags = (2 or 4) 
  obj.Backup "MyBackups", &HFFFFFFFF, iFlags

PHP:
  <?php
  $obj
= new COM("IIS://LocalHost")or die("Unable to instantiate IIS"); 
 
$err = com_invoke ($obj, "Backup", "MyBackups", "&HFFFFFFFF", 2|4 );
 
$obj = null;
  print
"err=".$err; // returns 0 on success
 
?>

Glen
20-Sep-2003 10:49
Example on how to read a registry value:

<?php
  $shell
= &new COM('WScript.Shell');
 
var_dump($shell->regRead('HKEY_CURRENT_USER\Environment\TEMP'));
?>

(outputs string(39) "%USERPROFILE%\Lokale Einstellungen\Temp" on my system)
EuresMan
01-Aug-2003 03:21
To mstaiger
I have encountered the same problem you report.
I tried to use the above code for a word document but it doesn't works, although the same code was good if i use it on a excel sheet.

The solution is explained at the following link :
http://www.phpbuilder.net/columns/venkatesan20030501.php3
rickardsjoquist at hotmail dot com
09-Jul-2003 10:33
If you want to use a DSN-less connection to a database (access for example) and return the results of a query as a multidimensional array with the fieldnames as identifier try this. Hope it helps someone :-)
--------------------------------------------------------

<?php
function db($sql) {
   
$c = new COM("ADODB.Connection");
   
$c->open('DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=' . realpath("relative_path/db.mdb"));
   
$r = $c->execute($sql);
   
$i = 0;
   
$num_fields = $r->fields->count();
    while (!
$r->EOF)
        {
            for(
$j = 0;$j<$num_fields;$j++) {
           
$key = $r->Fields($j);
           
$r_items[$i][$key->name] = $key->value;
        }
       
$i++;
       
$r->MoveNext();
    }
   
$r->close();
   
$c->close();
   
$r = null;
   
$c = null;
    return
$r_items;
}
?>

--------------------------------------------------------
use it like this:
--------------------------------------------------------
<?php
$results
= db("SELECT field_a, field_b FROM table");
foreach(
$result as $i => $item) {
    echo
$item['field_a'];
    echo
$item['field_b'];
}
?>
--------------------------------------------------------
You can also use: print_r($result); if you want the structure of the array to be printed.
info at sharedprojects dot nl
16-Jun-2003 09:41
<?php
// An other way to connect
// this connect to a ODBC-datasourced added in the
// ODBC Data Source Administrator under System DSN

$odbcname = "northwind";
$conn->Open("DSN=$odbcname");
?>
eguan1ao_at_yahoo_dot_com
20-Nov-2002 01:35
An example of connecting to a Microsoft Access database, executing an SQL query, and displaying the results in HTML.

<?php

$db
= 'C:\\Program Files\\Microsoft Office\\Office\\Samples\\Northwind.mdb';