自定义PHP扩展

时间:2014-09-16 10:48:37

标签: php c compiler-errors extension-methods

我需要为PHP创建自定义扩展。在我想将编译的扩展加载到PHP之前,所有事情都进展顺利。比我收到此错误消息(通过使用php -m):"警告:PHP启动:无效的库(可能不是PHP库)' first.so'在第0行"

中的未知

OS:

OS X 10.8.5

这是我的编译过程,完全没有错误:

$ phpize54
$ sudo ./configure --with-php-config=/opt/local/bin/php-config54
$ sudo make install

我在dir中通过.ini文件注册扩展名以获取其他.ini文件

extension=first.so

我没有使用其他工具。 Whan我试图通过这种方式从PHP发布源(posix,具体)中包含的扩展名来扩展一些扩展,一切正常,扩展被正确加载。

有人在下面的源代码中看到任何错误吗?感谢U for hellp。

的config.m4

PHP_ARG_ENABLE(first,whether to enable FIRST functions,
[  --disable-first         Disable FIRST functions], yes)

if test "$PHP_FIRST" = "yes"; then
  AC_DEFINE(HAVE_FIRST, 1, [whether to include FIRST functions])
  PHP_NEW_EXTENSION(first, first.c, $ext_shared)
fi

first.c

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "ext/standard/info.h"

extern zend_module_entry first_module_entry;
#define first_module_ptr &first_module_entry
#define phpext_first_ptr first_module_ptr


static PHP_MINFO_FUNCTION(first)
{
    php_info_print_table_start();
    php_info_print_table_row(2, "Revision", "$Id: 01 $");
    php_info_print_table_end();
}

static PHP_MINIT_FUNCTION(first)
{
    return SUCCESS;
}

PHP_FUNCTION(hallo)
{
    RETURN_STRING("FIRST extension function works\n", 1);
}

ZEND_BEGIN_ARG_INFO_EX(arginfo_hallo, 0, 0, 0)
ZEND_END_ARG_INFO()

const zend_function_entry first_functions[] =
{
    PHP_FE(hallo, arginfo_hallo)
    PHP_FE_END
};

zend_module_entry first_module_entry = {
    STANDARD_MODULE_HEADER,
    "first", 
    first_functions, 
    PHP_MINIT(first),
    NULL,
    NULL,
    NULL, 
    PHP_MINFO(first),
    NO_VERSION_YET,
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_POSIX
ZEND_GET_MODULE(first)
#endif

1 个答案:

答案 0 :(得分:0)

#ifdef COMPILE_DL_POSIX
ZEND_GET_MODULE(first)
#endif

这看起来不错。在config.m4中,您声称您的扩展名首先被调用(PHP_NEW_EXTENSION(first, ...),但是您正在检查名为posix的扩展是否已构建为共享。

背景:PHP可以通过两种方式加载扩展(意味着PHP模块与Zend Extensions混淆,比如xdebug或opcache - 它们是不同的topi)。静态编译成PHP或共享。

静态意味着您的扩展是作为PHP的一部分构建的,并且内置在php二进制文件中。 (把它放在php-src / ext /中,运行buildconf,configure)这可以通过configure创建一个文件main/internal_functions.c,其中包含所有php_foo.h个文件,并创建一个module_entry数组,并对其进行处理在PHP开始。

如果扩展是构建共享的(在php-src中使用--with-foo=sharedphpize)并通过php.ini加载它,PHP将使用{{1}查找函数get_module() }和dlopen()系统apis(或Windows上的dlsym())将返回模块结构。为了不在宏LoadDll执行此操作的情况下始终编写该函数get_module()。但ZEND_GET_MODULE是一个通用名称,并且在静态构建期间必须防止每个扩展创建它,因为这会导致冲突在同一个二进制文件中多次具有相同的功能,这就是为什么构建系统创建COMPILED_DL_FOO定义哪些可以用作警卫。

因此,在您的情况下,PHP打开库,查找get_module但无法找到它,耸耸肩并报告错误。

参考文献: