php的扩展写法总结

PHP的扩展写法总结

在 PHP 中,扩展是一种 C 语言编写的动态链接库(.so文件或.dll文件),它能够提供一些 PHP 无法直接完成的功能,比如支持某些第三方库、提高 PHP 执行效率等。

下面将介绍如何编写 PHP 扩展,包括相关的代码示例和一些常用的扩展 API。

前置条件

在进行 PHP 扩展的编写之前,需要准备好以下工具:

扩展写法

扩展的基本结构

扩展包含两个主要的文件,一个是头文件(.h文件),另一个是源文件(.c文件)。源文件中需要包含头文件,并且实现扩展的初始化函数、定义扩展的函数等。

下面是一个基本的扩展结构:

+-- my_extension.h // 头文件
+-- my_extension.c // 源文件

编写头文件

在头文件中需要定义一些宏和函数声明,可以按照以下模板进行编写:

#ifndef MY_EXTENSION_H
#define MY_EXTENSION_H

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

#include "php.h"

extern zend_module_entry my_extension_module_entry;
#define phpext_my_extension_ptr &my_extension_module_entry

#endif /* MY_EXTENSION_H */

其中,zend_module_entry 结构体是 PHP 定义的用于描述模块的结构体,每个扩展都需要定义一个这样的结构体。php.h 是 PHP 预编译头文件,用于包含一些 PHP 扩展需要用到的公共头文件。

编写源文件

在源文件中需要包含头文件,并且实现扩展的初始化函数、定义扩展的函数。以下是一个简单的示例代码:

#include "php.h"
#include "my_extension.h"

static zend_function_entry my_extension_functions[] = {
    PHP_FE(my_extension_hello, NULL)
    PHP_FE_END
};

static PHP_MINIT_FUNCTION(my_extension)
{
    return SUCCESS;
}

static PHP_MSHUTDOWN_FUNCTION(my_extension)
{
    return SUCCESS;
}

static PHP_RINIT_FUNCTION(my_extension)
{
    return SUCCESS;
}

static PHP_RSHUTDOWN_FUNCTION(my_extension)
{
    return SUCCESS;
}

zend_module_entry my_extension_module_entry = {
    STANDARD_MODULE_HEADER,
    "my_extension",
    my_extension_functions,
    PHP_MINIT(my_extension),
    PHP_MSHUTDOWN(my_extension),
    PHP_RINIT(my_extension),
    PHP_RSHUTDOWN(my_extension),
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_MY_EXTENSION
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
#endif
ZEND_GET_MODULE(my_extension)
#endif

在上面的示例代码中,定义了一个名为 my_extension_hello 的函数,这个函数没有参数,返回 "Hello World!"。

函数定义的格式为:PHP_FUNCTION(function_name),其中 function_name 是函数名。PHP_FE(function_name, arg_info) 宏可以将函数导出为扩展的 API。

编译扩展

在编写完头文件和源文件之后,可以使用以下命令来编译扩展:

phpize
./configure --enable-my_extension
make && make install

上述命令实际上执行了以下操作:

  • phpize 用于生成构建扩展所需的文件,例如 Makefile、configure 等。
  • ./configure --enable-my_extension 用于生成 Makefile、config.h 等文件。
  • make && make install 用于编译并安装扩展。

使用扩展

在 PHP 中,可以使用 extension_loaded 函数来检查一个扩展是否已加载,可以使用 get_extension_funcs 函数来获取扩展的函数列表。

if (extension_loaded('my_extension')) {
    $funcs = get_extension_funcs('my_extension');
    var_dump($funcs);
}

示例

这里举一个引用了第三方库的扩展编写的例子。

在编写扩展前,需要先安装 libcurl 库。在 Ubuntu 系统上,可以使用以下命令来安装:

sudo apt-get install libcurl4-openssl-dev

以下是编写 curl 扩展的代码示例:

my_curl.h

#ifndef MY_CURL_H
#define MY_CURL_H

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

#include "php.h"
#include <curl/curl.h>

extern zend_module_entry my_curl_module_entry;
#define phpext_my_curl_ptr &my_curl_module_entry

PHP_FUNCTION(my_curl);
PHP_MINIT_FUNCTION(my_curl);

#endif /* MY_CURL_H */

my_curl.c

#include "my_curl.h"

static zend_function_entry my_curl_functions[] = {
    PHP_FE(my_curl, NULL)
    PHP_FE_END
};

static PHP_MINIT_FUNCTION(my_curl)
{
    CURLcode err;

    err = curl_global_init(CURL_GLOBAL_ALL);
    if (err != CURLE_OK) {
        php_error_docref(NULL, E_ERROR, "%s", curl_easy_strerror(err));
        return FAILURE;
    }

    return SUCCESS;
}

static PHP_MSHUTDOWN_FUNCTION(my_curl)
{
    curl_global_cleanup();
    return SUCCESS;
}

static PHP_FUNCTION(my_curl)
{
    CURLcode err;
    CURL *curl;

    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com");
        err = curl_easy_perform(curl);
        if (err != CURLE_OK) {
            php_error_docref(NULL, E_WARNING, "curl_easy_perform() failed: %s\n", curl_easy_strerror(err));
        }
        curl_easy_cleanup(curl);
    } else {
        php_error_docref(NULL, E_WARNING, "curl_easy_init() failed\n");
    }
}

