首页 > 后端开发 > php教程 > 通过PHP-CPP开始PHP扩展开发

通过PHP-CPP开始PHP扩展开发

Lisa Kudrow
发布: 2025-02-21 09:06:11
原创
412 人浏览过

通过PHP-CPP开始PHP扩展开发

在与PHP的交往中,您可能会考虑自己写PHP扩展。我能想到的有几个原因激发了我这样做:

>

    >扩展PHP功能以进行一些非常特殊的用法(数学,统计,几何等)。
  • 与纯PHP实施相比,
  • 具有更高的性能和效率
  • 利用以前掌握的语言(对我,C)获得的编程获得的迅速性。
  • >
在选择构建PHP扩展的工具方面,我们看到了两种不同的方法:

    使用更多的PRHP语义,例如Zephir。
  • >使用更多的Pro-C/C语义,例如PHP-CPP,将在本文中解决。
  • 对我来说,选择第二种方法的主要驱动器很简单:我开始使用C/C进行编程爱好,因此我仍然更愿意在C/C中编写那些较低级别的模块。 PHP-CPP的官方网站给出了其他一些理由。
>

钥匙要点

PHP-CPP是一个用于开发PHP扩展的库,允许C开发人员编写PHP扩展,而无需直接与Zend API合作的复杂性。它写在C 11中,并提供了有据可查和用户友好的课程的集合。

> PHP-CPP正在迅速发展,建议使用Git克隆存储库以进行最新更新。它支持单线读取的PHP安装,并需要升级到G编译器到4.8.x版或更高版本以兼容。
    >
  • > PHP-CPP提供了一个骨架扩展项目,其中包括一个main.cpp文件,用于编译扩展名的制造文件以及用于扩展加载的.INI文件。可以定制骨架项目以适合个人需求,并使用“ make && sudo make install”命令进行编译和安装。
  • PHP-CPP支持四种类型的函数签名,可以从PHP调用,并允许参数以数组形式通过值传递。它还允许功能导出/注册,功能参数类型的规范以及以对象为导向的扩展的创建。
  • >安装和配置
  • PHP-CPP正在迅速发展。在本文撰写本文时,它以0.9.1版本(大约2天发布)。根据其文档:“这是一个为即将推出的V1.0版本做准备的功能冻结版本”,因此我们有信心很快就会看到其1.0主要版本。 因此,至少在此期间,建议使用git克隆存储库,并通过git拉动获得最新更新。
  • 注意:安装上的PHP-CPP文档指出,暂时,它“仅支持单线读取PHP安装”,因为“内部Zend Engine使用了非常奇怪的系统来确保线程安全性”。未来的发行版可能支持多线Readed PHP安装,但让我们暂时记住这一点,并遵守其当前限制。幸运的是,大多数PHP安装都应该是“单线读取的PHP安装”。

    >

    > php-cpp写在C 11中。因此,我的Ubuntu 12.04 LTS中安装的G较旧版本不支持它。我们需要将G编译器升级到上述4.8.x版本。有一篇文章详细介绍了进行升级的步骤。请按照列出的说明进行操作。

    >另外,PHP-CPP汇编将使用php.h标头文件。除非安装PHP-DEV,否则通常在Ubuntu框中缺少此文件。我们可以通过发出此命令来安装与PHP5相关的开发文件:

<span>sudo apt-get install php5-dev</span>
登录后复制
登录后复制
登录后复制

>升级G并安装必要的标头文件后,我们可以发布以下命令以编译和安装PHP-CPP库文件(libphpcpp.so):>

<span>make && sudo make install</span>
登录后复制
登录后复制
登录后复制
登录后复制
汇编将很快。安装后,libphpcpp.so文件将被复制到/usr/lib,所有PHP-CPP标头文件将被复制到/usr/include/include and/usr/include/include/phpcpp文件夹。

>。 PHP-CPP LIB的安装现已完成。这非常简单,我们现在可以继续进行编程部分。

