从扩展中返回"本机"PHP对象

Ala*_*orm 15 php c php-extension php-internals

我正在尝试为个人项目创建PHP扩展.除了上面文章中的内容之外,我对zend_engine一无所知,而且我的C技能已经过时了10年,并且只是学术性的.所有这些都是说"如果我好像在问一个愚蠢的问题,我可能就是".

是否可以在我自己的扩展中调用其他PHP扩展中的函数,或者每个PHP扩展都被认为是孤岛,而没有深入了解系统的其他部分?如果这是可能的,这是常见做法还是坏主意™?

也就是说,我知道我可以用这样的东西返回一个字符串.

PHP_FUNCTION(hello_world)
{
    char *str;
    str = estrdup("Hello World");
    RETURN_STRING(str, 0);
}
Run Code Online (Sandbox Code Playgroud)

我希望能够返回一个SimpleXML元素或一个DomDocument元素.谷歌搜索已经证明是困难的,因为扩展开发并没有那么多,并且有很多标准的PHP使用.

Art*_*cto 4

是的,扩展实际上可以依赖于其他扩展。他们能:

  • 使用其他扩展全局注册的资源,例如类类型或 PHP 函数(也就是说,它们的访问权限并不比用户态脚本少,用户态脚本显然可以使用这些资源)。参见zend_call_functionzend_lookup_class_ex
  • 使用文件中声明的任何导出符号和结构php_extensionname.h(这些标头是唯一被视为将本机 API 导出到其他扩展的标头)。但是,某些扩展实际上可能不会导出这些头文件中声明的某些符号,您必须查找用PHPAPI. 请注意,某些扩展无法停用,您可以依赖它们的存在(例如,从 5.3/5.4 开始,标准、SPL、反射、日期、PCRE、EREG)。
  • 如果您的扩展和目标扩展都是静态构建的,那么您当然可以对可以使用的符号有更多的自由度,但使用非导出的符号并不是一个好的做法。

我希望能够返回 SimpleXML 元素或 DomDocument 元素。

如果您需要显式实例化 aSimpleXMLElement或 a DOMDocument,可以使用 来实现object_init_ex。扩展通常会导出zend_class_entry *必须传递该宏的 ,但如果没有,您始终可以使用zend_lookup_class_ex. 这不会调用构造函数,因此如果需要,您仍然必须手动执行此操作。

某些扩展可能会提供本机接口来实例化和初始化对象,但通常扩展不准备让其他扩展实例化其类型。

当然,您也可以像脚本一样调用返回任何这些类型的 PHP 函数和方法。您将得到一个zval *可以从您的函数返回的值。

至于如何声明依赖关系,扩展描述符中有一个条目。这将确保您的扩展在您声明依赖的扩展之后加载。有关在编译时声明依赖关系的信息,请参阅PHP_ADD_EXTENSION_DEP