php - 自定义 PHP 扩展

标签 php c compiler-errors extension-methods

我需要为 PHP 创建自定义扩展。一切都很顺利,直到我想将编译的扩展加载到 PHP 中。我收到此错误消息(通过使用 php -m):“警告:PHP 启动:第 0 行未知中的无效库(可能不是 PHP 库)'first.so'”

操作系统:

OS X 10.8.5

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

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

我正在通过目录中的 .ini 文件注册扩展名以获取其他 .ini 文件

extension=first.so

我没有使用其他附加工具。当我尝试以这种方式直接从 PHP 发行版源(具体而言,posix)中包含的扩展来编译某些扩展时,一切正常,并且扩展已正确加载。

有人看到我下面的源代码有什么错误吗?谢谢你的帮助。

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

第一个.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

最佳答案

#ifdef COMPILE_DL_POSIX
ZEND_GET_MODULE(first)
#endif

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

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

静态意味着您的扩展是作为 PHP 的一部分构建的,并且直接构建在 php 二进制文件中。 (将其放入 php-src/ext/,运行 buildconf,配置)这通过配置创建一个文件 main/internal_functions.c 来工作,其中包含所有 php_foo.h 文件和创建一个 module_entry 数组,该数组在 PHP 启动时进行处理。

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

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

引用文献:

关于php - 自定义 PHP 扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25866778/

相关文章:

c - c 中的位操作给出了意想不到的结果

java - Try-With-Resources示例,编译失败。代码有什么问题

PHP ftp_nlist 不工作

php - 如何设置全局变量以供 Laravel 和 Vuejs 访问?

PHP MySQL 计数 IF Google 图表并从列/行中提取数据

c - ARM设备树文件中,三个中断值是什么意思

c - epoll_wait之后如何更新epoll事件?

c++ - 为什么 "possible lack of precision"不是编译器错误?

c++ - LNK2038 : mismatch detected for 'RuntimeLibrary' : value 'MT_StaticRelease' doesn't match value 'MD_DynamicRelease' in main.obj

php - 从php文件夹中删除3天前的文件