From 537636373c59b3ce33f15311d2bc89ce72d5cc45 Mon Sep 17 00:00:00 2001 From: Toon Schoenmakers Date: Wed, 16 Sep 2015 15:29:58 +0200 Subject: Added support for setting a std::function as an exception handler This is so far only tested with php 5.5.9, might not work on versions below that. --- include/call.h | 1 + include/value.h | 6 ++++++ zend/exception_handler.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++ zend/functor.h | 8 ++++---- 4 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 zend/exception_handler.cpp diff --git a/include/call.h b/include/call.h index 094c7d2..f26fd29 100644 --- a/include/call.h +++ b/include/call.h @@ -46,6 +46,7 @@ extern PHPCPP_EXPORT Value require(const char *filename); inline PHPCPP_EXPORT Value require(const std::string &filename) { return require(filename.c_str()); } extern PHPCPP_EXPORT Value require_once(const char *filename); inline PHPCPP_EXPORT Value require_once(const std::string &filename) { return require_once(filename.c_str()); } +extern PHPCPP_EXPORT Value set_exception_handler(const std::function &handler); extern PHPCPP_EXPORT const char *sapi_name(); /** diff --git a/include/value.h b/include/value.h index 532d0c1..5b746a1 100644 --- a/include/value.h +++ b/include/value.h @@ -33,6 +33,7 @@ namespace Php { */ class Base; class ValueIterator; +class Parameters; template class HashMember; /** @@ -1209,6 +1210,11 @@ protected: friend class Callable; friend class Script; friend class ConstantImpl; + + /** + * Friend functions which have to access that zval directly + */ + friend Value set_exception_handler(const std::function &handler); }; /** diff --git a/zend/exception_handler.cpp b/zend/exception_handler.cpp new file mode 100644 index 0000000..51874a4 --- /dev/null +++ b/zend/exception_handler.cpp @@ -0,0 +1,49 @@ +/** + * Exception_handler.cpp + * + * Set the exception handler + * + * @author Toon Schoenmakers + */ + +/** + * Dependencies + */ +#include "includes.h" + +/** + * Open the PHP namespace + */ +namespace Php { + +/** + * Set a std::function as a php exception handler + */ +Value set_exception_handler(const std::function &handler) +{ + // create a functor which wraps our callback + Function functor(handler); + + // initialize our output value + Value output; + + // turn our user_exception_handler into a Value so we can return the original one later on + if (EG(user_exception_handler)) output = EG(user_exception_handler); + + // detach so we have the zval + auto value = functor.detach(true); + + // allocate the user_exception_handler + ALLOC_ZVAL(EG(user_exception_handler)); + + // copy our zval into the user_exception_handler + MAKE_COPY_ZVAL(&value, EG(user_exception_handler)); + + // return the original handler + return output; +} + +/** + * End of namespace + */ +} diff --git a/zend/functor.h b/zend/functor.h index 503a05c..5458027 100644 --- a/zend/functor.h +++ b/zend/functor.h @@ -29,12 +29,12 @@ public: * @param function The function to wrap */ Functor(const std::function &function) : _function(function) {} - + /** * Destructor */ virtual ~Functor() {} - + /** * Invoke the functor * @param params @@ -61,7 +61,7 @@ public: * @param tsrmls */ static void initialize(TSRMLS_D); - + /** * Shutdown the class * @param tsrmls @@ -80,7 +80,7 @@ private: * @var zend_class_entry */ static zend_class_entry *_entry; - + }; /** -- cgit v1.2.3