常见扩展问题解答

为了帮助您学习 PHP 的基础知识,我们刚刚完成的教程介绍了如何构建一个非常简单的练习扩展。以下各节提供的信息将回答常见问题,并尽量减少与以下方面有关的问题:

  • 链接外部库。

  • 命名约定。

  • PHP 资源

连接外部库

通常情况下,创建 PHP 扩展是为了提供与某些第三方 C 库的绑定。在这种情况下,PHP 扩展必须与该库链接。这是通过扩展配置文件 "config.m4"(或 Windows 下的 "config.w32")来实现的。例如,下面的 "config,m4 "将用于实现与 libzstd 绑定的 zstd 扩展:

PHP_ARG_WITH([zstd],
    [for zstd support],
    [AS_HELP_STRING([--with-zstd],
        [Include zstd support])])

if test "$PHP_ZSTD" != "no"; then
    PKG_CHECK_MODULES([LIBZSTD], [libzstd])
    PHP_EVAL_INCLINE($LIBZSTD_CFLAGS)
    PHP_EVAL_LIBLINE($LIBZSTD_LIBS, ZSTD_SHARED_LIBADD)

    PHP_SUBST(ZSTD_SHARED_LIBADD)

    AC_DEFINE(HAVE_ZSTD, 1, [ Have zstd support ])

    PHP_NEW_EXTENSION(zstd, zstd.c, $ext_shared)

fi

当扩展使用外部库时,我们使用 --with-<feature> 选项而不是 --enabel-<feature>,因此使用 PHP_ARG_WITH() 宏而不是 PHP_ARG_ENABLE()。此外,我们还添加了一些特殊宏,以通过 pkg-config 查找库和包含路径,并在最终的 Makefile 中添加特殊规则。

命名约定

开始编写新扩展时,请尽量使用统一的命名规范。几乎没有其他选择:

  • 无前缀(scale)。

  • 名称前缀带下划线(test_scale)。

  • 名称前缀和大小写混合(TestScale)。

  • 命名空间 (Test\scale) - 如果使用宏 (ZEND_NS_NAME、ZEND_NS_FENTRY、ZEND_NS_FE、INIT_NS_CLASS_ENTRY) 构建命名空间名称,则会出现特殊变体。

  • 使用静态类作为命名空间(Test::scale)- 可以创建一个类,并将所有函数声明为该类的静态方法。

PHP 资源

PHP 还有一种类型:资源(resource)。历史上,当需要在 PHP zval 中保存一些 C 数据(如文件描述符)时,就会用到这种类型。它表示为 zend_refcounted 结构的子结构,并带有指向某些 C 数据结构的指针。

PHP 资源仍然用于 PHP 扩展。不过,不建议在新的扩展中使用它们,因为可以通过在 PHP 内部对象中嵌入 C 数据来实现更智能、更高效的解决方案。