PHP扩展是高级PHP程序员必须了解的技能之一,对于一个初入门的PHP扩展开发者,怎么才能开发一个成熟的扩展,进入PHP开发的高级领域呢?本系列开发教程将手把手带您从入门进入高级阶段。
本教程系列在linux下面开发(推荐使用centos),php版本用的是5.6,并假设您有必定的linux操做经验和c/c++基础。
有问题须要沟通的朋友请加QQ技术交流群32550793和我沟通。
前面两节介绍了如何用PHP-CPP编写经常使用的扩展函数,扩展类。对怎么使用PHP-CPP开发扩展应该已经很熟悉了,下面晋级学习一下关于扩展函数参数类型方面的内容。php
下面教程内容的相关源码已经上传到github上面。linux
git clone https://github.com/elvisszhang/phpcpp_param.git
有时候,咱们开发的函数,咱们但愿只能传入特定的类型,例如字符串运算的函数只能传入字符串参数,数值运算的函数只能传入数字参数,数组操做的函数只能传入数组参数。c++
下面是扩展中如何指定一个函数参数类型的样例代码git
#include <phpcpp.h> void example(Php::Parameters ¶ms) { } extern "C" { PHPCPP_EXPORT void *get_module() { static Php::Extension myExtension("my_extension", "1.0"); myExtension.add<example>("example", { Php::ByVal("a", Php::Type::Numeric), Php::ByVal("b", "ExampleClass"), Php::ByVal("c", "OtherClass") }); return myExtension; } }
上面的 Php::ByVal 是表明值类型的参数的设定方式,聪明点的你应该猜到相对应还有一个 Php::ByRef的表明引用类型的参数设定方式。惋惜的是在php5.x扩展上面,通过实验证实,引用方式的参数设定无效。程序员
Php::ByVal 是表明值类型的参数的设定方式,总共有两个函数原型定义。github
第一种原型是给标量,数组,对象,匿名函数等参数类型使用的,其C++的函数定义以下。数据库
/** * ByVal 值类型的参数的设定方式 * @param name 参数名称 * @param type 参数类型 * @param required 参数是否必填,默认必填 */ ByVal(const char *name, Php::Type type, bool required = true);
第二种原型是给具备特定类名的函数参数使用的,其C++的函数定义以下。centos
/** * ByVal 值类型的参数的设定方式 * @param name 参数名称 * @param classname 参数类名 * @param nullable 是否能够为空 * @param required 参数是否必填,默认必填 */ ByVal(const char *name, const char *classname, bool nullable = false, bool required = true);
值得注意的是,PHP不存在所谓函数参数名这个说法,上面函数参数里面的name只是起一个助记符的做用,主要是在参数类型错误等异常状况下,抛出异常的错误信息里面使用,方便用户知道具体是哪一个参数有问题。
ByVal函数中的Php::Type是个C++的枚举量,表明PHP-CPP的函数参数,总共支持如下11种类型。数组
Php::Type::Null - 表示任何类型均可以传入 Php::Type::Numeric - 整数类型 Php::Type::Float - 数值类型,支持整数、单精度浮点数、双精度浮点数 Php::Type::Bool - 布尔类型 Php::Type::Array - 数组类型 Php::Type::Object - 对象类型 Php::Type::String - 字符串类型 Php::Type::Resource - 资源类型(保存有为打开文件、数据库链接、图形画布区域等的特殊句柄) Php::Type::Constant - 常量类型 Php::Type::ConstantArray - 常量数组类型 Php::Type::Callable - 函数类型
除了 Php::Type::Array or Php::Type::Object 这两个类型的参数使用起来比较特殊,必须使用专用的对应的C++类来操做。其余类型使用起来基本上差异不大,由于PHP::Value这个类已经作了类型重载处理,。函数
对于阶乘运算函数,咱们都知道,须要并且只需传入一个正整数类型便可。
下面是该扩展函数的C++源码
//演示阶乘 Php::Value pm_factorial(Php::Parameters ¶ms) { int n = (int)params[0]; if(n < 0 ) return 0; int i,f=1; for(i=1;i<=n;i++) f *= i; return f; }
注册扩展函数的代码
myExtension.add<pm_factorial>("pm_factorial", { Php::ByVal("a", Php::Type::Numeric) });
PHP测试代码(test/1.php)
<?php echo PHP_EOL . '-----TEST pm_factorial()-----' . PHP_EOL; var_dump( pm_factorial() ); echo PHP_EOL . '-----TEST pm_factorial(\'abc\')-----' . PHP_EOL; var_dump( pm_factorial('abc','def') ); echo PHP_EOL . '-----TEST pm_factorial(\'5\')-----' . PHP_EOL; var_dump( pm_factorial('5') ); echo PHP_EOL . '-----TEST pm_factorial(0)-----' . PHP_EOL; var_dump( pm_factorial(0) ); echo PHP_EOL . '-----TEST pm_factorial(10)-----' . PHP_EOL; var_dump( pm_factorial(10) ); echo PHP_EOL . '-----TEST pm_factorial(-10)-----' . PHP_EOL; var_dump( pm_factorial(-10) ); echo PHP_EOL . '-----TEST pm_factorial(5.3)-----' . PHP_EOL; var_dump( pm_factorial(5.3) ); ?>
测试返回结果
# php test/1.php -----TEST pm_factorial()----- PHP Warning: pm_factorial() expects at least 1 parameter(s), 0 given in /data/develop/phpcpp_param/test/1.php on line 3 NULL -----TEST pm_factorial('abc')----- int(1) -----TEST pm_factorial('5')----- int(120) -----TEST pm_factorial(0)----- int(1) -----TEST pm_factorial(10)----- int(3628800) -----TEST pm_factorial(-10)----- int(0) -----TEST pm_factorial(5.3)----- int(120)
根据以上测试结果,能够总结出:
以演示两个数字相加为例,咱们但愿传入两个参数,并且两个参数都是数值类型。
下面是该扩展函数的C++源码
//演示两个数相加 Php::Value pm_add(Php::Parameters ¶ms) { return params[0] + params[1]; }
注册扩展函数的代码
myExtension.add<pm_add>("pm_add", { Php::ByVal("a", Php::Type::Float), Php::ByVal("b", Php::Type::Float) });
PHP测试代码(test/2.php)
<?php echo PHP_EOL . '-----TEST pm_add()-----' . PHP_EOL; var_dump( pm_add() ); echo PHP_EOL . '-----TEST pm_add(1)-----' . PHP_EOL; var_dump( pm_add(1) ); echo PHP_EOL . '-----TEST pm_add(\'abc\',\'def\')-----' . PHP_EOL; var_dump( pm_add('abc','def') ); echo PHP_EOL . '-----TEST pm_add(\'1\',\'2\')-----' . PHP_EOL; var_dump( pm_add('1','2') ); echo PHP_EOL . '-----TEST pm_add(1,2)-----' . PHP_EOL; var_dump( pm_add(1,2) ); echo PHP_EOL . '-----TEST pm_add(1.3,2.4)-----' . PHP_EOL; var_dump( pm_add(1.3,2.4) ); ?>
运行测试代码,返回结果
# php test/2.php -----TEST pm_add()----- PHP Warning: pm_add() expects at least 2 parameter(s), 0 given in /data/develop/phpcpp_param/test/1.php on line 3 NULL -----TEST pm_add(1)----- PHP Warning: pm_add() expects at least 2 parameter(s), 1 given in /data/develop/phpcpp_param/test/1.php on line 6 NULL -----TEST pm_add('abc','def')----- int(0) -----TEST pm_add('1','2')----- int(3) -----TEST pm_add(1,2)----- int(3) -----TEST pm_add(1.3,2.4)----- float(3.7)
根据以上测试结果,能够总结出:
因为篇幅有限,其余的参数类型下一章节继续演示。