> Welcome to the jungle

Thank you, Francois. Malheuresement, plus de questions...


> PHP uses an object store.
Am I correct in understanding that the object store is a global data
structure? Wouldn't this tend to discourage any attempts at
multithreading/multiprocessing within one's PHP script--unless the object
store is protected by a lock...


It would appear that for some zend_object ,zobj, that if the object has any
dynamic properties at all then zobj->properties will be defined a HashTable
that contains not just the dynamic properties, but all the default object
properties (i.e., those defined explicitly by the class) as well. At least
that appears to be the case from my code below.

Is there not any way to first iterate through the default properties and
then iterate through *only the dynamic properties* ?  If so, please
advise?  If not, it sounds like I must iterate through all properties and
check each property's key to see if it's included among the default
properties.

Also -- and this is *very* important:
1) Will this code ALWAYS return the properties in the same sequence? E.g.,
if I am iterating through N objects of type MyClass, will each instance
iterate the properties in the same order?
2) Will this code ALWAYS iterate over default properties (i.e., "sealed"
properties, those explicitly defined by class definitinos) FIRST and then
iterate any dynamically assigned properties?
These questions are very important for my serialization algorithm.

            zobj = zend_objects_get_address(*val TSRMLS_CC);

            if (!zobj->properties) {
                php_printf("***No dynamic properties!\n");
            } else {
                php_printf("***we got dynamic properties...sadly, this will
also iterate through default properties too\n");
                zend_hash_internal_pointer_reset_ex(zobj->properties, &pos);
                while (zend_hash_get_current_data_ex(zobj->properties,
(void **) &value, &pos) == SUCCESS) {
                    if (zend_hash_get_current_key_ex(zobj->properties,
&key, &key_len, &num_index, 0, &pos) == HASH_KEY_IS_STRING) {
                        if (zend_check_property_access(zobj, key, key_len-1
TSRMLS_CC) == SUCCESS) {

                            zend_unmangle_property_name(key, key_len - 1,
&class_name, &prop_name);

                            php_printf("dynamic property is %s, key_len is
%d\n", prop_name, key_len);
                        }
                    }
                    zend_hash_move_forward_ex(zobj->properties, &pos);
                }
            }

On Tue, Sep 22, 2015 at 5:42 PM, François Laupretre <franc...@php.net>
wrote:

> Hi,
>
> Hope this can help.
>
> Le 22/09/2015 20:16, j adams a écrit :
>
>> 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 specified by class definitions) and "dynamic" properties"
>> (i.e., those assigned ad-hoc to some object that are not party of any
>> class
>> definition).
>>
>> I found the source of the php function get_object_vars():
>> http://lxr.php.net/xref/PHP_5_6/Zend/zend_builtin_functions.c#985
>> However, I am still pretty confused. PHP source is *full* of macros and
>> has
>> basically no comments.
>>
>
> Welcome to the jungle
>
> 2) What does zend_objects_get_address do? This reference looks very
>> different than the usual macro, e.g. Z_OBJ_HT_P
>>
>
> PHP uses an object store. This allows handling objects by reference. Every
> object instance is defined by a numeric handle (an offset in the object
> store). Object zvals contain the object handle. The object address is
> obtained through the object store. Look
> http://lxr.php.net/xref/PHP_5_6/Zend/zend_objects_API.c#274
>
> Z_OBJ_HT() is used to call an object's handlers. This information is also
> present in the zend_object but, for a better performance AFAIK, also made
> available in the zval struct.
>
> 3) Am I correct in understanding that zend_check_property_access simply
>> checks if the property in question is availabe in the scope in which this
>> function call gets executed?
>>
>
> Yes
>
>
>> 4) What does zend_unmangle_property_name do? Why is this function changed
>> to zend_unmangle_property_name_ex in 5.5 and later?
>>
>
> Properties are stored using 'mangled' names. The format of a mangled name
> is '<NULL><class name><NULL><property name><NULL>', where <NULL> is a null
> byte. Class name and property name are 'decoded' by
> zend_unmangle_property_name(). Look
> http://lxr.php.net/xref/PHP_5_6/Zend/zend_compile.c#5373
>
> 5) Why do we call Z_ADDREF_PP(value) here? Is this reference counting to
>> prevent garbage collection?
>>
>
> This is reference counting. Incremented because a reference to the 'value'
> zval is added to the result array.
>
> 7) The code looks quite different between the different versions:
>> 5.3 - http://lxr.php.net/xref/PHP_5_3/Zend/zend_builtin_functions.c#950
>> 5.5 - http://lxr.php.net/xref/PHP_5_5/Zend/zend_builtin_functions.c#982
>> 5.6 - http://lxr.php.net/xref/PHP_5_6/Zend/zend_builtin_functions.c#985
>>  From what I can tell there is at least one difference between 5.3 and 5.6
>> -- zend_unmangle_property_name_ex does not exist before 5.5. Can anyone
>> recommend how to make code that'll work in 5.3-5.6? Also, with 7 coming
>> out
>> I'd like it work there too.
>>
>
> Making code working with 5.3-5.6 is quite easy with a pair of ifdef.
> Unfortunately, writing code to compile on PHP 5 & 7 is complex. It seems
> most people porting extensions to PHP 7 finally duplicated most, if not all
> of their code.
>
> Regards
>
> François
>

Reply via email to