1

So I'm hoping someone can help and I'm sure this is probably something simple I'm missing. I'm using PHP to access a .net API for a third party software.

Based on the very minimalist documentation on the API I have a working vbsript that connects to the object, performs a login and then does a query which results in the output of the query being dumped to a message box.

Here's the vbscript sample:

'Test device status
Set xxx = CreateObject("The.API.Object.Goes.Here")
'Login
Result = Xxx.LoginToHost("xxx.xxx.xxx.xxx","8989","Administrator","")
if (Result = true) then
  MsgBox("OK")
else
  MsgBox("Error - " & Xxx.LastError)
  WScript.Quit
end if
'Get Status
Result = Xxx.GetDeviceStatus("", out)
if (Result = true) then
  MsgBox(out)
else
  MsgBox("Error - " & Xxx.LastError)
end if
'Logout
Result = Xxx.Logout()
if (Result = true) then
  MsgBox("Logout OK")
else
  MsgBox("Error - " & Xxx.LastError)
end if

The Xxx.GetDeviceStatus has two perimeters, the first being a device target or if left blank returns all devices, the second is the string variable to dump the result in.

When the script executes, the second message box contains a list of all devices as I would expect.

In PHP I have:

$obj = new DOTNET("XxxScripting, Version=1.0.XXXX.XXXXXX, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX","Here.Goes.The.Api");
$obj->LoginToHost('xxx.xxx.xxx.xxx','8989','Administrator','');
$result = $obj->GetDeviceStatus('','out');
echo $result."<br />";

echoing result gives 1 because the value of result is a boolean value and GetDeviceStatus is successful. What I can't figure out is how to get the value of 'out' which is the actual query result.

Any help would be greatly appreciated.

user692942
  • 16,398
  • 7
  • 76
  • 175
N8hack
  • 13
  • 3
  • Read the type library of the mysterious object. –  Feb 24 '16 at 08:09
  • Looks to me like `GetDeviceStatus` expects the second parameter to be a variable so it can pass data to it. If you look at your definition in PHP compared to VBScript they are not equivalent, in PHP you pass the string `'out'` instead of a variable called `out` like you do in VBScript. Maybe try defining a variable called `$out` in PHP and pass that as the second argument? `$result = $obj->GetDeviceStatus('', $out);`. – user692942 Feb 24 '16 at 11:02
  • Tried this as was suggested in another response. It doesn't seem that the DOTNET object returns the value to PHP so the $out variable doesn't get defined and you end up with an undefined variable error. If you define the variable to an empty string or null it returns as an empty string or null. – N8hack Feb 24 '16 at 19:33
  • Where is that other response, another question? – user692942 Feb 24 '16 at 19:50

1 Answers1

1

The second parameter of GetDeviceStatus() method call according to the VBScript should pass a variable that will be populated with the output. However in the PHP example you are just passing the string 'out' which isn't equivalent to what is being done in the VBScript.

Instead try passing a PHP variable to the method and then echoing that variable to screen, like this;

$result = $obj->GetDeviceStatus('', $out);
if ($result)
  echo $out."<br />";

After a bit of digging it appears according to the PHP Reference that you need to pass By Reference variables to COM using the VARIANT data type.

Quote from ferozzahid [at] usa [dot] com on PHP - COM Functions

"To pass a parameter by reference to a COM function, you need to pass VARIANT to it. Common data types like integers and strings will not work for it."

With this in mind maybe this will work;

$out = new VARIANT;
$result = $obj->GetDeviceStatus('', $out);
if ($result)
  echo $out."<br />";
user692942
  • 16,398
  • 7
  • 76
  • 175
  • I tried that too. The results is two "Undefined variable: out in line x" errors. It won't define a php variable for some reason. – N8hack Feb 24 '16 at 17:10
  • @N8hack I'm no PHP expert by any means but did expect that to work. – user692942 Feb 24 '16 at 19:48
  • @Lakymart I hear ya. Thanks for the response though. I opened up the COM object in VS and browsed the methods and VS shows the function as follows. `Public Function GetDeviceStatus(sDevice As String, ByRef sStatus As String) As Boolean` which after looking at some other examples all I've found is someone who suggested PHP DOTNET class doesn't support ByRef variables. But that doesn't make any sense so I'm still looking for suggestions. – N8hack Feb 24 '16 at 23:09
  • @N8hack It's definitely expecting it `ByRef` just looking at the VBScript example. Which is why I suggested what I did, but if it doesn't work then perhaps `ByRef` doesn't work in PHP through COM? – user692942 Feb 24 '16 at 23:20
  • 1
    @N8hack Have updated the answer, hopefully this will help. – user692942 Feb 25 '16 at 09:40
  • You are a genius. I totally missed that one. Spent 2 days looking for it too. Only one comment on this that hung me up for a while. Look at your method in the COM object and don't name your variable the same as the COM objects variable definition... That didn't work. For example: `Public Function GetDeviceStatus(sDevice As String, ByRef out As String) As Boolean` dont do : `$out= new VARIANT; $result = $obj->GetDeviceStatus('', $out); if ($result) echo $out."
    ";` as at least for me, the var $out just kept getting set to an empty string. Kind of weird. Thanks again @Lankymart
    – N8hack Feb 25 '16 at 19:41
  • @Lankymart please help me with this one when you have time http://stackoverflow.com/questions/42189245/how-to-pass-an-array-of-bytes-reference-to-a-com-object-method – Joseph Feb 13 '17 at 22:55