內建於PHP4裡的COM函數對於我們在win32環境下開發程式是相當有吸引力的,但是至今仍沒有多少相關的技術文檔。本文將以三個例子分別處理 MS office 2000 Word 、 Excel 、 Adobe Distiller 來說明如何在PHP中使用COM函數。 COM技術是由Microsoft在幾年前提出並開發的,本文中提到的相關名詞有OLE, OLE Automation,ActiveX, COM ,這些詞的意思都基本一樣,都表示用一段封裝的代碼(對象)來完成一個windows 應用程式的一些功能。 PHP4 COM 函數可以串連一個對象執行個體,並使用它的方法與屬性。 如果你想使用下面的例子源碼,請參考一下我的配置。 Windows 98 - MS Office 2000 Apache 1.3.9 Windows PHP4.02 Dev (08-20-00) Running as CGI PHP4中的COM標記 現在讓我們開始吧,用PHP4的COM來執行個體化一個組件,需要 new 操作符和對象的 "OLE 程式標識": $instance = new COM("$identifier"); ?> 因為COM是一個PHP4的保留字,它傳送這個對象的標識給一個建構函式,現在得到了這個組件的一個執行個體,根據OOP類的性質,我們可以很容易地訪問它的方法與屬性。 例如: $instance->[Object]->[method1]->[method2]->..->[property]; ?> 就是這麼簡單! OOP的結構在PHP下不能工作,(由於PHP文法的問題,屬性的名字.值是非法字元,如點和圓括弧等),所以PHP4提供了兩個相應的函數: bool com_set(class com_object, string property name, string property_value); mixed com_get(class com_object, string property_name); ?> 最後,PHP4也支援DCOM技術,可以在遠端電腦建立一個對象執行個體。 $Instance = new COM(string "Component name", string "remote_server_address"); ?> 注意:這是用DCOM指令來設定PHP。在將來,PHP開發人員提供Unix下對DCOM的支援。 標識、方法和屬性 標識是一個如下的字串: MS Word: "Word.Application" or "Word.Application.9" MS Excel: "Excel.Application" or "Excel.Sheet" ADOBE Acrobat: "Exch.application" or "dfDistiller.PdfDistiller" 對於最後一個標識,我要指明的是,獲得正確的對象標識名不是一件容易的事。如果你不能訪問VBA文檔,你可以尋找一下windows的註冊表,在 HKEY_CLASSES_ROOT 中尋找一下,你就可以得到一些應用程式的名字。在你的機器上有效對象標識放在 CLSID 子檔案夾下。 應用程式一般會提供文檔說明它的COM方法和屬性。在office2000中,你可以運行程式,開啟VBA編輯器 ,選擇對象編輯器。輸入應用程式庫中的一個方法名或屬性名稱,然後,在下面的視窗中用滑鼠右鍵選擇一個類或成員名稱,點協助,你就會得到關於這個類或成員的描述。你也可以參考 MSDN。一個 Excel 的例子如下: http://msdn.microsoft.com/librar ... odelapplication.htm 用COM函數操作 MS Word 現在,我們開始第一個例子吧: #********************************************************* # 本例來自Zend網站,略有改動 # 開啟一個word執行個體,並建立一個文檔Useless test.doc # 輸入一行文字 "This is a test2..." #********************************************************* #執行個體化一個對象 $word = new COM("word.application") or die("Unable to instantiate Word"); #取得並顯示版本 print "Loaded Word, version {$word->Version} "; #另一種方法去取得版本 $testversion = com_get($word->application,version); print "Version using Com_get(): $testversion "; #使其可見 $word->Visible = 1; #建立新檔案 $word->Documents->Add(); #寫字元 $word->Selection->TypeText("This is a test..."); #儲存 $word->Documents[1]->SaveAs("Useless test.doc"); #關閉 $word->Quit(); ?> 你只要花幾分鐘來讀這個程式,並參考Word的OLE 技術文檔,你將學到幾乎是你在自己程式中所需的全部的操作。 MS Excel在使用PHP的COM函數 如同上面的Word的例子一樣,你應學習這個例子的同時參考Excel的Visual Basic 編輯器中的物件瀏覽器的協助文檔。 #開啟workbook和它的sheet, #本例使用一個試算表是Excel安裝時內建的SOLVSAMP.XLS $workbook = "Crogram FilesMicrosoft officeOfficeSamplesSOLVSAMP.XLS"; $sheet = "Quick Tour"; #執行個體化一個組件的對象 $ex = new COM("Excel.sheet") or Die ("Did not connect"); #取程式名稱和版本 print "Application name:{$ex->Application->value} " ; print "Loaded version: {$ex->Application->version} "; #開啟工作本使我們可使用它 $wkb = $ex->application->Workbooks->Open($workbook) or Die ("Did not open"); #預儲存原來的工作本,建立一個工作本的複本 $ex->Application->ActiveWorkbook->SaveAs("Ourtest"); #$ex->Application->Visible = 1; #本句去注釋讓Excel可見 # 讀寫一個儲存格在一個新的工作表中 # 我們可以讀到這個儲存格 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} "; #Print the value of the cell:10000 $cell->value = 15000; #Change it to 15000 print "New value = {$cell->value} ";#Print the new value=15000 #最後,用新值重新計算這個儲存格 $sheets->Calculate; #必須的如果要計算,手動則是可選的 #可看到效果總價值(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. "; #根據計算公式,廣告影響了公司的開銷,這裡將顯示 $57,809 #使用Excel內建的函數 # 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 "; #Should print monthly payment = $ -1,037.03 #可選,儲存 $ex->Application->ActiveWorkbook->SaveAs("Ourtest"); #關閉,不提問 $ex->application->ActiveWorkbook->Close("False"); unset ($ex); ?> 這個例子讓你的PHP與Excel一同工作了,當然,也有更多的對象可以使用,訪問一個自已寫的OOP封裝類也與訪問excel一樣容易。 用PHP的COM訪問 Adobe Distiller 這最後一個例子不是MS程式了,如果你的程式有一個PostScript檔案,你會對這個有興趣的,改寫(蒸餾)它成為一個PDF文檔. Adobe 有一個程式叫 Distiller ,它可以產生一個執行個體。代碼如下: $pdf = new COM("pdfdistiller.pdfdistiller.1"); ?> 有一點要注意的,是在Distiller 的文檔中給出的這個OLE標識名 "pdfdistiller" 是無效的。 蒸餾一個檔案的最基本的方法是: $pdf->FileToPdf ($psfile, strOutputPDF '', strJobOptions ""); ?> 這 $psfile 是這個PostScript的檔案名稱, strOutputPDF 是輸出檔案PDF的檔案名稱。 StrJobOptions 是Distiller的參數檔案名稱,最後兩個參數是可選的,預設是同一名字。 這PS檔案名稱與PDF檔案名稱,使用這個預設的Job options 檔案。例如: $pdf->FileToPdf ($psfile, "", ""); #這兒$psfile 可以是 Myfile.ps 將返回 Myfile.pdf 檔案。 ?> 在Distiller中有更多的方法和屬效能被用。如果你感興趣,請參考一下Adobe的技術文檔。 中止/可能的問題 如果你的代碼中發生了什麼錯誤,你可能會建立了一個執行個體,但沒有正常地關閉它。最糟的是,這個應用程式可能被這個執行個體所保持,結果,在你的程式列表中就存在多份這個程式的副本,即使你更正了這個錯誤也會干擾你的結果。解決方案是:修正一個bug以來要及時清除它們在你重新開始運行之前,用 並結束任務。同樣的原因,在你的代碼最後,也要及時關閉這個程式並刪除這個執行個體。 你有一些技巧在處理 com_get 和 com_set的異常時。例如: $Version = Com_get($instance->Application,"Version"); 將會在Word中工作但在Excel中會產生一個錯誤。 有一些對象在PHP4中是不能執行個體化的,這是因為這個程式要一個自訂的介面,但PHP4不支援。 為什麼我們要用它? 我希望這三個例子可以給你一些思考的線索,PHP的COM允許你在PHP的指令碼中訪問windows4的程式。這個代碼比ASP簡單並且能整合其它的PHP對資料庫強大的支援功能。Microsoft 在各個方面都大力銷售這個COM 技術,在不同的名稱和結構下,如 COM+(Combine COM with Microsoft Transaction Server MTS), ADO, OLE DB, OWC, Windows DNA, 等等。 PHP 和 Apache的結合,提供了一個開放源碼的解決方案。 |