PHP Conference Japan 2024

com 類別

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

簡介

com 類別允許您實例化與 OLE 相容的 COM 物件,並呼叫其方法和存取其屬性。

類別綱要

class com extends variant {
/* 方法 */
public __construct(
    string $module_name,
    array|string|null $server_name = null,
    int $codepage = CP_ACP,
    string $typelib = ""
)
}

覆載方法

返回的物件是一個覆載物件,這表示 PHP 不會像處理一般類別那樣看到任何固定的方法;而是將任何屬性或方法存取傳遞給 COM。

PHP 會自動偵測接受參考參數的方法,並自動將一般的 PHP 變數轉換為可以參考傳遞的形式。這表示您可以非常自然地呼叫該方法;您不需要在程式碼中進行任何額外的努力。

com 範例

範例 #1 com 範例 (1)

<?php
// 啟動 word
$word = new com("word.application") or die("無法實例化 Word");
echo
"載入 Word,版本 {$word->Version}\n";

// 將其帶到前景
$word->Visible = 1;

// 開啟一個空白文件
$word->Documents->Add();

// 執行一些奇怪的操作
$word->Selection->TypeText("這是一個測試...");
$word->Documents[1]->SaveAs("無用的測試.doc");

// 關閉 word
$word->Quit();

// 釋放物件
$word = null;
?>

範例 #2 com 範例 (2)

<?php

$conn
= new com("ADODB.Connection") or die("無法啟動 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++; // 遞增 rowcount
$rs->MoveNext();
}

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

$rs = null;
$conn = null;

?>

目錄

新增筆記

使用者貢獻筆記 36 則筆記

14
tsintra at humansoft dot pt
15 年前
在嘗試了解我的 PHP 與 MS Word 通訊問題一周後,我終於讓它正常運作了...
似乎如果您正在執行 IIS,則 COM 物件會以受限制的權限調用。
如果您遇到權限問題,例如無法開啟或儲存文件,並且出現如下錯誤:

- 此命令不可用,因為沒有開啟任何文件

- 命令失敗

請嘗試以下操作(如果您正在執行 IIS):

- 執行 "dcomcnfg"
- 開啟元件服務 > 電腦 > 我的電腦 > DCOM 設定
- 搜尋 Microsoft Office Word 97-2003 文件 (它會類似這樣翻譯成您的語言,所以花點時間搜尋)
- 在其上按一下滑鼠右鍵,然後開啟屬性
- 選擇「身分」標籤
- 通常這會設定為「啟動的使用者」。您必須將其變更為「互動式使用者」或您選擇的管理員使用者。
- 套用這些新設定並測試您的 COM 應用程式。現在應該可以正常運作了。

希望這能為你們中的一些人省下許多令人頭痛的時間 :)
5
info at ensostudio dot ru
4 年前
使用 WScript.Shell 的完整範例
<?php
/**
* 方法 & 屬性
* @link https://msdn.microsoft.com/en-us/library/2f38xsxe(v=vs.84).aspx
*/
$shell = new com('WScript.Shell', null, CP_UTF8);
var_dump($shell->CurrentDirectory);
foreach (
$shell->Environment as $value) {
var_dump($value);
}
// 檢查檔案 'Test.php'
$process = $shell->Exec('.../php.exe --syntax-check --file=".../src/Test.php"');
// 等待完成:1 - 完成
while (! $process->Status) {
usleep(5000);
}
// 結果:-1 - 語法錯誤,0 - 沒有錯誤
var_dump($process->ExitCode);
// 顯示回應
var_dump($process->StdOut->ReadAll());
// 顯示錯誤
var_dump($process->StdErr->ReadAll());
?>
10
rogier
13 年前
我花了一些時間透過試錯才弄清楚這個問題

如果您在取得類似「錯誤 [0x80004002] ...」(訊息抱怨關於不支援的介面)的 com 例外狀況時感到沮喪,而且您透過 COM 呼叫類別方法,該方法需要 char 作為引數,您不應該使用單字元字串呼叫該方法。

呼叫此類方法的正確方式是使用類型為 VT_UI1 的 VARIANT。

COM 啟用的方法定義

public bool DoSomething(char arg);

<?php

$com
= new COM('Some.Class.Name');

// 這將會失敗
$var = 'a';
$com->DoSomething($var);

// 這會正確運作
$var = new VARIANT(ord('a'), VT_UI1);
$com->DoSomething($var);

?>

希望這能幫助一些人
2
yinon at xacct dot com
22 年前
為了使 Word 範例運作,請在伺服器端執行以下操作。
對我來說有效...
1. 按一下「開始」-->「執行」並輸入「dcomcnfg」
2. 在「應用程式」索引標籤中,向下找到「Microsoft Word 文件」
3. 按一下「內容」按鈕
4. 前往「安全性」索引標籤
5. 按一下「使用自訂存取權限」,然後按一下「編輯」
6. 按一下「新增」,然後按一下「顯示使用者」
7. 反白顯示 IIS 匿名使用者帳戶 (通常是 IUSR_<機器名稱>),按一下「新增」
8. 按一下「確定」返回「安全性」索引標籤
9. 按一下「使用自訂啟動權限」,然後按一下「編輯」
10. 按一下「新增」,然後按一下「顯示使用者」
11. 反白顯示 IIS 匿名使用者帳戶 (通常是 IUSR_<機器名稱>),按一下「新增」
12. 按一下「確定」,然後按一下「套用」。

