>
钥匙要点
注意:安装上的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>
>。 PHP-CPP LIB的安装现已完成。这非常简单,我们现在可以继续进行编程部分。
在这样做之前,我们将讨论PHP-CPP中使用的一些重要概念和术语。完整的文档可以在其官方网站上找到,并鼓励每个人在执行任何真正的编程之前阅读它。骨架(空)扩展项目文件
PHP-CPP提供了一个骨架扩展项目,其中包含以下3个文件:
makefile:示例制作文件以编译扩展名
>更改ini_dir = /etc/php5/conf.d匹配系统的配置。就我而言,它是ini_dir = /etc/php5/cli/conf.d。我修改了INI路径,以首先启用PHP CLI环境的扩展。
>
<span>sudo apt-get install php5-dev</span>
在PHP-CPP提供的空项目中,此文件仅包含一个函数:get_module(),该函数下面摘录:
<span>make && sudo make install</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 -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功能)按值传递。现在,让我们编译并安装扩展程序。如果一切顺利进行,新的骨架将复制到扩展名目录。
<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>
>我们将回到以后观察到的内容。
在main.cpp中,我们添加了另一个函数swap():
>
<span>sudo apt-get install php5-dev</span>
我们明确地说:
<span>make && sudo make install</span>
将有两个参数(a和b);
>
>第一个呼叫(交换($ 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-CPP中的一些关键功能,并提供现实世界中的用例,展示了使用php-cpp的C类和名称空间实现的使用。
>
>关于PHP扩展开发的常见问题(常见问题解答)我可以使用php-cpp创建PHP 7的扩展名。
是的,PHP-CPP与PHP 7兼容。但是,您需要确保使用最新版本的PHP-CPP,因为较早的版本可能不支持PHP 7。php-cpp提供一个名为php ::异常的类,您可以用来从C代码中抛出异常。这些例外可以像其他任何PHP例外一样在您的PHP代码中捕获和处理。
>如何从我的C代码中调用PHP函数?
以上是通过PHP-CPP开始PHP扩展开发的详细内容。更多信息请关注PHP中文网其他相关文章!