在这样做之前,我们将讨论PHP-CPP中使用的一些重要概念和术语。完整的文档可以在其官方网站上找到,并鼓励每个人在执行任何真正的编程之前阅读它。

骨架(空)扩展项目文件

PHP-CPP提供了一个骨架扩展项目,其中包含以下3个文件:

> main.cpp:包含get_module函数的主CPP文件(稍后将详细讨论)

>

makefile:示例制作文件以编译扩展名

    yourextension.ini:仅包含一行扩展名加载
  • > makefile
  • >如果您熟悉 *NIX开发,那么您熟悉此Makefile。应进行一些轻微的更改以自定义此文件以满足我们的需求:

更改名称=您对更有意义的extension,例如名称=骨架。

>更改ini_dir = /etc/php5/conf.d匹配系统的配置。就我而言,它是ini_dir = /etc/php5/cli/conf.d。我修改了INI路径,以首先启用PHP CLI环境的扩展。

  • 这些都是我所做的所有更改。其余的makefile可以保持原样。
  • > yourextension.ini
>我将此文件重命名为skeleton.ini,然后更改了这样的文件中的唯一行:

>

<span>sudo apt-get install php5-dev</span>
登录后复制
登录后复制
登录后复制

> main.cpp

在PHP-CPP提供的空项目中,此文件仅包含一个函数:get_module(),该函数下面摘录:

<span>make && sudo make install</span>
登录后复制
登录后复制
登录后复制
登录后复制

>目前,让我们更改此行以匹配我们打算创建的扩展名:>

当后者试图加载所需的库时,PHP调用了<span>extension=skeleton.so</span>来调用。 到目前为止,我们已经对空的项目进行了一些更改,以适应我们的需求。现在,我们可以编译和安装此项目并安装扩展名:

接下来,我们需要将所需的文件复制到适当的文件夹中:>

<span><span>#include <phpcpp.h></span>
</span>
<span>/**
</span><span> *  tell the compiler that the get_module is a pure C function
</span><span> */
</span><span>extern "C" {
</span>
    <span>/**
</span><span>     *  Function that is called by PHP right after the PHP process
</span><span>     *  has started, and that returns an address of an internal PHP
</span><span>     *  strucure with all the details and features of your extension
</span><span>     *
</span><span>     *  @return void*   a pointer to an address that is understood by PHP
</span><span>     */
</span>    PHPCPP_EXPORT <span>void *get_module() 
</span>    <span>{
</span>        <span>// static(!) Php::Extension object that should stay in memory
</span>        <span>// for the entire duration of the process (that's why it's static)
</span>        <span>static Php::Extension extension("yourextension", "1.0");
</span>
        <span>// @todo    add your own functions, classes, namespaces to the extension
</span>
        <span>// return the extension
</span>        <span>return extension;
</span>    <span>}
</span><span>}  </span>
登录后复制
登录后复制
>我们只需要确保将骨架复制到PHP扩展的正确位置(在我的Ubuntu设置中,它应该为/usr/lib/php5/20121212,如上所示)。

然后,我们可以通过PHP -I |将扩展名验证在CLI中加载。 GREP骨架,终端应显示类似的东西:

>
<span>static Php::Extension extension("skeleton", "1.0"); // To be humble, we can change the version number to 0.0.1</span>
登录后复制
登录后复制

(回想一下skeleton.ini是我们修改的文件,其中包含扩展名= skeleton.so line。)

> 到目前为止,我们已经使用PHP-CPP进行了编译并安装了我们的第一个PHP扩展。当然,此扩展程序还没有任何作用。现在,我们将创建第一个功能,以进一步了解建立PHP扩展的过程。

通过PHP-CPP开始PHP扩展开发“你好,泰勒”功能

我们创建的第一个功能将是“ Hello,World”的第一个功能。让我们查看main.cpp的完整代码:

>

>根据“注册本机函数”上的PHP-CPP文档,它支持四种类型的功能签名:

