business loans
(5 months ago)
Don't have enough cash to buy a house? Don't worry, just because that is possible to take the credit loans to solve all the problems. Therefore get a car loan to buy all you require.
LacyGrant30
(5 months ago)
Don't have enough cash to buy a house? Don't worry, just because that is possible to take the <a href="http://goodfinance-blog.com/topics/credit-loans">credit loans</a> to solve all the problems. Therefore get a car loan to buy all you require.
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 requests to it
• An alternative is to run a separate process as a tcp server and queue • 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: • WMI:
http://www.php.net/manual/en/ref.com.php
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wm http://support.microsoft.com/default.aspx?scid=kb;EN-US;q257757 http://snaps.php.net
• Server-side MS Office: • PHP snapshots
Don't have enough cash to buy a house? Don't worry, just because that is possible to take the credit loans to solve all the problems. Therefore get a car loan to buy all you require.
Don't have enough cash to buy a house? Don't worry, just because that is possible to take the <a href="http://goodfinance-blog.com/topics/credit-loans">credit loans</a> to solve all the problems. Therefore get a car loan to buy all you require.