Writing PECL extension, need to iterate object properties, distinguish dynamic ones
I'm working on a data serialization routine wherein I must iterate through an object's properties while distinguishing between "sealed" properties (i.e., those defined by class definitions) and "dynamic" properties" (i.e., those assigned ad-hoc to the object that are not party of any class definition).
I've been searching through the lxr for suitable code examples, but can't seem to find any code doing precisely this thing. Also, the code really doesn't have many useful comments to explain what functions are doing which makes it pretty hard to follow. I can't figure out what zend_lookup_class or zend_update_class_constants are doing but somehow the function get_class_vars is excluding any non-accessible properties.
I have two big problems/questions that I'm hoping someone might help me sort out.
1) Is there a method that will reliably return all "sealed" properties in a *consistent order*. I.e., if I encounter an array of objects of class Foo, can I be sure that iterating through an object's properties will always occur in the exact same sequence? Any variation in the sequence order will result in serialization problems for this protocol.
2) What is the accepted/canonical/orthodox way to disinguish between public properties (i.e., properties available in the current scope) and private/protected properties? My loop below that uses zend_hash_get_current_key_ex appears to also iterate through properties unavailable in the current scope and yet I am not privy to their names.
E.g., I ran the following code. classEntry is the zend_class_entry corresponding to some object that is an instance of class ABC which has properties X, Y, and Z. Y is a private property.
Code:
char *key;
long index, i;
uint key_len;
HashPosition pos;
HashTable defaultProperties;
defaultProperties = classEntry->default_properties;
// for dev debugging, loop through default properties to list them
zend_hash_internal_pointer_reset_ex(&defaultProperties, &pos);
for (;; zend_hash_move_forward_ex(&defaultProperties, &pos)) {
i = zend_hash_get_current_key_ex(&defaultProperties, &key, &key_len, &index, 0, &pos);
if (i == HASH_KEY_NON_EXISTANT) {
// out of members! skip the rest of the loop
break;
}
php_printf("The %s th key is %s, i is %d\n", pos->arKey, key, i);
}
The output seems reasonable enough for the X and Z properties, but something is wrong with the Y property. Here's the output:
Code:
The Z th key is Z, i is 1
The th key is , i is 1
The X th key is X, i is 1
So apparently I cannot check i, the return value of zend_hash_get_current_key_ex for any indication that the property is inaccessible. What should I be checking for? Or should I be using some different function or combination of parameters?