正如LazyOne所建议的那样,手动方法可以像编写存根声明并将 php 文件转储到项目树或搜索路径中的某处(如适当的存根目录)一样简单:
<?php
/** allows observing the server lock/object counts and unloadability state of a COM module that uses the
* Zrbj.COM.ComServerLocking infrastructure
* @property-read int $Revision revision of the observer module implementation
* @property-read string $ServerDLL executable which houses the code for this observer object
*/
interface ISrvDllObserver
{
/** server lock count information (ICounterInfo) for this object's own server module */
public function GetCountsForOwnModule (): ICounterInfo;
/** server lock count information (ICounterInfo) for a loaded COM module that uses Zrbj.COM.ComServerLocking.
* @param string $module_name basename without file extension is sufficient unless there are multiple loaded
* modules with the same basename; use path and/or file extension to disambiguate
*/
public function GetCountsForLoadedModule (string $module_name): ICounterInfo;
}
从那时起,IntelliSense 完美运行。
手动过程可能会产生完美的结果,但非常费力。我记得 FoxPro 和 Visual Studio 早期版本附带的用于处理类型库的可编写脚本的对象tlbinf32.dll
(+ tlbinf32.chm
)。开始的 ProgID 是TLI.TLIApplication
.
我可以在 microsoft.com 上找到的对这个工具的唯一引用是这篇旧文章:
Visual Basic:使用 TypeLib 信息对象库检查 COM 组件
该工具仍随 Visual Studio 提供,但现在已被调用vstlbinf.dll
且不再记录。vstlbinf.dll
仍然将旧的tlbinf32.chm
作为其帮助文件,但不再提供。旧文档对于理解对象模型仍然很有用,即使它引用了二十多年前的版本。(注意:可能需要手动注册 DLL。)
于是我带着Delphi开始驯服TLI.TLIApplication
。事实证明,它并不比直接使用等容易得多ITypeLib
,ITypeInfo
但优点是TLI.TLIApplication
可以从任何脚本语言中使用,包括 PHP 本身。
下面是可以从 COM 类型库中提取以用于 PHP 存根的信息示例:
<?php
// 'k:\VS2019\Community\Common7\IDE\vstlbinf.dll' (2021-04-21 10:05:35)
// processed 2021-05-02 22:39:10 by Zrbj.COM.PhpStubs.pas rev. 2021-05-02
//
// Library: TLI
// Version: 1.0
// LIBID : {8B217740-717D-11CE-AB5B-D41203C10000}
// Comment: TypeLib Information
// 32 interface(s) and 3 coclass(es)
//
// coclasses:
// * {8B217752-717D-11CE-AB5B-D41203C10000} -> _SearchHelper (ProgID TLI.SearchHelper)
// 'Helper object for GetMembersWithSubString and multiple TypeLibs'
// * {8B217746-717D-11CE-AB5B-D41203C10000} -> _TypeLibInfo (ProgID TLI.TypeLibInfo)
// 'TypeLib information'
// * {8B21775E-717D-11CE-AB5B-D41203C10000} -> _TLIApplication (ProgID TLI.TLIApplication)
// 'TLIApplication object'
/// {8B21774B-717D-11CE-AB5B-D41203C10000} dual nonextensible dispatchable
/** VarType information for parameters and return types
* @property-read TypeInfo $TypeInfo Type information for VT_PTR VarType
* @property-read int $TypeInfoNumber TypeInfo number for 0 VarType (Cheaper than TypeInfo property)
* @property-read variant $TypedVariant Get a variant with this VarType
* @property-read bool $IsExternalType Is TypeInfo external to this library
* @property-read TypeLibInfo $TypeLibInfoExternal External typelib. Same as TypeInfo.Parent.
* @property-read int $PointerLevel Dereferencing level of type
* @property-read int $VarType VarType of Parameter
* @property-read int $ElementPointerLevel Dereferencing level for type of an array element
*/
interface VarTypeInfo
{
/** Get bounds for VT_VECTOR array. LBound in column 1, UBound in column 2. */
public function ArrayBounds (int $Bounds): int;
}
/// {8B217749-717D-11CE-AB5B-D41203C10000} dual nonextensible dispatchable
/** Parameter Information
* @property-read string $Name Name of the object
* @property-read bool $Optional Optional Parameter
* @property-read VarTypeInfo $VarTypeInfo VarTypeInfo object for this parameter
* @property-read bool $Default Default Parameter
* @property-read variant $DefaultValue Default value
* @property-read bool $HasCustomData Check if custom data is available
* @property-read CustomDataCollection $CustomDataCollection Custom data GUIDs and Values
* @property-read int $Flags Parameter Flags
*/
interface ParameterInfo
{
}
...
参数注释明显不存在,因为在 Microsoft IDL 或类型库中没有这样的东西。但总的来说,将类型库处理成 PHP 存根的结果似乎相当令人满意,而且它确实使在 PHP 中处理 COM 对象变得容易得多。