2012-03-19 39 views
15

我正在为个人项目创建a PHP extension。除了什么是上述文章中链接的人,我没有zend_engine的知识,我的C技能在10年以后的日期,并且是只有永远的学术。所有这些都是说“如果我好像在问一个愚蠢的问题,我可能就是”。从分机返回“原生”PHP对象

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

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

PHP_FUNCTION(hello_world) 
{ 
    char *str; 
    str = estrdup("Hello World"); 
    RETURN_STRING(str, 0); 
} 

我希望能够返回,例如,一个SimpleXML元素或一个DomDocument元素。谷歌搜索已被证明是困难的,因为关于扩展开发没有太多的时间,并且标准的PHP使用量有很多。

+0

不错的问题;如果Zend文档没有说明这一点,我会很惊讶。 – 2012-03-19 16:37:00

+1

@KerrekSB这是一个很好的RTFM :)。如果你(或任何人)知道一个很好的概述这个zend文档,并且不承担5年以上的扩展黑客体验(甚至是一个),我很乐意看到它。 – 2012-03-19 16:54:38

回答

4

是,扩展其实可以依靠别人。他们可以:其它扩展全球注册

  • 使用的资源,如类类型或PHP函数(也就是,他们没有比用户脚本的土地机会少,能明显使用这些资源)。见zend_call_functionzend_lookup_class_ex
  • 使用在文件php_extensionname.h中声明的任何导出的符号和结构(这些头是唯一被认为将本机API导出到其他扩展的头)。然而,一些扩展可能实际上不出口这些头文件中声明一些符号,你必须寻找与PHPAPI声明符号。请注意,某些分机不能被停用,你能依靠他们存在(例如,为5.3/5.4,标准,SPL,反射,日期,PCRE,额日格)。
  • 如果您的扩展和目标扩展都是静态构建的,那么您可以使用更多的符号范围,但使用非导出符号不是一个好习惯。

我希望能够返回,比如说,一个SimpleXML的元素,或者一个DOMDocument元素。

如果你需要显式实例化SimpleXMLElementDOMDocument,你可以用object_init_ex这样做。扩展通常导出必须通过宏观的zend_class_entry *,但如果没有,你可以随时使用zend_lookup_class_ex。这确实调用构造函数,所以你仍然必须手动,如果你需要做的。

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

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

至于如何声明依赖关系,扩展描述符为此具有entry。这将确保您的扩展程序在您声明依赖的扩展程序之后加载。要在编译时声明依赖关系,请参阅PHP_ADD_EXTENSION_DEP

2

如果你正在写扩展名,那么Extending and Embedding PHP(又名“萨拉的书”)是必不可少的阅读材料。现在有点过时了,但是你可以在网上找到或者关闭最好的资源。