Fix foreach after the garbage collector is invoked
Fixes https://github.com/mongodb/mongo-php-driver/issues/1776, https://jira.mongodb.org/browse/PHPC-2505, and the equivalent bug triggered when assigning dynamic properties and then unsetting them again.
The underlying issue in both cases is the invocation of zend_std_get_properties, which populates the properties hashtable in the zend object (not in the interned mongo one).
This, in turn, causes the iteration logic to completely skip iteration due to the if (zend_hash_num_elements(properties) == 0) { check in the ZEND_FE_RESET_R_SPEC_CV_HANDLER
The fix adds custom handlers for get_property, write_property, unset_property, has_property, get_property_ptr_ptr which use a new interned php_properties hashtable, instead of the zend hashtable property.
The zend_gc handler is also modified to invoke get_properties instead of zend_std_get_properties.
The overall implementation mostly works as expected, the only issue is some strange refcounting behavior within the garbage collector on the hashtable returned by get_gc, which sometimes increments the refcount without decrementing it again, leading to a leak of the interned properties hashtable (detectable using ASAN); I have asked clarifications regarding that, marking the PR as draft in the meantime.
There's also a leftover issue with foreach loops not exiting for whatever reason, still looking into that.