summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-14 10:32:32 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-14 10:32:32 +0100
commit4c55148476952276ece19f5b975ca0a0233dee4c (patch)
treef16b9da14403c33f1ca951e16e58841a3d88f091 /src
parent159781ee8257329ca9c40306f7495a8c2f31f710 (diff)
implemented __destruct magic method
Diffstat (limited to 'src')
-rw-r--r--src/base.cpp35
-rw-r--r--src/classbase.cpp47
2 files changed, 58 insertions, 24 deletions
diff --git a/src/base.cpp b/src/base.cpp
index 2c46147..f677bcf 100644
--- a/src/base.cpp
+++ b/src/base.cpp
@@ -13,29 +13,6 @@
namespace Php {
/**
- * Function that is called to clean up space that is occupied by the object
- * @param object The object to be deallocated
- */
-static void deallocate_object(void *object TSRMLS_DC)
-{
- // allocate memory for the object
- MixedObject *obj = (MixedObject *)object;
-
- // deallocate the cpp object
- if (obj->cpp) delete obj->cpp;
-
- // get rid of the object properties
- // @todo if we enable the following two lines, segmentation
- // faults and memory corruption occurs. however, the online
- // documentation does it like this
- //zend_hash_destroy(obj->php.properties);
- //FREE_HASHTABLE(obj->php.properties);
-
- // deallocate the entire object
- efree(obj);
-}
-
-/**
* Store the object in the PHP object cache
* @param entry Class entry
* @return MixedObject
@@ -71,13 +48,23 @@ MixedObject *Base::store(zend_class_entry *entry)
// the destructor and clone handlers are set to NULL. I dont know why, but they do not
// seem to be necessary...
- _handle = zend_objects_store_put(result, NULL, deallocate_object, NULL TSRMLS_CC);
+ _handle = zend_objects_store_put(result, (zend_objects_store_dtor_t)ClassBase::destructObject, (zend_objects_free_object_storage_t)ClassBase::freeObject, NULL TSRMLS_CC);
// done
return result;
}
/**
+ * Overridable method that is called right before an object is destructed
+ */
+void Base::__destruct() const
+{
+ // throw exception, so that the PHP-CPP library will check if the user
+ // somehow registered an explicit __destruct method
+ throw NotImplemented();
+}
+
+/**
* Overridable method that is called to check if a property is set
*
* The default implementation does nothing, and the script will fall back
diff --git a/src/classbase.cpp b/src/classbase.cpp
index ec316cd..2fae658 100644
--- a/src/classbase.cpp
+++ b/src/classbase.cpp
@@ -1077,6 +1077,53 @@ void ClassBase::unsetProperty(zval *object, zval *member, const struct _zend_lit
}
/**
+ * Function that is called when an object is about to be destructed
+ * This will call the magic __destruct method
+ */
+void ClassBase::destructObject(zend_object *object, zend_object_handle handle)
+{
+ // allocate memory for the object
+ MixedObject *obj = (MixedObject *)object;
+
+ // get meta info
+ ClassBase *meta = cpp_class(object->ce);
+
+ // prevent exceptions
+ try
+ {
+ // call the destruct function
+ if (obj->cpp) meta->callDestruct(obj->cpp);
+ }
+ catch (const NotImplemented &exception)
+ {
+ // fallback on the default destructor call
+ zend_objects_destroy_object(object, handle);
+ }
+ catch (Exception &exception)
+ {
+ // a regular Php::Exception was thrown by the extension, pass it on
+ // to PHP user space
+ exception.process();
+ }
+}
+
+/**
+ * Function that is called to clean up space that is occupied by the object
+ * @param object The object to be deallocated
+ */
+void ClassBase::freeObject(zend_object *object)
+{
+ // allocate memory for the object
+ MixedObject *obj = (MixedObject *)object;
+
+ // deallocate the cpp object
+ if (obj->cpp) delete obj->cpp;
+
+ // pass on to the default destructor
+ zend_objects_free_object_storage(object);
+}
+
+/**
* Function that is called when an instance of the class needs to be created.
* This function will create the C++ class, and the PHP object
* @param entry Pointer to the class information