PHP and COM
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

PHP and COM

  • 15,564 views
Uploaded on

A discussion of the OLE/COM bridge in PHP 5. ...

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.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    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
    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
    Your message goes here
  • PHP also has an ActiveScript compatible interface; it is still a little bit experimental, but works for most of the stuff I’ve tried.
    The DLL is called php5activecript.dll and the best available version can be found in the PECL repository on our snapshots site.
    Are you sure you want to
    Your message goes here
  • The Language property can be set to the name of any language that you have installed; by default, windows ships with javascript and vbscript.
    You can download ActivePerl, ActiveRuby and ActivePython
    The COM extension provides an IDispatchEx wrapper for PHP objects, so that you can invoke them from other COM compatible scripting languages using this technique.
    Are you sure you want to
    Your message goes here
  • The main new thing here is com_message_pump(); you can thing of this as being something like sleep() except that the time is measured in milliseconds. The other big difference is that it will handle COM messages while it sleeps, returning after it processes the queue.
    We need to do this so that the COM can maintain various state and be able to actually call into our callback.
    If you’re writing any COM scripts, you should probably use com_message_pump() in any place where you are sleeping for more than a couple of seconds.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
15,564
On Slideshare
14,459
From Embeds
1,105
Number of Embeds
21

Actions

Shares
Downloads
315
Comments
28
Likes
5

Embeds 1,105

http://www.phpeye.com 504
http://netevil.org 357
http://www.planet-php.net 78
http://phpeye.com 52
http://wezfurlong.org 36
http://www.planet-php.org 16
http://www.slideshare.net 16
http://min2liz.net 13
http://planet-php.org 10
http://www.netevil.org 8
http://www.webonorme.net 3
http://www.linkedin.com 2
http://lj-toys.com 2
https://rccdopencampus.blackboard.com 1
http://planet-php.net 1
http://100.ig.gmodules.com 1
http://cameleon.mine.nu 1
http://209.85.175.104 1
http://64.233.169.104 1
http://64.233.179.104 1
http://axwl.vicp.cc 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. PHP and COM
    • Wez Furlong < [email_address] >
  • 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 as Component 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] . “ ”; }
  • 13. Iterators
    • Set domainObject = GetObject(&quot;WinNT://Domain&quot;)
    • For Each obj in domainObject Response.Write obj.Name & &quot;<br />“ Next
    • $domainObject = new COM(&quot;WinNT://Domain&quot;);
    • foreach ($domainObject as $obj) { echo $obj->Name . &quot;<br />&quot;; }
  • 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( &quot;Select * from Win32_Processor&quot;);
    • foreach ($cpus as $cpu) { printf(“%s %dMHz %d%% ”, $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 ”); 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(&quot;InternetExplorer.Application&quot;);
    • $ie->Visible = true;
    • $ie->Navigate(&quot;http://www.php.net&quot;);
  • 30. IE Events 2
    • class IEEvents { var $dom = null; function DocumentComplete($dom, $url) { echo “$url complete ”; $this->dom = $dom; } }
  • 31. IE Events 3
    • $sink = new IEEvents; $ie = new COM(&quot;InternetExplorer.Application&quot;); $ie->Visible = true; com_event_sink($ie, $sink, ‘DWebBrowserEvents2’); $ie->Navigate(&quot;http://www.php.net&quot;); 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=&quot;test&quot;> <script language=&quot;PHPScript&quot;> $WScript->Echo(&quot;Hello&quot;); </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.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/wmi_start_page.asp
    • Server-side MS Office: http://support.microsoft.com/default.aspx?scid=kb;EN-US;q257757
    • PHP snapshots http://snaps.php.net