diff options
author | Martijn Otto <martijn.otto@copernica.com> | 2014-02-06 16:06:43 +0100 |
---|---|---|
committer | Martijn Otto <martijn.otto@copernica.com> | 2014-02-06 16:06:43 +0100 |
commit | 7c3c6cb385543dd5a3730f6cce8337ae3c1307f7 (patch) | |
tree | 4204ea8c98041ed11e870f76067da5f6b17febb3 | |
parent | 30aeb60818c9d4b0318848d7dc83062f9c78b804 (diff) |
Added the call() method for Value objects, allowing calling of member functions of PHP objects
-rw-r--r-- | include/value.h | 29 | ||||
-rw-r--r-- | src/value.cpp | 255 |
2 files changed, 278 insertions, 6 deletions
diff --git a/include/value.h b/include/value.h index 6b764a2..0990e82 100644 --- a/include/value.h +++ b/include/value.h @@ -565,7 +565,6 @@ public: * Call the function in PHP * We have ten variants of this function, depending on the number of parameters * This call operator is only useful when the variable represents a callable - * @param name Name of the function * @return Value */ Value operator()(); @@ -580,6 +579,25 @@ public: Value operator()(Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7, Value p8); Value operator()(Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7, Value p8, Value p9); + /** + * Call a method + * We have ten variants of this function, depending on the number of parameters + * This is only applicable when the Value contains PHP object + * @param name Name of the function + * @return Value + */ + Value call(const std::string &name); + Value call(const std::string &name, Value p0); + Value call(const std::string &name, Value p0, Value p1); + Value call(const std::string &name, Value p0, Value p1, Value p2); + Value call(const std::string &name, Value p0, Value p1, Value p2, Value p3); + Value call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4); + Value call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5); + Value call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6); + Value call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7); + Value call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7, Value p8); + Value call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7, Value p8, Value p9); + private: /** * Call function with a number of parameters @@ -589,6 +607,15 @@ private: */ Value exec(int argc, struct _zval_struct ***params); + /** + * Call method with a number of parameters + * @param name Name of method to call + * @param argc Number of parameters + * @param argv The parameters + * @return Value + */ + Value exec(const std::string &name, int argc, struct _zval_struct ***params); + protected: /** * The wrapped zval diff --git a/src/value.cpp b/src/value.cpp index 49c9c2b..1fec43a 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -851,13 +851,219 @@ Value Value::operator()(Value p0, Value p1, Value p2, Value p3, Value p4, Value Value Value::operator()(Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7, Value p8, Value p9) { // array of parameters - zval **params[10] = { &p0._val, &p1._val, &p2._val, &p3._val, &p4._val, &p5._val, &p6._val, &p7._val, &p8._val, &p9._val}; + zval **params[10] = { &p0._val, &p1._val, &p2._val, &p3._val, &p4._val, &p5._val, &p6._val, &p7._val, &p8._val, &p9._val }; // call the function return exec(10, params); } /** + * Call the method - if the variable holds an object with the given method + * @param name name of the method to call + * @return Value + */ +Value Value::call(const std::string &name) +{ + // call with zero parameters + return exec(name, 0, NULL); +} + +/** + * Call the method - if the variable holds an object with the given method + * @param name name of the method to call + * @param p0 The first parameter + * @return Value + */ +Value Value::call(const std::string &name, Value p0) +{ + // array of parameters + zval **params[] = { &p0._val }; + + // call with zero parameters + return exec(name, 1, params); +} + +/** + * Call the method - if the variable holds an object with the given method + * @param name name of the method to call + * @param p0 The first parameter + * @param p1 The second parameter + * @return Value + */ +Value Value::call(const std::string &name, Value p0, Value p1) +{ + // array of parameters + zval **params[] = { &p0._val, &p1._val }; + + // call with zero parameters + return exec(name, 2, params); +} + +/** + * Call the method - if the variable holds an object with the given method + * @param name name of the method to call + * @param p0 The first parameter + * @param p1 The second parameter + * @param p2 The third parameter + * @return Value + */ +Value Value::call(const std::string &name, Value p0, Value p1, Value p2) +{ + // array of parameters + zval **params[] = { &p0._val, &p1._val, &p2._val }; + + // call with zero parameters + return exec(name, 3, params); +} + +/** + * Call the method - if the variable holds an object with the given method + * @param name name of the method to call + * @param p0 The first parameter + * @param p1 The second parameter + * @param p2 The third parameter + * @param p3 The fourth parameter + * @return Value + */ +Value Value::call(const std::string &name, Value p0, Value p1, Value p2, Value p3) +{ + // array of parameters + zval **params[] = { &p0._val, &p1._val, &p2._val, &p3._val }; + + // call with zero parameters + return exec(name, 4, params); +} + +/** + * Call the method - if the variable holds an object with the given method + * @param name name of the method to call + * @param p0 The first parameter + * @param p1 The second parameter + * @param p2 The third parameter + * @param p3 The fourth parameter + * @param p4 The fifth parameter + * @return Value + */ +Value Value::call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4) +{ + // array of parameters + zval **params[] = { &p0._val, &p1._val, &p2._val, &p3._val, &p4._val }; + + // call with zero parameters + return exec(name, 5, params); +} + +/** + * Call the method - if the variable holds an object with the given method + * @param name name of the method to call + * @param p0 The first parameter + * @param p1 The second parameter + * @param p2 The third parameter + * @param p3 The fourth parameter + * @param p4 The fifth parameter + * @param p5 The sixth parameter + * @return Value + */ +Value Value::call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5) +{ + // array of parameters + zval **params[] = { &p0._val, &p1._val, &p2._val, &p3._val, &p4._val, &p5._val }; + + // call with zero parameters + return exec(name, 6, params); +} + +/** + * Call the method - if the variable holds an object with the given method + * @param name name of the method to call + * @param p0 The first parameter + * @param p1 The second parameter + * @param p2 The third parameter + * @param p3 The fourth parameter + * @param p4 The fifth parameter + * @param p5 The sixth parameter + * @param p6 The seventh parameter + * @return Value + */ +Value Value::call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6) +{ + // array of parameters + zval **params[] = { &p0._val, &p1._val, &p2._val, &p3._val, &p4._val, &p5._val, &p6._val }; + + // call with zero parameters + return exec(name, 7, params); +} + +/** + * Call the method - if the variable holds an object with the given method + * @param name name of the method to call + * @param p0 The first parameter + * @param p1 The second parameter + * @param p2 The third parameter + * @param p3 The fourth parameter + * @param p4 The fifth parameter + * @param p5 The sixth parameter + * @param p6 The seventh parameter + * @param p7 The eighth parameter + * @return Value + */ +Value Value::call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7) +{ + // array of parameters + zval **params[] = { &p0._val, &p1._val, &p2._val, &p3._val, &p4._val, &p5._val, &p6._val, &p7._val }; + + // call with zero parameters + return exec(name, 8, params); +} + +/** + * Call the method - if the variable holds an object with the given method + * @param name name of the method to call + * @param p0 The first parameter + * @param p1 The second parameter + * @param p2 The third parameter + * @param p3 The fourth parameter + * @param p4 The fifth parameter + * @param p5 The sixth parameter + * @param p6 The seventh parameter + * @param p7 The eighth parameter + * @param p8 The ninth parameter + * @return Value + */ +Value Value::call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7, Value p8) +{ + // array of parameters + zval **params[] = { &p0._val, &p1._val, &p2._val, &p3._val, &p4._val, &p5._val, &p6._val, &p7._val, &p8._val }; + + // call with zero parameters + return exec(name, 9, params); +} + +/** + * Call the method - if the variable holds an object with the given method + * @param name name of the method to call + * @param p0 The first parameter + * @param p1 The second parameter + * @param p2 The third parameter + * @param p3 The fourth parameter + * @param p4 The fifth parameter + * @param p5 The sixth parameter + * @param p6 The seventh parameter + * @param p7 The eighth parameter + * @param p8 The ninth parameter + * @param p9 The tenth parameter + * @return Value + */ +Value Value::call(const std::string &name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7, Value p8, Value p9) +{ + // array of parameters + zval **params[] = { &p0._val, &p1._val, &p2._val, &p3._val, &p4._val, &p5._val, &p6._val, &p7._val, &p8._val, &p9._val }; + + // call with zero parameters + return exec(name, 10, params); +} + +/** * Call function with a number of parameters * @param argc Number of parameters * @param argv The parameters @@ -867,16 +1073,55 @@ Value Value::exec(int argc, zval ***params) { // the return zval zval *retval = nullptr; - + // the current exception zval *oldException = EG(exception); - + // call the function if (call_user_function_ex(CG(function_table), NULL, _val, &retval, argc, params, 1, NULL) != SUCCESS) return nullptr; - + // was an exception thrown? if (oldException != EG(exception)) throw OrigException(EG(exception)); - + + // no (additional) exception was thrown + return retval ? Value(retval) : nullptr; +} + +/** + * Call method with a number of parameters + * @param name Name of method to call + * @param argc Number of parameters + * @param argv The parameters + * @return Value + */ +Value Value::exec(const std::string &name, int argc, struct _zval_struct ***params) +{ + // the method to call and the return value + zval *method; + zval *retval; + + // construct the method, this is done similarly to how in PHP we can call + // a member function using call_user_func: pass in an array with the object + // and the method to call as the first parameter + MAKE_STD_ZVAL(method); + array_init(method); + + // add the object and the method to call + add_index_zval(method, 0, _val); + add_index_stringl(method, 1, name.c_str(), name.length(), 0); + + // the current exception + zval *oldException = EG(exception); + + // call the function + if (call_user_function_ex(CG(function_table), NULL, method, &retval, argc, params, 1, NULL) != SUCCESS) return nullptr; + + // free the method + FREE_ZVAL(method); + + // was an exception thrown? + if (oldException != EG(exception)) throw OrigException(EG(exception)); + // no (additional) exception was thrown return retval ? Value(retval) : nullptr; } |