从扩展返回“本机”PHP 对象

Posted

技术标签:

【中文标题】从扩展返回“本机”PHP 对象【英文标题】:Returning "Native" PHP Objects from an Extension 【发布时间】:2012-04-04 03:57:24 【问题描述】:

我正在为个人项目创建a php extension。除了上面文章中的链接之外,我对 zend_engine 一无所知,而且我的 C 技能已经过时了 10 年,而且只是学术性的。所有这一切都是在说“如果看起来我在问一个愚蠢的问题,我可能是”。

是否可以在我自己的扩展中调用来自其他 PHP 扩展的函数,或者每个 PHP 扩展都被视为一个孤岛,对系统的其他部分没有洞察力?如果这是可能的,这是常见的做法,还是 Bad Idea™?

也就是说,我知道我可以返回这样的字符串。

PHP_FUNCTION(hello_world)

    char *str;
    str = estrdup("Hello World");
    RETURN_STRING(str, 0);

我希望能够返回一个 SimpleXML 元素或一个 DomDocument 元素。谷歌搜索已被证明是困难的,因为没有大量关于扩展开发的内容,而且有大量关于标准 PHP 使用的内容。

【问题讨论】:

好问题;如果 Zend 文档没有对此有所说明,我会感到惊讶。 @KerrekSB 这是一个不错的 RTFM :)。如果您(或任何人)知道一份 zend 文档,该文档对此有很好的概述,并且不假设有 5 年以上的扩展黑客经验(甚至没有),我很乐意看到它。 【参考方案1】:

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

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

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

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

一些扩展可能会提供一个本地接口来实例化和初始化一个对象,但一般来说扩展并不准备让其他扩展实例化它们的类型。

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

关于如何声明依赖,扩展描述符有一个entry。这将确保您的扩展在您声明依赖的扩展之后加载。要在编译时声明依赖项,请参阅PHP_ADD_EXTENSION_DEP

【讨论】:

【参考方案2】:

我对php扩展编写不太了解,但是如果你还没有读过,你可以试试这个 http://devzone.zend.com/446/extension-writing-part-iii-resources/

使用这个你可以将任何类型的资源传递给 php 扩展

【讨论】:

【参考方案3】:

如果您正在编写扩展程序,那么Extending and Embedding PHP(又名“Sara's Book”)是必不可少的阅读材料。现在有点过时了,但您可以在线或离线找到最好的资源。

【讨论】:

以上是关于从扩展返回“本机”PHP 对象的主要内容,如果未能解决你的问题,请参考以下文章

使用本机查询从 Spring Data 返回自定义对象

React本机推送通知,GCM服务器返回401

JVM函数调用与从本机方法返回的性能?

当我尝试从 PHP 对象/数组返回值时,出现 500 错误。但是可以返回所有对象

Mysql 查询在 Codeigniter 中返回空结果,但在本机 PHP 中工作正常

从 php 返回一个可迭代对象到 Ajax