在这种情况下,我使用第二个签名,并且参数以数组形式(PHP功能)按值传递。

但是,在Helloworld中,我们专门使用了C型STD :: String来获取第一个参数。 我们还使用C STD LIB来输出一个热情的消息。

在get_module()函数中,在声明扩展变量后,我们添加了要导出的函数(helloworld()),并为php脚本(helloworld)分配一个名称。

现在,让我们编译并安装扩展程序。如果一切顺利进行,新的骨架将复制到扩展名目录。
<span>make && sudo make install</span>
登录后复制
登录后复制
登录后复制
登录后复制

我们可以编写一个简单的脚本来测试刚刚创建的函数:>

<span>cp -f skeleton.so /usr/lib/php5/20121212
</span><span>cp -f skeleton.ini /etc/php5/cli/conf.d</span>
登录后复制
请花一些时间来查看输出:

>我们将回到以后观察到的内容。

>函数参数通过参考

接下来,我们将看到另一个函数,该函数通过引用,swap()函数传递参数。在此功能中,我们还将尝试指定参数及其类型的数量。

在main.cpp中,我们添加了另一个函数swap():

>

<span>sudo apt-get install php5-dev</span>
登录后复制
登录后复制
登录后复制
以及通过指定参数数量及其类型来导出功能:>

我们明确地说:
<span>make && sudo make install</span>
登录后复制
登录后复制
登录后复制
登录后复制

将有两个参数(a和b);
    >
  • 应通过引用(而不是通过值); >通过
  • 它们应该是数字类型的。
  • >让我们编译并再次安装更新的扩展程序,并编写一些代码片段,以查看此新功能的工作方式:>
交换($ a)将失败。这是预期的和出乎意料的。预期的部分是我们需要两个参数,只给出一个参数。但是,当调用函数交换并提示我们不够的参数时,PHP不应该捕获该错误吗?

>

>第一个呼叫(交换($ a,$ b))显示了预期的结果:20 | 10。该函数交换了两个数字。
<span>extension=skeleton.so</span>
登录后复制
>

第二个通话是出乎意料的:我们告诉PHP我们要交换两个数字!但是它只是忽略了第二个参数传递的是字符串,并且无论如何都进行交换!

好吧,从某种意义上说,仍然可以预期。 PHP并没有真正区分数字类型和字符串类型。这种行为符合PHP标准。同样,由于这种行为,我们没有,也不能使用C内部类型作为功能(TEMP)中使用的临时变量,而是使用PHP ::值作为变量类型。

第三个通话将起作用。第一个var_dump将显示DateTime对象,第二个将显示整数。这是某种程度上出乎意料的(至少对我来说)。毕竟,对象与数字/字符串完全不同。但是,在考虑到这种“互换”行为在PHP中也可行之后,它与PHP的奇怪之处相符。

>那么,这是否意味着“类型”规范不会产生任何影响?并不真地。为了进一步阐述这一点,我们创建了第三个功能:>

我们这样注册了此功能:

测试代码将是这样的:

>
<span><span>#include <phpcpp.h></span>
</span>
<span>/**
</span><span> *  tell the compiler that the get_module is a pure C function
</span><span> */
</span><span>extern "C" {
</span>
    <span>/**
</span><span>     *  Function that is called by PHP right after the PHP process
</span><span>     *  has started, and that returns an address of an internal PHP
</span><span>     *  strucure with all the details and features of your extension
</span><span>     *
</span><span>     *  @return void*   a pointer to an address that is understood by PHP
</span><span>     */
</span>    PHPCPP_EXPORT <span>void *get_module() 
</span>    <span>{
</span>        <span>// static(!) Php::Extension object that should stay in memory
</span>        <span>// for the entire duration of the process (that's why it's static)
</span>        <span>static Php::Extension extension("yourextension", "1.0");
</span>
        <span>// @todo    add your own functions, classes, namespaces to the extension
</span>
        <span>// return the extension
</span>        <span>return extension;
</span>    <span>}
</span><span>}  </span>
登录后复制
登录后复制