此外,您應該查看「Microsoft Word 文件內容」中的「身分識別」索引標籤,並確認其設定為「互動式使用者」


另外,請以 IUSR_<機器名稱> 帳戶登入機器,啟動 Word,並確保按一下 Word 第一次為特定使用者執行時顯示的對話方塊。換句話說,請確保 Word 為 IUSR_ 使用者正常開啟。

您可以在這裡找到更多有用的資訊
http://www.email-screen.com/support-doc2txt.html
4
mbirth at webwriters dot de
16 年前
使用來自 http://freenet-homepage.de/gborn/WSHBazaar/WSHDynaCall.htm 的 DynamicWrapper,並在透過「regsvr32 dynwrap.dll」註冊後,您可以輕鬆設定輸出顏色,即使在 Windows 上也能製作色彩繽紛的 CLI 指令碼。

<?php

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

// 註冊需要的功能
$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');

// 取得主控台控制代碼
$ch = self::$dw->GetStdHandle(-11); // -11 = STD_OUTPUT_HANDLE

?>

在這些初始化步驟之後,您可以使用以下方式設定主控台輸出顏色

<?php
$dw
->SetConsoleTextAttribute($ch, 14);
echo
'這是黃色文字!';
$dw->SetConsoleTextAttribute($ch, 7);
echo
'返回正常的灰色!';
?>

使用 SetConsoleTitle,您甚至可以設定在主控台視窗中顯示的標題。

顏色值為 0..7 表示深色,8..15 表示淺色。順序為(黑色/銀色、藍色、綠色、青色、紅色、洋紅色、黃色/棕色、白色/灰色)。我也發現,如果您將 16384 加到該值,它應該是反相的。新增 32768 應該會產生底線文字。但後兩種對我不起作用。
2
mastrboy.servebeer.com
16 年前
快速 wmi 查詢範例

<?php
$obj
= new COM ( 'winmgmts://127.0.0.1/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 版本 : $bios_version\n".
"序號 : $serial\n".
"硬體型號 : $model\n";
?>
2
halfer
17 年前
感謝稍早添加註解的 completewebservices 的 paul;我使用他的程式碼來解決 Crystal 9 執行階段元件的特別困難的問題。由於某些原因,VBA/VBS 可以將原生日期類型作為參數傳遞給需要日期的 Crystal 報表,但在 PHP 中,我嘗試了各種字串、unix 時間戳記、COM 變體日期等,所有這些都會導致 com_exception。

我的解決方案是採用 VBScript 來借用 CDate 函式,該函式可以正常運作。雖然不是最優雅的解決方案,但這種參數化方法比搜尋並取代 RecordSelectionFormula 字串更受青睞。當然,如果這裡的任何人有更好的方法,請在這裡發布 - 我相信這會很有用。

<?php
// $rptParam 是一個具有日期類型的報表參數物件
$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", "2006 年 4 月 25 日");
?>
3
z3n at overflow dot biz
15 年前
在使用 ADODB.Connection 物件查詢回覆時,當我將 `$rs->Fields['field_name']->Value` 插入陣列時,全部都回傳 `variable Object`,像這樣:

<?php
for ($rl[$v]=array(),_qm($_query);!$res->EOF;$res->MoveNext()) {
$rl[$v][]=$res->Fields['x']->Value;
}
?>

我發現將值轉換為 INT 可以解決這個問題

<?php $rl[$v][]=intval($res->Fields['x']->Value); ?>
1
james dot m dot love at gmail dot com
15 年前
如果您使用 COM 建立與 MS Access 2007 資料庫的 DSN-less 連線,您會透過 Google 搜尋發現需要使用更新版本的 Jet,因此我找到的連線字串如下所示:

<?php
$databaselocation
= "C:\Path\to\db.accdb";
$conn = new COM('ADODB.Connection') or exit('無法啟動 ADO。');
$conn->Open("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=$databaselocation") or die('無法啟動 Jet');
?>

然而,在我的設定 (WinVista、Access 2007、PHP526) 中,我發現它總是會因為「無法啟動 Jet」而「die」,即使連線成功 ($conn->State 讀取為 "1")。

我想到的解決方法是直接刪除 `$conn->Open()` 上的 `die()` 命令。如果 ADO 連線發生災難性的錯誤,它自己的錯誤處理引擎會將堆疊追蹤等資訊傳回主控台/標準輸出。

因此,我的 `Open()` 命令如下所示:

<?php
$conn
->Open("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=$databaselocation");
?>
1
csaba at alum dot mit dot edu
19 年前
將 IE 移到前景
如果您在 Win32 平台上使用 PHP 的命令列 (CLI) 版本(例如 XP Pro、SP2),您可能會希望將輸出導向到 IE(也許您想在那裡處理輸出),當 Popup 不夠用時(請參閱我稍早的貼文,如下)。

使用 `$ie = new COM("InternetExplorer.Application");` 取得 IE 實例非常簡單。問題是,您不一定會在前景看到它(尤其是當您已經開啟一個時),而且誰想浪費按鍵來找到它?下面的程式碼對我來說一直有效(如果您想進行其他調整(例如 `$ie->Document->ParentWindow->resizeTo(800,500);` 或 `$ie->Document->Body->bgColor = "yellow";`),在 `$ie->Visible = true;` 行之前進行這些調整可以避免螢幕干擾)。

<?php
function newIEtoForeground($title, $evtPrefix="") {
// 將新的 IE 實例帶到前景,標題為 $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()); // 獨特的標題
$ie->Visible = true;
while (!
$oWSH->AppActivate("$tmpTitle - M")) usleep(10000);

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

來自維也納的 Csaba Gabor
1
rickardsjoquist at hotmail dot com
21 年前
如果您想要使用 DSN-less 連線到資料庫(例如 Access),並將查詢結果作為具有欄位名稱作為識別符號的多維陣列回傳,請嘗試這個方法。希望對某些人有所幫助 :-)
--------------------------------------------------------

<?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;
}
?>

