]> granicus.if.org Git - php/commitdiff
- Add zend_merge_properties() which is designed to serve *_fetch_object().
authorMarcus Boerger <helly@php.net>
Fri, 29 Aug 2003 23:27:22 +0000 (23:27 +0000)
committerMarcus Boerger <helly@php.net>
Fri, 29 Aug 2003 23:27:22 +0000 (23:27 +0000)
- Explain drawbacks of object_and_properties_init and zend_merge_properties.
#
# I guess we can live with the purity problem of potentially calling __set()
# of an object which wasn't already ctored.
#

Zend/zend_API.c
Zend/zend_API.h

index ccfb51fce563760ae0db593b56cb2adbd79479d7..ead407f9e7feff6e324fadb00dd1d80db475da4b 100644 (file)
@@ -655,6 +655,44 @@ ZEND_API int _array_init(zval *arg ZEND_FILE_LINE_DC)
 }
 
 
+static int zend_merge_property(zval **value, int num_args, va_list args, zend_hash_key *hash_key)
+{
+       /* which name should a numeric property have ? */
+       if (hash_key->nKeyLength) {
+               zval *obj = va_arg(args, zval *);
+               zend_object_handlers *obj_ht = va_arg(args, zend_object_handlers *);
+               zval member;
+               TSRMLS_FETCH();
+
+               ZVAL_STRINGL(&member, hash_key->arKey, hash_key->nKeyLength-1, 0);
+               obj_ht->write_property(obj, &member, *value TSRMLS_CC);
+       }
+       return ZEND_HASH_APPLY_KEEP;
+}
+
+
+/* This function should be called after the constructor has been called 
+ * because it may call __set from the uninitialized object otherwise. */
+ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destroy_ht TSRMLS_DC)
+{
+       zend_object_handlers *obj_ht = Z_OBJ_HT_P(obj);
+       zend_class_entry *old_scope = EG(scope);
+
+       EG(scope) = Z_OBJCE_P(obj);
+       zend_hash_apply_with_arguments(properties, (apply_func_args_t)zend_merge_property, 2, obj, obj_ht);
+       EG(scope) = old_scope;
+
+       if (destroy_ht) {
+               zend_hash_destroy(properties);
+               FREE_HASHTABLE(properties);
+       }
+}
+
+
+/* This function requires 'properties' to contain all props declared in the
+ * class and all props being public. If only a subset is given or the class 
+ * has protected members then you need to merge the properties seperately by
+ * calling zend_merge_properties(). */
 ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC)
 {
        zval *tmp;
index ad500c15325755cc6fb9479462e8ab390fa6a5c0..4bbc3c2e09809dbf84f72fda3c31f5a348b6a277 100644 (file)
@@ -203,6 +203,8 @@ ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC TSRMLS_DC);
 ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC TSRMLS_DC);
 ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC);
 
+ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destroy_ht TSRMLS_DC);
+
 /* no longer supported */
 ZEND_API int add_assoc_function(zval *arg, char *key, void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS));