1 / 39

PHP and COM

PHP and COM. Wez Furlong < wez@messagesystems.com >. Plan. What is COM? What's it good for? How do I use it? Instantiation... and Monikers Exceptions Typelibraries Variants .Net Interop ActiveScript Persistence (experimental). Common Object Model.

angeln
Download Presentation

PHP and COM

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. PHP and COM Wez Furlong<wez@messagesystems.com>

  2. Plan • What is COM? • What's it good for? • How do I use it? • Instantiation... and Monikers • Exceptions • Typelibraries • Variants • .Net Interop • ActiveScript • Persistence (experimental)

  3. Common Object Model • Frequently mislabeled asComponent Object Model • Specifies programming interfaces for OO code • Those interfaces are programming language independent • Provides a mechanism for code re-use

  4. OLE • A subset of these interfaces are collectively known as OLE:Object Linking and Embedding • They define a way to dynamically create and invoke methods on objects that implement those interfaces • PHP COM is really PHP OLE

  5. COM Servers • A COM Server is some module that exposes a COM interface via creatable classes • In-Proc (DLL) => fast • Out-of-Proc (EXE) => not so fast • DCOM => on another machine • Your code sees these as the same thing

  6. What's it good for? • Talking to other applications and libraries • Most win32 software vendors provide a COM interface • Can be used to transition from ASP to PHP • Can use “easy” languages to extend PHP

  7. How do I use it? • $word = new COM(“Word.Application”);$word->visible = true;$word->Documents->Add();$word->Selection->TypeText(“hello”);$word->ActiveDocument->SaveAs(“test.doc”);$word->Quit();

  8. Instantiation • $word = new COM(“Word.Application”, array( ‘Server’ => ‘otherbox’, ‘Username’ => ‘foo’, ‘Password’ => ‘bar’ ), CP_UTF8);

  9. Exceptions • try { $o = new COM(“…”);} catch (com_exception $e) { print “failed to create: $e”;} • $e->getCode() corresponds to weird hex number (will show example later)

  10. Typelibraries • Import constants from a COM server as regular PHP constants. • Manually • com_load_typelib(‘Word.Application’); • echo wdGoToBookmark; • From php.ini: • com.typelib_file=C:\mytypelibs.txt

  11. Variants • PHP COM is really PHP Variant • Variant is win32 equivalent of PHP typeless variables • JIT conversion in PHP 5 • OLE default properties • $doc = $word->ActiveDocument; • print $doc; // prints document title

  12. Variant Arrays • $user = new COM( “LDAP://cn=user,ou=test,dc=php,dc=net”); • $arr = $user->GetEx(“otherHomePhone”); • for ($i = 0; $i < count($arr); $i++) { print $arr[$i] . “\n”;}

  13. Iterators • Set domainObject = GetObject("WinNT://Domain") • For Each obj in domainObject Response.Write obj.Name & "<br />“Next • $domainObject = new COM("WinNT://Domain"); • foreach ($domainObject as $obj) { echo $obj->Name . "<br />";}

  14. Variant Functions • Arithmetic • variant_add variant_sub • variant_mul variant_div • Casting • variant_set_type (VT_BSTR etc.) • variant_get_type • variant_date_from_timestamp • variant_date_to_timestamp • VB-like behaviour

  15. .Net Interop • .Net is modern replacement for VB • Uses similar concepts to COM • MS provide an “Interop” layer to map .Net assemblies into COM • $stack = new DOTNET(‘mscorlib’, ‘System.Collections.Stack’); • $stack->push(‘.Net’); • $stack->Push(‘Hello ’); • echo $stack->pop() . $stack->pop();

  16. Some Sample Scripts • Look at some common tasks implemented in PHP • Gotchas?

  17. WMI for system monitoring • $wmi = new COM( “WinMgmts:{impersonationLevel=impersonate}” .“//{$hostname}/root/cimv2”); • $cpus = $wmi->ExecQuery( "Select * from Win32_Processor"); • foreach ($cpus as $cpu) { printf(“%s %dMHz %d%%\n”, $cpu->Name, $cpu->MaxClockSpeed, $cpu->LoadPercentage);}

  18. ADO DB • Useful for transitioning ASP • Often faster to use odbc or native drivers • $conn = new COM(‘ADODB.Connection’);$conn->Open($dsn);$conn->Execute(‘update …’); • $rs = new COM(‘ADODB.Recordset’);$rs->Open(‘select foo from bar’, $conn); • while (!$rs->EOF()) { echo $rs->Fields(‘foo’); $rs->MoveNext();}

  19. MS Office (Word) • $word = new COM(“Word.Application”); • $word->visible = true; • $word->Documents->Add(); • $word->Selection->TypeText(“hello ” . $_SESSION[‘username’]); • $word->ActiveDocument->SaveAs(“test.doc”); • $word->Quit();

  20. Shmop mutex • Use a single instance of Word • Use mutex to control access to it • extension=php_shmop.dll • Need to be running ISAPI or Apache module on win2k and later

  21. Shmop mutex 2 • 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;} • function drop_mutex($mtx) { shmop_delete($mtx);}

  22. Shmop mutex 3 • com_get_active_object() returns a handle to an instance from the Running Object Table • 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; }}

  23. Shmop mutex 4 • $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);

  24. Create a server app • The shmop idea is prone to failure if something bad happens to a request that holds the mutex • An alternative is to run a separate process as a tcp server and queue requests to it • PHP 5 makes this easy

  25. Client for Word Daemon • $daemon = stream_socket_client(‘127.0.0.1:4000’); • if ($daemon) { • fwrite($daemon, serialize($data)); • $result = fgets($daemon); • }

  26. Word Daemon • $w = new COM(‘Word.Application’);$s = stream_socket_server(‘127.0.0.1:4000’);while (true) { $client = stream_socket_accept($s); $data = unserialize(stream_get_contents($client)); generate_word_doc($data); fwrite($client, “DONE\r\n”); fclose($client);}

  27. With Events • COM event handling framework is build from ‘Connection Points’ • A source object is implements IConnectionPointContainer • A sink object (callback handler) implements a dispinterface • dispinterfaces allow a loose handler implementation; perfect for scripting languages

  28. turning on events • bool com_event_sink($object, • $sinkobject [, $sinkname]); • Plumbs in event handling; • Events from $object are sunk into $sinkobject

  29. Sinking events from IE • $ie = new COM("InternetExplorer.Application"); • $ie->Visible = true; • $ie->Navigate("http://www.php.net");

  30. IE Events 2 • class IEEvents { var $dom = null; function DocumentComplete($dom, $url) { echo “$url complete\n”; $this->dom = $dom; }}

  31. IE Events 3 • $sink = new IEEvents;$ie = new COM("InternetExplorer.Application");$ie->Visible = true;com_event_sink($ie, $sink, ‘DWebBrowserEvents2’);$ie->Navigate("http://www.php.net");while (!$sink->dom) { com_message_pump(4000);} • // we can do stuff with $sink->dom here, or just continue with something else

  32. IActiveScript • A set of interfaces that abstract scripting engines • A compatible host can run any compliant script engine • Works in both directions; you can load engines in php, and you can load php into other hosts

  33. Invoke JScript from PHP • class foo { function bar($msg) { echo $msg; }} • $js = new COM(‘ScriptControl’);$js->Language = ‘JScript’;$js->AddObject(‘foo’, new foo, false);$js->AddCode(‘foo.bar(“js!”);’);

  34. ActiveScript • This SAPI lets you load PHP into other scripting engines • You need to regsvr32 php5activescript.dll to enable it • Language = PHPScript • Sadly, can't load PHP into PHP via COM due to architecture of PHP SAPI interface

  35. Using PHP in Windows Script Host • Create a .wsf file like this: • <job id="test"> <script language="PHPScript"> $WScript->Echo("Hello"); </script></job> • cscript test.wsf

  36. Persistence Helper • Not everything supports the relevant interfaces, so not totally useful • Intention is to persist object state into streams or strings and store it into some kind of DB. • PHP streams are mapped as COM IStreams

  37. Bogus Example • $object = new COM(‘…’);$object->doSomething();$dest = fopen(‘ftp://…/…’, ‘wb’);$p = new COMPersistHelper($object);$p->SaveToStream($dest);

  38. Bogus Example 2 • $object = new COM(‘…’);$src = fopen(‘ftp://…/…’, ‘rb’);$p = new COMPersistHelper($object);$p->LoadFromStream($src); • // $object is now in same state as it was on previous slide

  39. Resources • These slides are on my blog and on slideshare.nethttp://netevil.org • PHP COM manual:http://www.php.net/manual/en/ref.com.php • WMI:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmi_start_page.asp • Server-side MS Office:http://support.microsoft.com/default.aspx?scid=kb;EN-US;q257757 • PHP snapshotshttp://snaps.php.net

More Related