--------------------------------------------------------
像這樣使用它:
--------------------------------------------------------
<?php
$results
= db("SELECT field_a, field_b FROM table");
foreach(
$result as $i => $item) {
echo
$item['field_a'];
echo
$item['field_b'];
}
?>
--------------------------------------------------------
您也可以使用:`print_r($result);` 如果您想要列印陣列的結構。
2
sparrowstail at googlemail dot com
14 年前
此腳本會報告所有 Windows 磁碟機、磁碟機類型、狀態(如果無法使用)、可用空間和磁碟機總大小

<?php

$fso
= new COM('Scripting.FileSystemObject');
$D = $fso->Drives;
$type = array("Unknown","Removable","Fixed","Network","CD-ROM","RAM Disk");
foreach(
$D as $d ){
$dO = $fso->GetDrive($d);
$s = "";
if(
$dO->DriveType == 3){
$n = $dO->Sharename;
}else if(
$dO->IsReady){
$n = $dO->VolumeName;
$s = file_size($dO->FreeSpace) . " free of: " . file_size($dO->TotalSize);
}else{
$n = "[Drive not ready]";
}
echo
"Drive " . $dO->DriveLetter . ": - " . $type[$dO->DriveType] . " - " . $n . " - " . $s . "<br>";

}

function
file_size($size)
{
$filesizename = array(" Bytes", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB");
return
$size ? round($size/pow(1024, ($i = floor(log($size, 1024)))), 2) . $filesizename[$i] : '0 Bytes';
}

?>

還有許多磁碟物件的其他屬性可以這樣呼叫 - 請參閱

http://msdn.microsoft.com/en-us/library/ts2t8ybh%28VS.85%29.aspx
3
juan156_elias at gmail dot com
9 年前
這是一個使用基於 COM/DOTNET 類別的 NetPhp 函式庫來使用 .Net 的範例。

您可以使用任何 .dll 檔案,無論它是否經過 COM 修飾,以及任何現成的 .Net framework 類型。 您也可以指定 .Net framework 的任何版本。

<?php

$runtime
= new \NetPhp\Core\NetPhpRuntime('COM', 'netutilities.NetPhpRuntime');

// 加入 SpreadsheetLight 和它所依賴的 OpenXML。
$runtime->RegisterAssemblyFromFile('/binaries/SpreadsheetLight.dll', 'SpreadsheetLight');
$runtime->RegisterAssemblyFromFile('/binaries/DocumentFormat.OpenXml.dll', 'DocumentFormat.OpenXml');
$runtime->RegisterAssemblyFromFile('/binaries/AjaxMin.dll', 'AjaxMin');

// 使用已註冊的組件中的類型的完整名稱。
$datetime = $runtime->TypeFromName("System.DateTime");

// 使用尚未註冊的類型的完整名稱(來自檔案)
$minifier = $runtime->TypeFromFile("Microsoft.Ajax.Utilities.Minifier", APPLICATION_ROOT . '/binaries/AjaxMin.dll');

// 使用尚未註冊的類型的完整名稱(可自動探索)
$datetime2 = $runtime->TypeFromAssembly("System.DateTime", "mscorlib, ....");

$datetime->Instantiate();
echo
$datetime->ToShortDateString()->Val(); // 輸出 01/01/0001

// 我們只能使用原生 PHP 的 Int32,所以解析
// 在 DateTime 建構函式中與 (long) 等效的 Int64。
$ticks = $runtime->TypeFromName("System.Int64")->Parse('98566569856565656');

$datetime->Instantiate($ticks);
echo
$datetime->ToShortDateString()->Val(); // 輸出 07/05/0313

// 我們只能使用原生 PHP 的 Int32,所以解析
// 在 DateTime 建構函式中與 (long) 等效的 Int64。
$ticks = $runtime->TypeFromName("System.Int64")->Parse('98566569856565656');

// 轉儲 .Net System.Timers.Timer 物件!
$data = $timer->GetPhpFromJson();

var_dump($data);

// 輸出:
// object(stdClass)[38]
// public 'AutoReset' => boolean true
// public 'Enabled' => boolean false
// public 'Interval' => int 100
// public 'Site' => null
// public 'SynchronizingObject' => null
// public 'Container' => null

// 檢查今天是否為星期一
$IsMonday = $runtime->TypeFromName("System.DateTime")->Now->DayOfWeek->
Equals($runtime->TypeFromName("System.DayOfWeek")->Enum('Monday'));

?>
2
paul at completewebservices dot com dot au
18 年前
PHP 似乎不支援設定帶有引數的屬性。這是我解決這個問題的方法

// 具有我想要設定的方法的物件
$auth = new COM("AUTHXOCX.AuthXOCXCtrl.1");

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

// 將物件新增到控制項
$oScript->AddObject('auth', $auth, true);

// 建立一個 VBScript 函式,讓我能夠設定它們
$oScript->AddCode(
'Function fixAccess(accessname)
auth.AuthDataReferrerEnabled(accessname) = 1
auth.AuthDataAuthentiXDBEnabled(accessname) = 0
End Function');

// 執行函式
$oScript->Run("fixAccess", $dir);
2
csaba at alum dot mit dot edu
19 年前
基本的 Windows IO
如果您在 Win32 平台上使用 PHP 的命令列 (CLI) 版本,您可能會想要有一個簡單的圖形介面來取得輸入和輸出。 以下提供了兩者的範例。

<?php
// 首先,我們取得一些輸入
$oScript = new COM("MSScriptControl.ScriptControl");
$oScript->Language = "VBScript";
$title = "I/O 示範:輸入部分";
$initial = "變更此值";
$prompt = "請輸入一個值";

$code = <<<EOF
Function getInput()
inVal = InputBox("
$prompt", "$title", "$initial")
getInput = inVal '如何在 VB 中指定回傳值
End Function
EOF;

$oScript->AddCode($code);
$input = $oScript->Eval("getInput()");
if (
gettype($input)=="NULL") $input = "輸入框已取消";

// 現在我們顯示一些輸出
$oWSH = new COM("WScript.Shell");
$title = "I/O 示範:輸出部分";
$timeout = 2; // 0 代表不逾時
$style = 0 + 48; // 要顯示的按鈕 + 警告符號
$oWSH->Popup($input, $timeout, $title, $style);
?>

這個例子為了說明目的而過於複雜。如果使用的程式碼量只有單一陳述式,則整個輸入部分可以簡化。所以,這樣就足夠了
$code = "InputBox(\"$prompt\", \"$title\", \"$initial\")";
$input = $oScript->Eval($code);

這個技術展示了與 Windows 作業系統和 VBScript 緊密結合的相當大的腳本功能。但是,您應該有非常具體的使用原因,因為在我的測試中,與 PHP 相比,VBScript 的速度往往非常慢。像這樣簡單的 I/O 還不錯,而且彈出視窗的大小可以很大。此外,這可能是一條存取 WinAPI 的可行途徑。

http://www.ss64.com/wsh/popup.html 顯示了 $oWSH->Popup 的一些文件

來自維也納的 Csaba Gabor
2
casanoteva 在 yahoo dot com
15 年前
大家好,我只想分享給大家,我經過多次嘗試和測試後,終於成功地從 Crystal Report 建立 PDF 格式的報表。
最後,我可以在沒有任何錯誤的情況下完成它。
這是我的系統;PHP 5.1.6、MSSQL2005 和 Crystal Report Server XI RL2

<?php

//- 變數 - 適用於您的 RPT 和 PDF
echo "列印報表測試";
$my_report = "D:\\Folder1\\SubFolder1\\Report.rpt"; //
rpt 來源檔案
$my_pdf
= "D:\\Folder1\\SubFolder1\\Report.pdf"; // RPT 匯出為 pdf 檔案
//- 建立新的 COM 物件 - 取決於您的 Crystal Report 版本
$ObjectFactory= new COM("CrystalReports115.ObjectFactory.1") or die ("載入時發生錯誤"); // 呼叫 COM 連接埠
$crapp = $ObjectFactory-> CreateObject("CrystalDesignRunTime.Application"); // 為 Crystal 建立一個實例
$creport = $crapp->OpenReport($my_report, 1); // 呼叫 rpt 報表

// 在之前重新整理資料

//- 設定資料庫登入資訊 - 必須要有
$creport->Database->Tables(1)->SetLogOnInfo("伺服器名稱", "資料庫名稱", "使用者名稱", "密碼");

//- 欄位提示,否則報表會掛起 - 以便通過
$creport->EnableParameterPrompting = 0;

//- DiscardSavedData - 重新整理,然後讀取記錄
$creport->DiscardSavedData;
$creport->ReadRecords();


// 匯出至 PDF 程序
$creport->ExportOptions->DiskFileName=$my_pdf; // 匯出至 pdf
$creport->ExportOptions->PDFExportAllPages=true;
$creport->ExportOptions->DestinationType=1; // 匯出至檔案
$creport->ExportOptions->FormatType=31; // PDF 類型
$creport->Export(false);

//------ 釋放變數 ------
$creport = null;
$crapp = null;
$ObjectFactory = null;

//------ 將報表嵌入網頁中 ------
print "<embed src=\"D:\\Folder1\\SubFolder1\\Report.pdf\" width=\"100%\" height=\"100%\">"



?>

這就是我全部要說的,無論如何,在 Crystal Report 中,我必須檢查「選項」索引標籤中的「DisCardSavedData」、「使用報表儲存資料」和「自動儲存 (1 分鐘)」,並且在「報表選項」中,我也必須檢查「使用報表儲存資料」。

希望這對任何人都有幫助

Casanoteva
1
pavanphp Gudipati
15 年前
在這裡,我描述一個程式,您可以從中使用 COM 元件連接任何 exe (軟體)。
pdf2swf 是一種將 PDf 轉換為 SWF 檔案的軟體。

這是 WScript.Shell 的最佳範例

<?php
#使用 pdf2swf 軟體將 pdf 轉換為 swf 的程式碼
#此程式碼可在 Windows 環境中運作。


## 重要參數
$software_path ="C:\\SWFTools\\pdf2swf" ;
$pdf_path ="C:\\SWFTools\\abcd.pdf" ;
$argument = "-o";
$swf_output ="C:\\SWFTools\\abcd.swf" ;



#實際程式碼
$cmd =" $software_path $pdf_path $argument $swf_output";

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("cmd /C $cmd ", 0, true);

# 0 代表命令提示字元隱藏模式
# 3 代表可見

?>
1
volker 在 kybs dot de
19 年前
若要使用 Windows 語音系統,請從 Microsoft 首頁 (免費下載) 安裝「適用於 Windows 應用程式的 Speech SDK 5.1」。
然後,您可以像這樣進行文字轉語音

$voice = new COM("SAPI.SpVoice");
$voice->Speak("您好,讓我們來聊聊");
1
deletethis@bjoern(at)syltonline(doot)de
19 年前
如果您可以取得舊的「TaskScheduler.dll」並註冊它,則從 PHP 處理和啟動 Windows 工作非常簡單。
當您有必須在不同使用者內容中執行的工作時,這非常有用。準備好使用者工作,並使用 PHP 和 Com 來為其建立一個 Web 介面。

以下是如何啟動 Windows 工作範例

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

我也正在開發一個類別,以處理透過 PHP 新增和移除工作的資訊。如果您有興趣,請與我聯繫。
1
phpguy _from_ toshpro _dot_ com
20 年前
如果您需要連線到 Access 資料庫 (在伺服器上,使用 IIS 或 APACHE 使用者帳戶),以下程式碼可以幫助您簡化此流程。這樣撰寫的原因是,我們同時有 MySQL 和 Access 資料庫,需要能夠來回切換。 `runQuery` 函式會傳回一個二維陣列,並且可以使用欄位名稱或數字作為內部陣列的索引。外部陣列永遠以整數索引。我們也發現 Access 會保持開啟狀態,並在兩小時內從 7MB 增加到 2.5GB 的問題,因此我們每次執行查詢時都會開啟並關閉它。如果它不是 SELECT 查詢,它會傳回 TRUE。如果發生錯誤而失敗,它會傳回 false。

有一個 `showErr` 旗標,我們大多只用於 MySQL,因為您可以輸出 MySQL 錯誤而不會產生 PHP 錯誤。Access 似乎沒有那麼友善。

<?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(
"無法建立 ADODB 連線<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 "執行 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;
}
?>
1
admin at CdnDomainRegistry dot ca
21 年前
這是一個 VBScript 與 PHP 的 COM 元件連線到 IIS Web 伺服器的範例/比較。
這些範例會在 IIS 中備份 IIS MetaBase (您伺服器的網站組態)。

VBScript
Dim obj, iFlags
Set obj = GetObject("IIS://LocalHost")
' 備份到下一個可用的版本號。
' 設定旗標以先儲存中繼資料庫,並且
' 強制備份,即使儲存失敗。
iFlags = (MD_BACKUP_SAVE_FIRST or MD_BACKUP_FORCE_BACKUP)
obj.Backup "MyBackups", MD_BACKUP_NEXT_VERSION, iFlags
' 注意:以上內容是從 Microbucks 複製的。
' 這是您必須執行的方式。
' 例如,使用常數的實際值。
iFlags = (2 or 4)
obj.Backup "MyBackups", &HFFFFFFFF, iFlags

PHP
<?php
$obj
= new COM("IIS://LocalHost")or die("無法實例化 IIS");
$err = com_invoke ($obj, "Backup", "MyBackups", "&HFFFFFFFF", 2|4 );
$obj = null;
print
"err=".$err; // 成功時傳回 0
?>

Glen
1
djogopatrao at gmail dot com
18 年前
我之前關於 Crystal Reports 的筆記消失了,但無論如何,我正在修正它們。

上面的程式碼連線到 COM (請注意版本號碼!在「登錄編輯程式」中搜尋正確的名稱以放入 `$COM_Object`),從檔案 (`$my_report`) 開啟報表,從資料庫重新載入記錄,然後將其匯出到 PDF 檔案 (`$my_pdf`)。

* 重要 * 當從瀏覽器 (我使用 Apache) 呼叫此程式碼,並且報表連線到 ODBC 資料庫時,此程式碼無法運作 (問題特別在於 `ReadRecords()` 行,但當資料未儲存到報表檔案時,也可能會出現問題)。

但是當您透過 PHP-CLI (也就是透過命令列) 執行此程式碼時,它可以正常運作!我回報了這個錯誤,但到目前為止沒有收到回覆 (如果您認為這很重要,請投它一票: http://bugs.php.net/bug.php?id=36959 )。

此外,可能會發生例外狀況,因此請將其放在 try_catch 區塊中。

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

// 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(); // 注意!

$creport->ExportOptions->DiskFileName=$my_pdf;
$creport->ExportOptions->PDFExportAllPages=true;
$creport->ExportOptions->DestinationType=1; // 匯出到檔案
$creport->ExportOptions->FormatType=31; // 類型:PDF
$creport->Export(false);
1
djogopatrao at gmail dot com
18 年前
我在某處 (http://www.recrystallize.com/merchant/supportfaq/supportfaq0003.htm) 找到一份清單,其中將每個 Crystal Reports 版本與其各自的 progID 相關聯 - 這可能會對一些朋友有所幫助。

7 Crystal.CRPE.Application

8.0 CrystalRuntime.Application 或 CrystalRuntime.Application.8

8.5 CrystalRuntime.Application 或 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
1
johnno1985 at gmail dot com
16 年前
我找不到任何關於我嘗試做的事情的範例。在採用了大家的片段後,我最終得到了一些可行的東西。

我正在使用 Crystal Reports 10、MS SQL Server 2005、Apache2 和 PHP5。

我的報表使用 SQL 預存程序,並傳遞一些參數來取得報表資料,因此我們的 PHP 必須設定資料庫登入資訊並傳遞參數。

以下是我提出的解決方案

<?php

//------ 變數 ------
$my_report = "C:\\Apache2\htdocs\\test\\MyReport.rpt"; //這必須是檔案的完整路徑
$my_pdf = "C:\\Apache2\htdocs\\test\\MyReport.pdf";

//------ 建立 Crystal Reports 10 的新 COM 物件 ------
$ObjectFactory= new COM("CrystalReports10.ObjectFactory.1");

//------ 建立應用程式庫的實例 -------
$crapp = $ObjectFactory->CreateObject("CrystalDesignRunTime.Application.10");

//------ 開啟你的 rpt 檔案 ------
$creport = $crapp->OpenReport($my_report, 1);

//------ 設定資料庫登入資訊 ------
$creport->Database->Tables(1)->SetLogOnInfo("MYSERVER", "Database", "user", "password");

//------ 抑制參數欄位提示,否則報表會停滯 ------
$creport->EnableParameterPrompting = 0;

//------ DiscardSavedData 會重新整理您的資料 -------
$creport->DiscardSavedData;
$creport->ReadRecords();

//------ 傳遞公式欄位 --------
$creport->FormulaFields->Item(1)->Text = ("'我的報表標題'");
$creport->ParameterFields(1)->AddCurrentValue ("FirstParameter");
$creport->ParameterFields(2)->AddCurrentValue (2000);

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

//------ 釋放變數 ------
$creport = null;
$crapp = null;
$ObjectFactory = null;

//------ 將報表嵌入網頁中 ------
print "<embed src=\"MyReport.pdf\" width=\"100%\" height=\"100%\">"

?>

顯然,這裡還有很多改進的空間,但它可以運作,而且應該可以讓您步上正軌。我也發現在測試過程中,腳本在抑制參數提示之前會停滯。一旦發生這種情況,一些之前可以運作的匯出功能會完全停止,而且除非我重新啟動 Apache,否則不會再次運作。如果您在腳本停滯後一直遇到問題,這可能是值得做的事情。
1
Eion Robb
10 年前
這裡的所有範例都顯示
<?php $var = new COM('Whatever.Something') or die(); ?>
然而,'or die()' 部分是多餘的,因為會拋出致命的 'com_exception' 例外,導致您的腳本終止。如果您想處理 'or' 條件,您需要捕獲例外,例如
<?php
try {
$var = new COM('Whatever.Something');
} catch (
com_exception $e) {
//無法載入,執行其他操作,例如註冊
exec('regsvr32 /s whatever.dll');
}
?>
2
IceNV
7 年前
在 PHP7(.x) 64 位元下,如果嘗試透過 COM 操作登錄檔 (StdRegProv),則會發生文件錯誤(在 MSDN 端,已回報),導致問題。

實際上,MSDN 報告說登錄檔 hive/root 必須回報為 uint32,這表示在 PHP 64 位元中,人們會建立新的 Variant($root,VT_UI4)。

這會拋出類型不符的錯誤。
似乎在內部,與 MSDN 的說法相反(截至目前,2016-12-13),root 參數實際上必須以 int32 的形式傳遞。

所以您必須
1. 將您的 root 數字轉換為負數 int,以避免在下面建立變體時出現超出範圍的例外狀況(基本上,整數 >= 2^31,您必須自己將其環繞 32 位元帶正負號整數的最大值);
2. 建立新的 Variant($root,VT_I4);
3. 將該變體傳遞到您的 COM API 呼叫。

這在 PHP 7.0 之前沒有發生,因為它之前總是使用 VT_I4 在內部(請參閱 https://bugs.php.net/bug.php?id=73605),但現在它會遵循(而且這樣做是對的)實際的整數長度,因此,如果沒有明確的轉換,PHP7 現在會在 x64 上輸出 VT_I8,而 PHP5 則會輸出 VT_I4。
0
Danil_lll
6 年前
您好。有一個使用 COM 庫(在 C++ 上撰寫)的 C# 程式碼 - hybrid.dll。
我需要將此程式碼從 C# 重寫為 PHP(也就是將 COM 庫連線到 PHP 程式碼)

以下是在 C# 中呼叫的函式
Gr = HybridLib.Hybrid_Color.GREEN;

以下是程式庫中的「Hybrid_Color」清單
enum Hybrid_Color
{
GREEN = 0x00000001,
BLACK = 0x00000002,
BLUE = 0x00000004,
};

該程式庫本身已在 PHP 中啟動
$PHP_Lib = new COM("HybridLib.Hybrid");

無法指派值
$gr = $PHP_Lib -> ..... ?????

我接下來要寫什麼,我不知道...
請告訴我,誰知道...
0
dpchiesa at hotmail dot com
15 年前
這裡有一種使用 DotNetZip 透過 COM 類別在 PHP 中建立 AES 加密 ZIP 檔案的方法。

<?php
try
{
$fname = "zip-generated-from-php-" . date('Y-m-d-His') . ".zip";
$zipOutput = "c:\\temp\\" . $fname;
$zip = new COM("Ionic.Zip.ZipFile");
$zip->Name = $zipOutput;
$dirToZip= "c:\\temp\\psh";
#$dirToZip= "c:\\dinoch\\webs\\php";
$zip->Encryption = 3;
$zip->Password = "AES-Encryption-Is-Secure";
$zip->AddDirectory($dirToZip);
$zip->Save();
$zip->Dispose();

if (
file_exists($zipOutput))
{
header('Cache-Control: no-cache, must-revalidate');
header('Content-Type: application/x-zip');
header('Content-Disposition: attachment; filename=' . $fname);
header('Content-Length: ' . filesize($zipOutput));
readfile($zipOutput);
unlink($zipOutput);
}
else
{
echo
'<html>';
echo
' <head>';
echo
' <title>Calling DotNetZip from PHP through COM</title>';
echo
' <link rel="stylesheet" href="basic.css"/>';
echo
' </head>';
echo
'<body>';
echo
'<h2>Whoops!</h2>' . "<br/>\n";
echo
'<p>The file was not successfully generated.</p>';
echo
'</body>';
echo
'</html>';
}
}
catch (
Exception $e)
{
echo
'<html>';
echo
' <head>';
echo
' <title>Calling DotNetZip from PHP through COM</title>';
echo
' <link rel="stylesheet" href="basic.css"/>';
echo
' </head>';
echo
'<body>';
echo
'<h2>Whoops!</h2>' . "<br/>\n";
echo
'<p>The file was not successfully generated.</p>';
echo
'<p>Caught exception: ', $e->getMessage(), '</p>', "\n";
echo
'<pre>';
echo
$e->getTraceAsString(), "\n";
echo
'</pre>';
echo
'</body>';
echo
'</html>';
}

?>
0
hwcshirley at gmail dot com
18 年前
回覆給:djogopatrao at gmail dot com
我稍微修改了你的程式碼。它現在可以運作了。

$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("無法建立物件");
$creport = $crapp->OpenReport($my_report, 1);
$creport->ReadRecords(); // 注意!

$creport->ExportOptions->DiskFileName=$my_pdf;
$creport->ExportOptions->PDFExportAllPages=true;
$creport->ExportOptions->DestinationType=1; // 匯出到檔案
$creport->ExportOptions->FormatType=31; // 類型:PDF
$creport->Export(false);
0
sodeh at dana dot ir
20 年前
用於連線到 SQL Server 並取得 UTF-8 編碼
使用此方法來連線到資料庫

$db = new COM("ADODB.Connection",NULL, 65001 );
-2
drich at nea-online dot net
21 年前
在 MS Word 中變更欄位 (非表單欄位)...

整個下午都在搜尋這個,因為我們的專案需要用到。也許這可以幫助其他人。

<?php
$input
= "x:\\path\\to\\test.doc";
$word = @new COM("word.application") or die("無法實例化 Word");
print
"已載入 Word,版本 {$word->Version}\n<br>";
$word->Visible = 1;
print
"已設定 Word 為可見<br>";
$word->Documents->Open($input);
print
"已開啟 $input<br>";
$word->Activate;
print
"已啟用 Word<br>";

print
"正在編輯欄位<br>";
$Field = $word->ActiveDocument->Fields(1);
$fieldData = $Field->Result;
$fieldData->Text = "Testing";

// 列印文件。
$word->Printout();

// 關閉 Word
$word->Quit();

// 釋放物件
$word->Release();
$word = null;

?>
-1
sadi at unicornsoftbd dot com
19 年前
如果你的 PHP 設定為 ISAPI 模組,那麼你在 PHP 頁面中建立的 COM 物件將會使用與網頁伺服器相同的記憶體空間。如果你的 COM 物件佔用過多記憶體,可能會強制產生某些 COM 錯誤,因為 PHP 本身不處理 COM 的記憶體使用。而且網頁伺服器也不知道要如何釋放 COM 記憶體。但是,如果你將 PHP 作為 CGI 使用,那麼 PHP 本身會處理 COM 的記憶體使用。在一個使用 COM 且 PHP 作為 ISAPI 模組的腳本中,我曾收到未知的 COM 錯誤。但是當我將 PHP 作為 CGI 使用時,就沒有錯誤。所以那些想要在應用程式中使用 COM 物件的人,請小心這一點。
-1
jon at jonroig dot com
21 年前
這是一個使用 MS Word 列印格式化範本的簡單範例。

首先,我已經在 Word 中建立好發票並將其儲存為 RTF 檔案。
在這個例子中,我使用的是 "sampleInvoice.php"

要被取代的欄位已標記為 ||客戶 ID|| 等等。

<?php
$dataText
= "";

// 開啟檔案
if(!($fp= fopen ("C:\wordTest\sampleInvoice.rtf", "r"))) die ("無法開啟");
$dataText = fread($fp, 2000000);
fclose ($fp);

// 取代範本欄位
$dataText = str_replace ("||CUSTOMER ID||",$customerIDValue, $dataText);

// 將檔案儲存為 rtf 格式
$timeStamp = time();
$saveFile = "C:/wordTemp/".$timeStamp."-invoice-".$customerIDValue.".rtf";
if(!(
$fq= fopen ($saveFile, "w+"))) die ("無法開啟");
fwrite ($fq, $dataText);
fclose ($fq);

// 初始化 Word 元件
$word = new COM("word.application") or die("無法建立 Word 物件");

print
"已載入 Word 版本 ($word->Version)\n";
$word->visible = true;
$word->Documents->Add();

// 開啟檔案
$word->Documents->Open("$saveFile");

// 將檔案輸出至預設印表機
$word->ActiveDocument->PrintOut(1);

// 關閉 Word
$word->Quit();
?>
-1
info at sharedprojects dot nl
21 年前
<?php
// 另一種連線方式
// 此方式連線至系統 DSN 中,在 ODBC 資料來源管理員中新增的 ODBC 資料來源

$odbcname = "northwind";
$conn->Open("DSN=$odbcname");
?>
-2
eguan1ao_at_yahoo_dot_com
22 年前
以下範例示範如何連線至 Microsoft Access 資料庫、執行 SQL 查詢,並將結果顯示在 HTML 中。

<?php

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

$conn = new COM('ADODB.Connection');

// 兩種連線方式,擇一使用。
$conn->Open("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=$db");
//$conn->Open("DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=$db");

$sql = 'SELECT ProductName, QuantityPerUnit, UnitPrice
FROM Products
ORDER BY ProductName'
;
$rs = $conn->Execute($sql);

?>

<table>
<tr>
<th>產品名稱</th>
<th>每單位數量</th>
<th>單價</th>
</tr>
<?php while (!$rs->EOF): ?>
<tr>
<td><?= $rs->Fields['ProductName']->Value ?></td>
<td><?= $rs->Fields['QuantityPerUnit']->Value ?></td>
<td><?= $rs->Fields['UnitPrice']->Value ?></td>
</tr>
<?php $rs->MoveNext() ?>
<?php
endwhile ?>
</table>

<?php

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

?>
-2
mstaiger at informatik dot uni-siegen dot de
22 年前
我發現上面的範例(MS Word)相當不盡人意。特別是,我找不到任何實際上成功執行的人,包括我自己。

因此,您可以試試這個 PowerPoint 範例。
----------------------------------
#實例化一個 PowerPoint 物件。
$ppoint = new COM("PowerPoint.application") or die("無法實例化 PowerPoint");

<?php
#建立新的簡報
$ppoint->Presentations->Add() or die ("無法建立簡報");

//新增投影片
$slide=$ppoint->Presentations[1]->Slides->Add(1,1);

//取得此投影片的名稱
$slidename = $slide->Name();
echo
"<br>slidename : $slidename";

//變更此新投影片的名稱
$slide->Name = "New Slidename";
$slidename = $slide->Name();
echo
"<br>NEW slidename : $slidename";

//儲存簡報
$ppoint->Presentations[1]->SaveAs("c:/InetPub/www/test.ppt");
$ppoint->Presentations[1]->Close();

//關閉 PowerPoint
$ppoint->Quit();

//釋放物件
$ppoint->Release();
$ppoint = null;
-----------------------
?>

設定如下:
w2k-server/office2k/iis5/php 4.1.1 isapi

如果您剛好找到可運作的 word2k 範例,請務必告訴我。

Marc
To Top