魔术方法
最后更新于:2022-04-02 02:33:25
[TOC]
## 概述
魔术方法中(__set,__get等)除了`__construct`,其他方法都可以不进行注册
`__onstruct`必须显示进行说明是因为:
1. 该__construct()方法没有固定的签名
2. 通过将其显式添加到扩展中,还可以指定它接受的参数
3. 该__construct()方法是公共,私有还是受保护的
## 示例
### 伪属性(__get,__set,__isset,__unset)
class User : public Php::Base
{
private:
std::string _name;
std::string _email;
public:
User() = default;
virtual ~User() = default;
// 参数使用 Php::Value 而不是 Php::Parameters
// 是因为 __get 方法只能为一个参数
Php::Value __get(const Php::Value &name)
{
if (name == "name")
return _name;
if (name == "email")
return _email;
return Php::Base::__get(name);
}
void __set(const Php::Value &name, const Php::Value &value)
{
if (name == "name")
{
// 使用 stringValue() 函数把 value 转为 字符串
_name = value.stringValue();
}
else if (name == "email")
{
std::string email = value;
if (email.find('@') == std::string::npos)
{
throw Php::Exception("Invalid email address");
}
_email = email;
}
else
{
// 默认处理
Php::Base::__set(name, value);
}
}
bool __isset(const Php::Value &name)
{
if (name == "name" || name == "email")
return true;
return Php::Base::__isset(name);
}
void __unset(const Php::Value &name)
{
if (name == "name" || name == "email")
{
throw Php::Exception("Name and email address can not be removed");
}
Php::Base::__unset(name);
}
};
extern "C"
{
PHPCPP_EXPORT void *get_module()
{
static Php::Extension myExtension("my_extension", "1.0");
Php::Class user("User");
myExtension.add(std::move(user));
return myExtension;
}
}
```
### 魔术方法__call(),__callStatic()和__invoke()
#include
class MyClass : public Php::Base
{
public:
MyClass() = default;
virtual ~MyClass() = default;
Php::Value regular(Php::Parameters ¶ms)
{
return "this is a regular method";
}
Php::Value __call(const char *name, Php::Parameters ¶ms)
{
std::string retval = std::string("__call ") + name;
for (auto ¶m : params)
{
retval += " " + param.stringValue();
}
return retval;
}
// 报错,无法实现
static Php::Value __callStatic(const char *name, Php::Parameters ¶ms)
{
Php::out<<"123"< myClass("MyClass");
myClass.method<&MyClass::regular>("regular");
myExtension.add(std::move(myClass));
return myExtension;
}
}
```
### __toString
#include
class MyClass : public Php::Base
{
public:
MyClass() = default;
virtual ~MyClass() = default;
Php::Value __toString(){
return "123";
}
};
extern "C" {
PHPCPP_EXPORT void *get_module() {
static Php::Extension my_extension("my_extension","1.0.0");
Php::Class myclass("MyClass");
my_extension.add(std::move(myclass));
return my_extension;
}
}
```
';
main.cpp
``` #includemain.php
``` name = "John Doe"; $user->email = "john.doe@example.com"; // 调用 __get echo ($user->email . "\n"); // john.doe@example.com // 调用 __isset var_dump(isset($user->name)); // bool(true) // 调用 __unset // 由于在c++中设置了移除email会抛异常 try { unset($user->email); } catch (Exception $e) print_r($e->getMessage()); //Name and email address can not be removed% } ```### 魔术方法__call(),__callStatic()和__invoke()
main.cpp
``` #includemain.php
``` regular()."\n"); // this is a regular method // 调用 __call echo($object->something()."\n"); // __call something echo($object->myMethod(1,2,3,4)."\n"); // __call myMethod 1 2 3 4 echo($object->whatever("a","b")."\n"); // __call whatever a b // 调用 __callStatic 但是失败了 MyClass::something()."\n"; echo(MyClass::myMethod(5,6,7)."\n"); echo(MyClass::whatever("x","y")."\n"); // 调用 __invoke 单是失败了 echo($object("parameter","passed","to","invoke")."\n"); ```### __toString