FAQ
There appear to be two different ways that I can free an internal
structure when dealing with classes. The first is to declare a
'zend_objects_destroy_object' handler:

...
    retval.handle = zend_objects_store_put(intern,
(zend_objects_store_dtor_t) zend_objects_destroy_object,
my_free_function_callback, NULL TSRMLS_CC);

    retval.handlers = zend_get_std_object_handlers();
...

In which 'my_free_function_callback' is the callback that frees
underlying structure information. The alternative is to use __destruct:

PHP_METHOD(my_class, __destruct)
{
}

...

static const zend_function_entry my_class_methods[] = {
...
  PHP_ME(my_class, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR)
...
};


Which is considered best-practice? I'm leaning toward the latter, but
want to make sure there aren't any issues with relying on the __destruct
approach.

--
Thomas Hruska
CubicleSoft President

I've got great, time saving software that you will find useful.

http://cubiclesoft.com/

Search Discussions

  • Johannes Schlüter at May 2, 2014 at 3:08 pm

    On Fri, 2014-05-02 at 07:45 -0700, Thomas Hruska wrote:
    ...
    retval.handle = zend_objects_store_put(intern,
    (zend_objects_store_dtor_t) zend_objects_destroy_object,
    my_free_function_callback, NULL TSRMLS_CC);

    retval.handlers = zend_get_std_object_handlers();
    ...

    In which 'my_free_function_callback' is the callback that frees
    underlying structure information.
    This is guaranteed to be called *exactly* once.
    The alternative is to use __destruct:

    PHP_METHOD(my_class, __destruct)
    {
    }
    This might be called and arbitrary number of times or might not be
    called at all. (inherited classes might overwrite the dtor and not call
    the parent; user might manually call $oject->__destruct() as they like)
    Which is considered best-practice? I'm leaning toward the latter, but
    want to make sure there aren't any issues with relying on the __destruct
    approach.
    My opinion is that __destruct() should "unset" the object state, as it
    makes sense, it should exist (unless class is marked final) so users can
    reliably call it from child classes. __destruct() should *not* destroy
    internal object structures which leaves pointers around etc. but always
    leave a defined state.

    The dtor handler should do all required cleanup to ensure there are no
    leaks etc. This mostly means cleaning up things the engine can't reach
    otherwise (having "struct my_object { zend_object inner; my_ptr_t
    *ptr; }" object->ptr should be cleaned up here)


    johannes
  • Thomas Hruska at May 3, 2014 at 3:24 am

    On 5/2/2014 8:07 AM, Johannes Schlüter wrote:
    On Fri, 2014-05-02 at 07:45 -0700, Thomas Hruska wrote:
    Which is considered best-practice? I'm leaning toward the latter, but
    want to make sure there aren't any issues with relying on the __destruct
    approach.
    My opinion is that __destruct() should "unset" the object state, as it
    makes sense, it should exist (unless class is marked final) so users can
    reliably call it from child classes. __destruct() should *not* destroy
    internal object structures which leaves pointers around etc. but always
    leave a defined state.

    The dtor handler should do all required cleanup to ensure there are no
    leaks etc. This mostly means cleaning up things the engine can't reach
    otherwise (having "struct my_object { zend_object inner; my_ptr_t
    *ptr; }" object->ptr should be cleaned up here)

    johannes
    Thanks! That was very helpful.

    --
    Thomas Hruska
    CubicleSoft President

    I've got great, time saving software that you will find useful.

    http://cubiclesoft.com/

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-internals @
categoriesphp
postedMay 2, '14 at 2:45p
activeMay 3, '14 at 3:24a
posts3
users2
websitephp.net

People

Translate

site design / logo © 2022 Grokbase