魔术方法

最后更新于:2022-04-02 02:33:25

[TOC] ## 概述 魔术方法中(__set,__get等)除了`__construct`,其他方法都可以不进行注册 `__onstruct`必须显示进行说明是因为: 1. 该__construct()方法没有固定的签名 2. 通过将其显式添加到扩展中,还可以指定它接受的参数 3. 该__construct()方法是公共,私有还是受保护的 ## 示例 ### 伪属性(__get,__set,__isset,__unset)
main.cpp ``` #include 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; } } ```

main.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 ``` #include #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; } } ```

main.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
main.cpp ``` #include #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.php ```
';