summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToon Schoenmakers <toon.schoenmakers@copernica.com>2015-09-16 15:29:58 +0200
committerToon Schoenmakers <toon.schoenmakers@copernica.com>2015-09-16 15:29:58 +0200
commit537636373c59b3ce33f15311d2bc89ce72d5cc45 (patch)
treea52ef6932895a0eb7b644d38dafdb2c26790d9c6
parent913cc8ac69ec9cc6705b26575644e887c2dedc30 (diff)
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.
-rw-r--r--include/call.h1
-rw-r--r--include/value.h6
-rw-r--r--zend/exception_handler.cpp49
-rw-r--r--zend/functor.h8
4 files changed, 60 insertions, 4 deletions
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<Value(Parameters &params)> &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 Type> 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<Value(Parameters &params)> &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 <toon.schoenmakers@copernica.com>
+ */
+
+/**
+ * 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<Value(Parameters &params)> &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<Value(Parameters &params)> &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;
-
+
};
/**