Search code examples
phpmultidimensional-arrayvariantcomobject

How do you read from a multidimensional variant array returned from a COM object in PHP?


I'm working with a COM object that returns a multidimensional VARIANT array (vt_array), and I'm trying to read values from the array.

When I use print_r($mdArray) it displays variant Object. (variant_get_type($mdArray) returns 8204.)

I tried using foreach ($mdArray as $oneArray) but I get the message:

Warning: Loader::getfields() [loader.getfields]: Can only handle single dimension variant arrays (this array has 2) in C:\Inetpub\wwwroot\root\script\fileloader.php on line 135 Fatal error: Uncaught exception 'Exception' with message 'Object of type variant did not create an Iterator' in C:\Inetpub\wwwroot\root\script\fileloader.php:135 Stack trace: #0 C:\Inetpub\wwwroot\root\script\fileloader.php(135): Loader::getfields() #1 C:\Inetpub\wwwroot\root\testloader.php(21): Loader->getfields() #2 {main} thrown in C:\Inetpub\wwwroot\root\script\fileloader.php on line 135

(The foreach loop is on line 135)

The only information I can get about the array is by using count($mdArray) which returns 8.

If anyone here has any experience reading from multidimensional VARIANT arrays please tell me how this can be done.


Solution

  • Try this to extract array values through "VBScript". Yes, you read that right...

    <?php
    
    $com = new COM("MSScriptControl.ScriptControl");
    $com->Language = 'VBScript';
    $com->AllowUI = false;
    $com->AddCode('
        Function getArrayVal(arr, indexX, indexY)
            getArrayVal = arr(indexX, indexY)
        End Function
    ');
    
    $y1 = 0;
    $y2 = 1;
    for ($x=0; $x < count($mdArray); $x++) {
        echo $com->Run('getArrayVal', $mdArray, $x, $y1) . ": ";
        echo $com->Run('getArrayVal', $mdArray, $x, $y2) . "\n";
        }
    
    ?>
    

    Tested good on a VBScript-created array, which otherwise gave me the exact same issues and errors as you when trying to coerce it to behave like a PHP array. The above method spawned by the unholy union of PHP and VBscript should extract values piece by piece just fine.

    To explain $y1 = 0; $y2 = 1;, keep in mind the parameters of the VBScript function are byref, so you can't pass anything in except a variable.

    Edit: Added $com->AllowUI = false to shut off any on-screen popups. Otherwise it would freeze the request if a MsgBox() somehow got called from VBScript and no one was at the server terminal to click 'ok'.