I'm having troubles calling any method inside a COM class in php. In order to find all methods inside that class, I used:
$com = new COM('Some.Class.Name');
com_print_typeinfo($com);
Comes out this class contains some 100 different methods. But when calling any of them:
$com->SomeMethod();
,this error pops up:
Fatal error: Call to undefined method com::SomeMethod() in C:\xampp\htdocs\www\test.php on line 22
This doesn't happen when I use other COM objects, like 'InternetExplorer.Application' class. Also, I know this COM object works as expected with other programming languages like Delphi.
I'm using PHP 5.5.19, on 64-bit Windows Vista, and XAMPP, with 32-bit PHP architecture.
I would appreciate any lead on what may be going on or some possible workaround to this situation.
EDIT: The COM server application is made with Delphi.
This might be another clue: When I use the code
$com = new COM('Some.Class.Name');
foreach ($com as $obj) {
echo $obj->Name . "<br />";
}
I get:
Fatal error: Uncaught exception 'Exception' with message 'Object of type com did not create an Iterator'
I guess this indicates there could be a problem with the application interface itself, but I don't know what that problem might be. I work in PHP, so the insides of COM objects are a total blur to me. But I would very much appreciate any clue on the concrete steps in order to fix this situation.
EDIT2: This is the in short code from the Srv_TLB.pas file.
unit Srv_TLB;
{$TYPEDADDRESS OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface
uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;
const
// TypeLibrary Major and minor versions
SrvMajorVersion = 1;
SrvMinorVersion = 0;
LIBID_Srv: TGUID = '{xxxxx-xxx-xxx-xx...}';
IID_ISrvObject: TGUID = '{yyyyy-yyy-yyy-yy..}';
CLASS_SrvObject: TGUID = '{zzzzz-zzz-zzz-z...}';
type
// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
ISrvObject = interface;
ISrvObjectDisp = dispinterface;
// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
SrvObject = ISrvObject;
ISrvObject = interface(IDispatch)
['{yyyyy-yyy-yyy-yy..}']
function FuncName1(const param1: WideString; const param2: WideString): Integer; safecall;
function FuncName2: OleVariant; safecall;
function FuncName3(const param: WideString): Integer; safecall;
end;
// *********************************************************************//
// DispIntf: ISrvObjectDisp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {yyyyy-yyy-yyy-yy..}
// *********************************************************************//
ISrvObjectDisp = dispinterface
['{yyyyy-yyy-yyy-yy..}']
function FuncName1(const param1: WideString; const param2: WideString): Integer; dispid 3;
function FuncName2: OleVariant; dispid 4;
function FuncName3(const param: WideString): Integer; dispid 5;
end;
CoSrvObject = class
class function Create: ISrvObject;
class function CreateRemote(const MachineName: string): ISrvObject;
end;
implementation
uses ComObj;
class function CoSrvObject.Create: ISrvObject;
begin
Result := CreateComObject(CLASS_SrvObject) as ISrvObject;
end;
class function CoSrvObject.CreateRemote(const MachineName: string): ISrvObject;
begin
Result := CreateRemoteComObject(MachineName, CLASS_SrvObject) as ISrvObject;
end;
end.
And the problem is (from the PHP side of things):
I can initialize the COM object with $com = new COM('The.Class.Name');
or with $com = new COM('{GUID}');
, and I get the type info with com_print_typeinfo($com);
, so I can see the object should have the methods FuncName1()
, FuncName2()
and FuncName3()
, but when I try to call any of them with $com->FuncName1(param1, param2);
, what it returns is this error:
Fatal error: Call to undefined method com::SomeMethod() in C:\xampp\htdocs\www\test.php on line 22
undefined means that the variable value has not been defined; it is not known what the value is. null means that the variable value is defined and set to null (has no value).
In a JavaScript program, the correct way to check if an object property is undefined is to use the typeof operator. If the value is not defined, typeof returns the 'undefined' string.
The undefined property indicates that a variable has not been assigned a value, or not declared at all.
A variable that has not been assigned a value is of type undefined . A method or statement also returns undefined if the variable that is being evaluated does not have an assigned value. A function returns undefined if a value was not returned .
Many things can go wrong with COM but I will try to help as best I can. I know that you use terms to describe the issue, like calling $com->SomeMethod(), but you need to be more specific in this case.
COM exposes its classes and functionality through two basic interfaces IUnknown and IDispatch.
It also has a DLL structure of C type, to expose functions (Not methods or classes) to the "out side" world.
Languages that can link directly to a DLL's, by reading the export table (like Delphi), make their calls directly on the interface exposed by the COM (Using IUnknown interface).
Script languages (like javascript, PHP python etc.) cannot call directly on the interface. Instead they use IDispatch interface.
This interface serve as a proxy that expose all COM functionality through simple text.
The IDispatch interface define standard methods for:
1. querying a COM on the interfaces it exposes
2. The methods' names of an object.
3. The parameters for each method.
In your post you display that IDispatch exposed three methods:
1. FuncName1
2. FuncName2
3. FuncName3
Therefore you cannot call SomeMethod on ISrvObject because it is not exposed via the IDispatch interface.
NOTE: COM uses WideString (UTF-16) text when exposing its interface. Take that into account once you do make a call on the interface methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With