Slideshare.net (beta)

 
Post to TwitterPost to Twitter
Post: 
Myspace Hi5 Friendster Xanga LiveJournal Facebook Blogger Tagged Typepad Freewebs BlackPlanet gigya icons

All comments

Add a comment on Slide 1

If you have a SlideShare account, login to comment; else you can comment as a guest


Showing 1-50 of 2 (more)

PHP and COM

From wezfurlong, 3 months ago

A discussion of the OLE/COM bridge in PHP 5.<br />These slides are fro more

2731 views  |  28 comments  |  1 favorite  |  94 downloads  |  15 embeds (Stats)
 

Categories

Add Category
 
 
 
 

Groups / Events

 
Embed
options

More Info

This slideshow is Public
Total Views: 2731
on Slideshare: 2261
from embeds: 470

Slideshow transcript

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

Slide 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)

Slide 3: Common Object Model • Frequently mislabeled as Component Object Model • Specifies programming interfaces for OO code • Those interfaces are programming language independent • Provides a mechanism for code re-use

Slide 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

Slide 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

Slide 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

Slide 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();

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

Slide 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)

Slide 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

Slide 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

Slide 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”; }

Slide 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 />\"; }

Slide 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

Slide 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();

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

Slide 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); }

Slide 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(); }

Slide 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();

Slide 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

Slide 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); }

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

Slide 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);

Slide 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

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

Slide 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); }

Slide 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

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

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

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

Slide 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

Slide 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

Slide 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!”);’);

Slide 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

Slide 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

Slide 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

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

Slide 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

Slide 39: Resources • These slides are on my blog and on slideshare.net http://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/wm • Server-side MS Office: http://support.microsoft.com/default.aspx?scid=kb;EN-US;q257757 • PHP snapshots http://snaps.php.net