zend_module_entry my_curl_module_entry = {
    STANDARD_MODULE_HEADER,
    "my_curl",
    my_curl_functions,
    PHP_MINIT(my_curl),
    PHP_MSHUTDOWN(my_curl),
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_MY_CURL
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
#endif
ZEND_GET_MODULE(my_curl)
#endif

在上述代码中,使用 curl_global_init 函数初始化 libcurl 库,在 PHP_MINIT_FUNCTION 中实现。

my_curl 函数中,使用 curl_easy_init 函数创建一个 CURL 句柄,然后设置 CURLOPT_URL 选项,并使用 curl_easy_perform 函数执行请求。

常用扩展 API

这里列出一些常用的扩展 API:

  • PHP_FUNCTION():定义一个扩展函数(Function)。
  • PHP_MINIT_FUNCTION():定义模块初始化函数。
  • PHP_MSHUTDOWN_FUNCTION():定义模块销毁函数。
  • PHP_RINIT_FUNCTION():定义请求初始化函数。
  • PHP_RSHUTDOWN_FUNCTION():定义请求销毁函数。
  • ZEND_BEGIN_MODULE_GLOBALS():定义模块的全局变量。
  • ZEND_DECLARE_MODULE_GLOBALS():声明模块的全局变量。
  • ZEND_GET_MODULE_GLOBALS():获取模块的全局变量。
  • ZEND_MODULE_STARTUP_FUNCTION():定义模块启动函数。
  • ZEND_MODULE_SHUTDOWN_FUNCTION():定义模块停止函数。
  • zend_register_module_ex():注册一个扩展模块。
  • zend_declare_property():在 PHP 类实例中声明属性。
  • zend_parse_parameters():解析 PHP 函数的参数。
  • retutn_value_*():返回 PHP 扩展的执行结果。
  • zend_stream_declare_property_null():设置 PHP 对象的属性值。

总结

通过以上介绍,读者应该能够了解如何编写自己的 PHP 扩展。PHP 扩展的编写是 C 语言开发者应该必备的技能之一,可以借助扩展来实现 PHP 无法直接完成的功能,提高程序性能和安全性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:php的扩展写法总结 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 详述php渗透全过程(组图)

    以下是详述PHP渗透全过程的完整攻略。 1.概述 PHP渗透是现代网络安全领域里一项非常重要的技能和工作,其主要目的是找出PHP应用程序中的安全漏洞并尝试利用它们获得系统访问权限或敏感数据。在进行PHP渗透前,我们需要了解以下知识:- PHP基础语法和操作方法;- 常见的Web漏洞及其检测方法和利用工具;- 经验丰富的安全漏洞挖掘技巧。 2.渗透全过程 2.…

    PHP 2023年5月26日
    00
  • 详解EventDispatcher事件分发组件

    详解EventDispatcher事件分发组件 EventDispatcher是一个常用的事件分发组件,可以在多处地方监听和触发自定义事件。在使用过程中,需要先引入该组件,并进行初始化。 引入EventDispatcher EventDispatcher是Symfony框架中的一个组件,我们可以通过composer进行安装引入: composer requi…

    PHP 2023年5月26日
    00
  • PHP几个实用自定义函数小结

    让我来详细地讲解一下“PHP几个实用自定义函数小结”这个主题的攻略。 什么是自定义函数 自定义函数是指在 PHP 代码中定义的、可以重复使用的代码块。它们通常用来执行特定的任务或返回某个值,可以让我们的代码更加简洁、易于维护。 自定义函数的语法 自定义函数的语法如下所示: function function_name(parameter1, paramete…

    PHP 2023年5月27日
    00
  • 百度工程师讲PHP函数的实现原理及性能分析(二)

    《百度工程师讲PHP函数的实现原理及性能分析(二)》是一篇介绍PHP函数实现原理和性能分析的技术文章,旨在帮助PHP开发者深入理解函数的工作原理,提高PHP程序的性能。下面是该文章完整攻略。 一、文章概述 本文主要分析PHP函数的实现原理和性能分析,介绍了函数调用栈、函数的参数传递方式、函数的返回值、函数的变量作用域等基础知识。然后详细讲解了PHP函数实现的…

    PHP 2023年5月27日
    00
  • 解析PHP无限级分类方法及代码

    解析PHP无限级分类方法及代码 在网站开发中,分类列表是常见的需要处理的数据类型,其中涉及到无限级分类问题。在PHP语言中,常见的有两种方式实现无限级分类,分别为递归和非递归方法。 递归实现无限级分类 递归实现是常见的无限级分类方法,主要思路是从顶级分类开始,逐级遍历下一级分类,直到最底层的子分类全部遍历完。 下面是一个递归实现无限级分类的PHP代码示例: …

    PHP 2023年5月26日
    00
  • PHP让数组中有相同值的组成新的数组实例

    要实现将数组中有相同值的元素组成新的数组实例,可以使用PHP的array_unique()和array_count_values()两个函数,它们的调用过程如下: // 定义数组 $nums = array(1, 2, 3, 2, 4, 4, 3, 5); // 去重 $unique_nums = array_unique($nums); // 统计元素出现…

    PHP 2023年5月26日
    00
  • Yii使用queue实现队列流程讲解

    以下是关于“Yii使用queue实现队列流程讲解”的完整使用攻略: 基础知识 在了解Yii使用queue实现队列之前,需要掌握一些基础知识,包括队列的基本概念、Yii中的queue组件等。以下是一些常见的基础知识: 队列的基本概念,包括队列的定义、队列的特点、队列的应用等。 Yii中的queue组件,包括queue组件的定义、queue组件的使用等。 使用攻…

    PHP 2023年5月12日
    00
  • php下批量挂马和批量清马代码

    为了防范网络黑客的攻击,网站管理员需要了解网站被挂马后的处理方式。一般在PHP语言下,网站被挂马的原因是服务端的文件有漏洞,或者被管理员账户密码泄露,网站的代码造成的后果就是在用户请求页面时,程序会在页面HTML代码中嵌入一个恶意脚本或链接,使得用户在访问页面时会自动执行恶意脚本或链接,从而感染用户的电脑或手机。下面我们将为您介绍如何通过PHP代码来批量挂马…

    PHP 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部