Published on

A discussion of the OLE/COM bridge in PHP 5.
These slides are from 2004.
I\'m hoping that SlideShare preserves the speakers notes; there\'s a good deal of information in there to complement the slide content.

Published in: Technology
  • Is there a way to use this OCX in PHP? or can i wrap it in a way? please if you can provide an example
    Are you sure you want to  Yes  No
    Your message goes here
  • I was reading the posts you have stated, I am facing a problem with COM and OCX, the issue is that the OCX i am using is provided with PSDispatch (Proxy for Dispinterface), whenever i call functions from this OCX using PHP/COM i get PHP Fatal error: Uncaught exception 'com_exception' with message 'Error [0x8000ffff] Catastrophic failure
    Are you sure you want to  Yes  No
    Your message goes here
  • Hi,
    Are you sure you want to  Yes  No
    Your message goes here
  • The cool thing is that you can persist (and restore) the object state into any PHP compatible stream.
    So, we’ve dumped the object state onto an ftp site here, but could have stored it into a memory stream or some kind of db stream or …

    Bogus because I don’t have a practical use for it (only common COM object that supports IPersist is the MSXML stuff; you can save to file from there using native API (but not to PHP streams so…)
    Are you sure you want to  Yes  No
    Your message goes here
  • Can load into any activescript host; Windows Scripting Host, ASP, the ScriptControl we used earlier, the WeaverSlave IDE, Kapsules desktop widget application
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • PHP and COM

    1. 1. PHP and COM <ul><li>Wez Furlong < [email_address] > </li></ul>
    2. 2. Plan <ul><li>What is COM? </li></ul><ul><li>What's it good for? </li></ul><ul><li>How do I use it? </li></ul><ul><ul><li>Instantiation... and Monikers </li></ul></ul><ul><ul><li>Exceptions </li></ul></ul><ul><ul><li>Typelibraries </li></ul></ul><ul><ul><li>Variants </li></ul></ul><ul><ul><li>.Net Interop </li></ul></ul><ul><ul><li>ActiveScript </li></ul></ul><ul><ul><li>Persistence (experimental) </li></ul></ul>
    3. 3. Common Object Model <ul><li>Frequently mislabeled as Component Object Model </li></ul><ul><li>Specifies programming interfaces for OO code </li></ul><ul><li>Those interfaces are programming language independent </li></ul><ul><li>Provides a mechanism for code re-use </li></ul>
    4. 4. OLE <ul><li>A subset of these interfaces are collectively known as OLE: Object Linking and Embedding </li></ul><ul><li>They define a way to dynamically create and invoke methods on objects that implement those interfaces </li></ul><ul><li>PHP COM is really PHP OLE </li></ul>
    5. 5. COM Servers <ul><li>A COM Server is some module that exposes a COM interface via creatable classes </li></ul><ul><li>In-Proc (DLL) => fast </li></ul><ul><li>Out-of-Proc (EXE) => not so fast </li></ul><ul><li>DCOM => on another machine </li></ul><ul><li>Your code sees these as the same thing </li></ul>
    6. 6. What's it good for? <ul><li>Talking to other applications and libraries </li></ul><ul><li>Most win32 software vendors provide a COM interface </li></ul><ul><li>Can be used to transition from ASP to PHP </li></ul><ul><li>Can use “easy” languages to extend PHP </li></ul>
    7. 7. How do I use it? <ul><li>$word = new COM(“Word.Application”); $word->visible = true; $word->Documents->Add(); $word->Selection->TypeText(“hello”); $word->ActiveDocument->SaveAs(“test.doc”); $word->Quit(); </li></ul>
    8. 8. Instantiation <ul><li>$word = new COM(“Word.Application”, array( ‘Server’ => ‘otherbox’, ‘Username’ => ‘foo’, ‘Password’ => ‘bar’ ), CP_UTF8); </li></ul>
    9. 9. Exceptions <ul><li>try { $o = new COM(“…”); } catch (com_exception $e) { print “failed to create: $e”; } </li></ul><ul><li>$e->getCode() corresponds to weird hex number (will show example later) </li></ul>
    10. 10. Typelibraries <ul><li>Import constants from a COM server as regular PHP constants. </li></ul><ul><li>Manually </li></ul><ul><ul><li>com_load_typelib(‘Word.Application’); </li></ul></ul><ul><ul><li>echo wdGoToBookmark; </li></ul></ul><ul><li>From php.ini: </li></ul><ul><ul><li>com.typelib_file=C:mytypelibs.txt </li></ul></ul>
    11. 11. Variants <ul><li>PHP COM is really PHP Variant </li></ul><ul><li>Variant is win32 equivalent of PHP typeless variables </li></ul><ul><li>JIT conversion in PHP 5 </li></ul><ul><li>OLE default properties </li></ul><ul><ul><li>$doc = $word->ActiveDocument; </li></ul></ul><ul><ul><li>print $doc; // prints document title </li></ul></ul>
    12. 12. Variant Arrays <ul><li>$user = new COM( “LDAP://cn=user,ou=test,dc=php,dc=net”); </li></ul><ul><li>$arr = $user->GetEx(“otherHomePhone”); </li></ul><ul><li>for ($i = 0; $i < count($arr); $i++) { print $arr[$i] . “ ”; } </li></ul>
    13. 13. Iterators <ul><li>Set domainObject = GetObject(&quot;WinNT://Domain&quot;) </li></ul><ul><li>For Each obj in domainObject Response.Write obj.Name & &quot;<br />“ Next </li></ul><ul><li>$domainObject = new COM(&quot;WinNT://Domain&quot;); </li></ul><ul><li>foreach ($domainObject as $obj) { echo $obj->Name . &quot;<br />&quot;; } </li></ul>
    14. 14. Variant Functions <ul><li>Arithmetic </li></ul><ul><ul><li>variant_add variant_sub </li></ul></ul><ul><ul><li>variant_mul variant_div </li></ul></ul><ul><li>Casting </li></ul><ul><ul><li>variant_set_type (VT_BSTR etc.) </li></ul></ul><ul><ul><li>variant_get_type </li></ul></ul><ul><ul><li>variant_date_from_timestamp </li></ul></ul><ul><ul><li>variant_date_to_timestamp </li></ul></ul><ul><li>VB-like behaviour </li></ul>
    15. 15. .Net Interop <ul><li>.Net is modern replacement for VB </li></ul><ul><li>Uses similar concepts to COM </li></ul><ul><li>MS provide an “Interop” layer to map .Net assemblies into COM </li></ul><ul><li>$stack = new DOTNET(‘mscorlib’, ‘System.Collections.Stack’); </li></ul><ul><li>$stack->push(‘.Net’); </li></ul><ul><li>$stack->Push(‘Hello ’); </li></ul><ul><li>echo $stack->pop() . $stack->pop(); </li></ul>
    16. 16. Some Sample Scripts <ul><li>Look at some common tasks implemented in PHP </li></ul><ul><li>Gotchas? </li></ul>
    17. 17. WMI for system monitoring <ul><li>$wmi = new COM( “WinMgmts:{impersonationLevel=impersonate}” .“//{$hostname}/root/cimv2” ); </li></ul><ul><li>$cpus = $wmi->ExecQuery( &quot;Select * from Win32_Processor&quot;); </li></ul><ul><li>foreach ($cpus as $cpu) { printf(“%s %dMHz %d%% ”, $cpu->Name, $cpu->MaxClockSpeed, $cpu->LoadPercentage); } </li></ul>
    18. 18. ADO DB <ul><li>Useful for transitioning ASP </li></ul><ul><li>Often faster to use odbc or native drivers </li></ul><ul><li>$conn = new COM(‘ADODB.Connection’); $conn->Open($dsn); $conn->Execute(‘update …’); </li></ul><ul><li>$rs = new COM(‘ADODB.Recordset’); $rs->Open(‘select foo from bar’, $conn); </li></ul><ul><li>while (!$rs->EOF()) { echo $rs->Fields(‘foo’); $rs->MoveNext(); } </li></ul>
    19. 19. MS Office (Word) <ul><li>$word = new COM(“Word.Application”); </li></ul><ul><li>$word->visible = true; </li></ul><ul><li>$word->Documents->Add(); </li></ul><ul><li>$word->Selection->TypeText(“hello ” . $_SESSION[‘username’]); </li></ul><ul><li>$word->ActiveDocument->SaveAs(“test.doc”); </li></ul><ul><li>$word->Quit(); </li></ul>
    20. 20. Shmop mutex <ul><li>Use a single instance of Word </li></ul><ul><li>Use mutex to control access to it </li></ul><ul><li>extension=php_shmop.dll </li></ul><ul><li>Need to be running ISAPI or Apache module on win2k and later </li></ul>
    21. 21. Shmop mutex 2 <ul><li>function try_mutex($timeout) { $t = time(); do { $mtx = shmop_open(42, “cwn”, 0644, 1); if ($mtx) return $mtx; usleep(200000); // 0.2 seconds } while (time() < $t + $timeout); return false; } </li></ul><ul><li>function drop_mutex($mtx) { shmop_delete($mtx); } </li></ul>
    22. 22. Shmop mutex 3 <ul><li>com_get_active_object() returns a handle to an instance from the Running Object Table </li></ul><ul><li>function get_one() { try { $w = com_get_active_object(‘Word.Application’); return $w; } catch (com_exception $e) { if ($e->getCode() == MK_E_UNAVAILABLE) return new COM(‘Word.Application’); throw $e; } } </li></ul>
    23. 23. Shmop mutex 4 <ul><li>$mtx = try_mutex(3); if (!$mtx) { .. Try again later … } $word = get_one(); $word->Documents->Add(); $word->Selection->TypeText(“foo”); $word->ActiveDocument->SaveAs($filename); $word->ActiveDocument->Close(); drop_mutex($mtx); readfile($filename); </li></ul>
    24. 24. Create a server app <ul><li>The shmop idea is prone to failure if something bad happens to a request that holds the mutex </li></ul><ul><li>An alternative is to run a separate process as a tcp server and queue requests to it </li></ul><ul><li>PHP 5 makes this easy </li></ul>
    25. 25. Client for Word Daemon <ul><li>$daemon = stream_socket_client(‘’); </li></ul><ul><li>if ($daemon) { </li></ul><ul><li>fwrite($daemon, serialize($data)); </li></ul><ul><li>$result = fgets($daemon); </li></ul><ul><li>} </li></ul>
    26. 26. Word Daemon <ul><li>$w = new COM(‘Word.Application’); $s = stream_socket_server(‘’); while (true) { $client = stream_socket_accept($s); $data = unserialize(stream_get_contents($client)); generate_word_doc($data); fwrite($client, “DONE ”); fclose($client); } </li></ul>
    27. 27. With Events <ul><li>COM event handling framework is build from ‘Connection Points’ </li></ul><ul><li>A source object is implements IConnectionPointContainer </li></ul><ul><li>A sink object (callback handler) implements a dispinterface </li></ul><ul><li>dispinterfaces allow a loose handler implementation; perfect for scripting languages </li></ul>
    28. 28. turning on events <ul><li>bool com_event_sink($object, </li></ul><ul><li>$sinkobject [, $sinkname]); </li></ul><ul><li>Plumbs in event handling; </li></ul><ul><li>Events from $object are sunk into $sinkobject </li></ul>
    29. 29. Sinking events from IE <ul><li>$ie = new COM(&quot;InternetExplorer.Application&quot;); </li></ul><ul><li>$ie->Visible = true; </li></ul><ul><li>$ie->Navigate(&quot;;); </li></ul>
    30. 30. IE Events 2 <ul><li>class IEEvents { var $dom = null; function DocumentComplete($dom, $url) { echo “$url complete ”; $this->dom = $dom; } } </li></ul>
    31. 31. IE Events 3 <ul><li>$sink = new IEEvents; $ie = new COM(&quot;InternetExplorer.Application&quot;); $ie->Visible = true; com_event_sink($ie, $sink, ‘DWebBrowserEvents2’); $ie->Navigate(&quot;;); while (!$sink->dom) { com_message_pump(4000); } </li></ul><ul><li>// we can do stuff with $sink->dom here, or just continue with something else </li></ul>
    32. 32. IActiveScript <ul><li>A set of interfaces that abstract scripting engines </li></ul><ul><li>A compatible host can run any compliant script engine </li></ul><ul><li>Works in both directions; you can load engines in php, and you can load php into other hosts </li></ul>
    33. 33. Invoke JScript from PHP <ul><li>class foo { function bar($msg) { echo $msg; } } </li></ul><ul><li>$js = new COM(‘ScriptControl’); $js->Language = ‘JScript’; $js->AddObject(‘foo’, new foo, false); $js->AddCode(‘“js!”);’); </li></ul>
    34. 34. ActiveScript <ul><li>This SAPI lets you load PHP into other scripting engines </li></ul><ul><li>You need to regsvr32 php5activescript.dll to enable it </li></ul><ul><li>Language = PHPScript </li></ul><ul><li>Sadly, can't load PHP into PHP via COM due to architecture of PHP SAPI interface </li></ul>
    35. 35. Using PHP in Windows Script Host <ul><li>Create a .wsf file like this: </li></ul><ul><li><job id=&quot;test&quot;> <script language=&quot;PHPScript&quot;> $WScript->Echo(&quot;Hello&quot;); </script> </job> </li></ul><ul><li>cscript test.wsf </li></ul>
    36. 36. Persistence Helper <ul><li>Not everything supports the relevant interfaces, so not totally useful </li></ul><ul><li>Intention is to persist object state into streams or strings and store it into some kind of DB. </li></ul><ul><li>PHP streams are mapped as COM IStreams </li></ul>
    37. 37. Bogus Example <ul><li>$object = new COM(‘…’); $object->doSomething(); $dest = fopen(‘ftp://…/…’, ‘wb’); $p = new COMPersistHelper($object); $p->SaveToStream($dest); </li></ul>
    38. 38. Bogus Example 2 <ul><li>$object = new COM(‘…’); $src = fopen(‘ftp://…/…’, ‘rb’); $p = new COMPersistHelper($object); $p->LoadFromStream($src); </li></ul><ul><li>// $object is now in same state as it was on previous slide </li></ul>
    39. 39. Resources <ul><li>These slides are on my blog and on </li></ul><ul><li>PHP COM manual: </li></ul><ul><li>WMI: </li></ul><ul><li>Server-side MS Office:;EN-US;q257757 </li></ul><ul><li>PHP snapshots </li></ul>