>当我们通过正确的类类型(SampleClass)传递时,对SwapoBject()的第一个调用将起作用。第二个将失败,显示“可捕获的致命错误:参数1传递给swapobject()必须是SampleClass的实例,是给定的另一个类别的实例...”。

<span>static Php::Extension extension("skeleton", "1.0"); // To be humble, we can change the version number to 0.0.1</span>
登录后复制
登录后复制
>上面的代码段说明了类型限制的一个重要方面:标量类型声明并未真正实现。 PHP以及PHP-CPP仅执行对象类型声明。同样,在PHP侧并未真正执行参数的数量。

结论

在本文中,我们说明了准备PHP-CPP为我们的PHP环境工作的步骤。我们还讨论了使用PHP-CPP(和C语义)创建PHP扩展的一些基本步骤。

>我们介绍了扩展项目文件,功能签名,功能导出/注册和功能参数类型。

>在下一篇文章中,我们将进一步详细介绍PHP-CPP中的一些关键功能,并提供现实世界中的用例,展示了使用php-cpp的C类和名称空间实现的使用。

>

>关于PHP扩展开发的常见问题(常见问题解答)

什么是PHP-CPP,它与PHP有何不同?它提供了有据可查和用户友好型类的集合,使C开发人员可以编写PHP扩展名,而无需直接与Zend API合作的复杂性。与PHP是一种解释的语言不同,PHP-CPP允许您以C(Comperied语言)编写代码。这可能会导致性能改进,因为编译的代码通常比解释的代码更快。

>如何在系统上安装php-cpp?

在系统上安装PHP-CPP需要从GitHub克隆PHP-CPP存储库。克隆后,导航到目录并执行“ make”命令。构建过程完成后,使用“ Make install”命令安装库。请记住,您需要具有根特权来安装库。

>如何使用PHP-CPP?创建基本的PHP扩展名,使用PHP-CPP创建PHP扩展程序涉及多个步骤。首先,您需要为扩展程序创建一个目录并导航到其中。然后,为您的扩展程序创建一个“ makefile”和c源文件。 “ makefile”将包含构建扩展名的说明,而C源文件将包含用于扩展的实际代码。编写代码后,您可以使用“ make”命令构建扩展名。

>如何调试我的php扩展名?

>调试PHP扩展程序可能会有些棘手,因为您''重新处理一种编译的语言。但是,您可以使用GDB(GNU调试器)等工具进行调试。 GDB允许您设置断点,逐步浏览代码并检查变量,在尝试追踪错误时,这可能非常有用。

我可以使用php-cpp创建PHP 7的扩展名。

是的,PHP-CPP与PHP 7兼容。但是,您需要确保使用最新版本的PHP-CPP,因为较早的版本可能不支持PHP 7。

>我如何处理PHP-CPP中的异常?

php-cpp提供一个名为php ::异常的类,您可以用来从C代码中抛出异常。这些例外可以像其他任何PHP例外一样在您的PHP代码中捕获和处理。

>我可以使用PHP-CPP创建面向对象的扩展吗?您可以在C代码中定义类,然后可以在PHP代码中使用这些类。这使您可以编写易于维护的干净,模块化的代码。

>如何从我的C代码中调用PHP函数?

php-cpp提供了一个名为php :: call的类,您可以使用C代码调用PHP功能。这使您可以利用PHP内置功能在扩展中的功能。

>我可以使用php-cpp创建与数据库交互的扩展吗? CPP创建与数据库交互的扩展。但是,您需要使用C数据库库,因为PHP-CPP不提供任何内置数据库功能。

>

>一旦您''如何分发我的php扩展名? VE构建了PHP扩展名,您可以通过将其包装为PECL包装来分配它。 PECL是PHP扩展的存储库,它提供了分发和安装扩展的标准方法。

以上是通过PHP-CPP开始PHP扩展开发的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板