社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
在前一篇文章《Windows下编写php扩展(二)将linux下的php-cpp项目移植到windows》说明了将php-cpp移植到windows的过程。
已移植到windows的phpcpp项目的完整的vs2017解决方案可在此 下载
接下来谈一谈用php-cpp开发php扩展的过程,本次的实验平台是win10 企业版,visual C++ 2017 社区版。
开发php扩展的工作区基本内容如下:
phpcpp-devinclude 目录下存放要引用的头文件,在phpcpp项目的linux版下,phpcpp-devincludep目录下的头文件与 编译phpcpp项目时include目录下的头文件是完一样的。但在windows下编译时,因为编译器的一些差异,所以对phpcpp-devinclude目录下的少量文件做了修改。
phpcpp-devlib 中存放 phpcpp.dll及引入库 phpcpp.lib 。在此项目中并不实际需要phpcpp.dll ,运行时,phpcpp.dll应该放在php安装目录 ,与php.exe在同一个目录中。前一篇文章中所谈的php-cpp的主要生成结果就是phpcpp.dll与phpcpp.lib。通过使用phpcpp.dll ,使得php扩展的开发工作得到了很大的简化。
本项目生成的扩展dll的位置是: x64ReleasemyPhpcppExt.dll。要在php中使用该扩展,应该将myPhpcppExt.dll复制到
php安装目录的ext目录中,并修改php.ini,加上相应的加载扩展的指令。
文件夹x64是vs2017自动生成的文件夹,删除后执行生成解决方案命令又会重新生成。
install_ext.php 是一个小脚本,用于在测试扩展功能时方便地将 扩展dll复制到目标文件夹,避免手工复制。如果路径变更了,也应相应地修改install_ext.php中的目标路径。
main.cpp 是扩展项目的源文件,其中有一些示例函数
phpcpp.h是包含文件的总入口,为了适应windows环境,与linux版本相比,做了一点路径上的小改动。
#include "phpcpp.h"
Php::Value my_plus(Php::Parameters ¶ms)
{
return params[0] + params[1] ;
}
void my_example()
{
// the C++ equivalent of the echo() function
Php::out << "example 1" << std::endl;
// generate output without a newline, and ensure that it is flushed
Php::out << "example 2n" << std::flush;
// or call the flush() method
Php::out << "example 3n";
Php::out.flush();
// just like all PHP functions, you can call the echo() function
// from C++ code as well
Php::echo("Example 4n");
Php::out.flush();
}
void my_echo()
{
// the C++ equivalent of the echo() function
Php::out << "my_echo ,test6" << std::endl;
Php::out.flush();
}
Php::Value native_bubblesort(Php::Parameters ¶ms)
{
// there is one input array, cast the PHP variable to a vector of ints
std::vector<int> input = params[0];
// loop through the array
for (size_t i = 0; i < input.size(); i++)
{
// loop through the elements that were already processed
for (size_t j = 1; j < input.size() - i; j++)
{
// move on if smaller
if (input[j - 1] <= input[j]) continue;
// swap elements
int temp = input[j];
input[j] = input[j - 1];
input[j - 1] = temp;
}
}
// done
return input;
}
/**
* tell the compiler that the get_module is a pure C function
*/
extern "C" {
/**
* Function that is called by PHP right after the PHP process
* has started, and that returns an address of an internal PHP
* strucure with all the details and features of your extension
*
* @return void* a pointer to an address that is understood by PHP
*/
__declspec(dllexport) void *get_module()
{
// static(!) Php::Extension object that should stay in memory
// for the entire duration of the process (that's why it's static)
static Php::Extension extension("myPhpcppExt1", "1.0");
// @todo add your own functions, classes, namespaces to the extension
//ÔÏîÄ¿ÖеÄadd·½·¨ÔÚÖØÔØʱÓеãÎÊÌ⣬ÏÖÔÚ½«Ìí¼Óº¯Êýµ½À©Õ¹µÄ¹¦ÄÜÖØÃüÃûΪ addFunc
extension.add<my_plus>("my_plus", {
Php::ByVal("a", Php::Type::Numeric),
Php::ByVal("b", Php::Type::Numeric),
});
extension.add<my_example>("my_example");
extension.add<my_echo>("my_echo");
extension.add<native_bubblesort>("native_bubblesort",{ Php::ByVal("input", Php::Type::Array) });
// return the extension
return extension;
}
}
用于测试的php文件内容
<?php
$x=2;
$y = 4;
echo my_plus($x,$y);
echo "n";
my_example(1);
my_echo();
// fill an array with random numbers
$count = 10000;
$x = array();
for ($i=0; $i<$count; $i++) $x[] = rand(0, 1000000);
// run the native and scripted bubblesort functions
$start = microtime(true);
$y = native_bubblesort($x);
$native = microtime(true);
$x = scripted_bubblesort($x);
$scripted = microtime(true);
// show the results
echo("Native: ".($native - $start)." secondsn");
echo("Scripted: ".($scripted - $native)." secondsn");
echo("rate:: ".($scripted - $native)/($native - $start)." secondsn");
//--------------------function-----------------------
function scripted_bubblesort(array $input)
{
// number of elements in the array
$count = count($input);
// loop through the array
for ($i = 0; $i < $count; $i++)
{
// loop through the elements that were already processed
for ($j = 1; $j < $count - $i; $j++)
{
// move on if smaller
if ($input[$j-1] <= $input[$j]) continue;
// swap elements
$temp = $input[$j];
$input[$j] = $input[$j-1];
$input[$j-1] = $temp;
}
}
// done
return $input;
}
从以上例子可以看出。同样的冒泡排序算法,用C++实现的速度是PHP实现的30多倍。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!