咱们在开始之前确保我们有一定的C++基础储备,包括类的声明,模板类,继承,构造函数,析构函数,友元函数,虚拟函数,等c++ 概念有一定的理解
类声明及注册
- 在声明类之前,我们需要明确这个类是否需要暴露给php应用来时实例,如果需要暴露在外边(给php代码实力),则声明的类一定要继承php::Base
- 通过Php::Class 把对应的类注册到extension;
- 通过Php::Interface 我们可以声明接口类;
- Php::Class对象有一个方法“extends()”和一个方法“implements()”,可用于指定基类和实现的接口;
在extension 中注册的interface 即使用了implements ,编译的时候是不会报错,只是让用户知道他可能来源与那个interface 的方法
类方法
- 成员函数的声明,参数,返回值等跟普通函数的声明几乎一样
- 通过 myClass.method<&MyClass::increment>(“increment”) 类对象的method方法来注册对应的成员函数;
- cpp 支持静态方法声明;
- 可以通过 class对象的method方法 的第二个参数将方法标记为 public、private 或 protected 来限定访问修饰符
- 使用 Php::Final 和 Php::Abstract 标志来创建最终或抽象方法;
- 限定访问修饰符参数可以与 Php::Abstract 或 Php::Final 进行按位或运算;
- __construct()and__destruct()方法,即php的构造函数和析构函数,但区别于c++ 的构造函数;
- phpcpp库同样支持__get(),__set(),__clone等魔术方法;
其他
- 通过class类对象的property 方法声明类属性;
- 通过class 类对象的constant 方法声明类常量;
#include <phpcpp.h>
#include <iostream>
#include <string>
//声明MyClass类为可以被外部php 调用
class MyClass : public Php::Base
{
//属性声明:用原生的c++ 属性类型
private:
int _value;
public:
//构造函数
MyClass()
{
_value = 3;
std::cout << "MyClass::MyClass" << std::endl;
std::cout << this << std::endl;
std::cout << _value << std::endl;
}
MyClass(int value) : _value(value)
{
std::cout << "MyClass::MyClass(" << value << ")" << std::endl;
}
//拷贝构造
MyClass(const MyClass &that)
{
std::cout << "MyClass::MyClass copy constructor" << std::endl;
}
//析构函数
virtual ~MyClass()
{
std::cout << "MyClass::~MyClass" << std::endl;
}
//php 构造函数,区别于c++ 构造函数,只是在实例化完成后第一个默认执行的函数(对于c++就是普通函数)
void __construct(Php::Parameters ¶ms)
{
// 属性初始化
if (!params.empty()) _value = params[0];
std::cout << "php constructor" << std::endl;
}
//php 析构函数
//virtual 虚函数 虚函数是指一个类中你希望重载的成员函数 ,当你用一个 基类指针或引用 指向一个继承类对象的时候,调用一个虚函数时, 实际调用的是继承类的版本
virtual void __destruct()
{
std::cout << "MyClass::__destruct" << std::endl;
}
//静态方法
static void staticMethod(Php::Parameters ¶ms)
{
std::cout << "staticMethod GETS CALLED!!!!" << std::endl;
}
//返回类对象
Php::Value objectMethod(Php::Parameters ¶ms)
{
int initValue = params[0];
return Php::Object("MyClass", new MyClass(initValue));
}
Php::Value myMethod(Php::Parameters ¶ms)
{
return params[0];
}
Php::Value increment() { return ++_value; }
Php::Value decrement() { return --_value; }
Php::Value value() const { return _value; }
};
/**
* 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
*/
PHPCPP_EXPORT 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("tiway", "1.0");
//声明一个接口类
Php::Interface myInterface("MyInterface");
//声明接口方法
myInterface.method("myMethod", {
Php::ByVal("value", Php::Type::String, true)
});
Php::Class<MyClass> myClass("MyClass");
// myClass.implements(myInterface);
myClass.method<&MyClass::myMethod>("myMethod", {
Php::ByVal("value", Php::Type::String, true)
});
//声明类属性
myClass.property("property1", "prop1");
myClass.property("property2", "prop2", Php::Protected);
//类常量
myClass.constant("MY_CONSTANT_1", 3.1415);
myClass.add(Php::Constant("MY_CONSTANT_2", "constant string"));
myClass.method<&MyClass::__construct>("__construct", {
Php::ByVal("a", Php::Type::Numeric)
});
//
myClass.method<&MyClass::__destruct>("__destruct");
//静态方法
myClass.method<&MyClass::staticMethod>("staticMethod");
myClass.method<&MyClass::objectMethod>("objectMethod", {
Php::ByVal("n", Php::Type::Numeric, true)
});
//标记为 public、private 或 protected 来限定访问修饰符
//标志参数可以与 Php::Abstract 或 Php::Final 进行按位或运算
myClass.method<&MyClass::value>("value", Php::Public | Php::Final);
myClass.method<&MyClass::increment>("increment");
myClass.method<&MyClass::decrement>("decrement");
//声明类对象禁止克隆
myClass.method("__clone", Php::Private);
// add the class to the extension
extension.add(std::move(myInterface));
extension.add(std::move(myClass));
// return the extension
return extension;
}
}
以上代码 https://github.com/tiway-deng/phpcpp-/tree/main/Tiway-class
总结
- 用phpcpp 虽然大大降低了写php 拓展的难度,但是对于c++ 的基础还是有一定的要求
- 如果用phpcpp 只是重写函数部分的话,可能c++本身的优势不是很大,如果是整个模块用cpp 来重构的话也涉及到开发周期与迭代周期的问题