diff --git a/internals2/variables/index.xml b/internals2/variables/index.xml index 7053b7a3b5..95b88a5d56 100644 --- a/internals2/variables/index.xml +++ b/internals2/variables/index.xml @@ -1,32 +1,31 @@ - - Working with variables -
- Intro - - For working with variables in PHP's core you have to learn about different - fundamental concepts used in PHP. Firstly PHP is a dynamic and weak typed - language. Secondly PHP uses a copy on write mechanism with reference - counting for memory handling. Please check the chapter for details how - reference counting and references work. - - - PHP variables, in general, consist out of two things: The label, which - might, for instance, be an entry in a symbol table, and the actual variable - container. For the most parts of this manual we will focus on the variable - container. - - - The variable container, in code called zval, is holding all - data needed to handle the variable. This includes not only the actual value - but also the current type, a counter counting the number of labels pointing - to this container and a flag whether these labels should be treated as - references or copies. In PHP 5.3 the relevant structures, which you can - find in Zend/zend.h, look like this: - - + + Working with variables +
+ Intro + + For working with variables in PHP's you have to learn about different + fundamental concepts used in PHP. Firstly PHP is a dynamic and weak typed + language. Secondly PHP uses a copy on write mechanism with reference + counting for memory handling. Please check the chapter for details how + reference counting and references work. + + + PHP variables, in general, consist out of two things: The label, which + might, for instance, be an entry in a symbol table, and the actual variable + container. For the most parts of this manual we will focus on the variable + container. + + + The variable container, in code is called zval, it holds all + data needed to handle the variable. This includes not only the actual value + but also the current type, a reference counter and a flag to determine if the + zval should be treated as a reference. In PHP 5.3+ the relevant structures, + which you can find in Zend/zend.h, look like this: + + - - - In the zvalue_value one can find the internal representation - for the different types the fields used should be clear from the names and - comments - especially if one knows that PHP's arrays are infact hash - tables. Nonetheless, knowing PHP's types one might miss a few: - NULL, boolean and resources. For - NULL we need no value, as NULL is the value of - that type. For boolean and resource values PHP - re-uses the value field. In the case of a boolean it holds - either 0 for false or 1 for - true. For resource-typed variables it holds the - resource id. - - - Now the good message is that you don't have to know these things in detail - as there are - like always in PHP - acces macros. The bad news is that there - are many of them: There are macros to access any aspect of the - zval and then, as one often deals with pointers to - zvals and even pointers to pointers to zvals, for - most of them there are shortcuts dereferencing these pointers. These macros - are spread over Zend/zend.h, - Zend/zend_operators.h and Zend/zend_API.h. - -
-
- Creating variables and setting values - - - -
+
+ + In the zvalue_value one can find the internal representation + for the different types the fields used should be clear from the names and + comments - especially if one knows that PHP's arrays are infact hash + tables. Nonetheless, knowing PHP's types one might miss a few: + NULL, boolean and resources. For + NULL we need no value, as NULL is the value of + that type. For boolean and resource values PHP + re-uses the value field. In the case of a boolean it holds + either 0 for false or 1 for + true. For resource-typed variables it holds the + resource id. + + + + The following table define the macros exposed by the engine for working with zvals. + + + + Accessor Macros + + + + Prototype + Accesses + Description + + + + + zend_uchar Z_TYPE(zval zv) + type + returns the type of the value + + + + long Z_LVAL(zval zv) + value.lval + + + + + zend_bool Z_BVAL(zval zv) + value.lval + cast long value to zend_bool + + + + double Z_DVAL(zval zv) + value.dval + + + + + zend_bool Z_RESVAL(zval zv) + value.lval + returns the resource list identifier for value + + + + char* Z_STRVAL(zval zv) + value.str.val + return the string value + + + + int Z_STRLEN(zval zv) + value.str.len + return the length of the string value + + + + HashTable* Z_ARRVAL(zval zv) + value.ht + return the HashTable (array) value + + + + zend_object_value Z_OBJVAL(zval zv) + value.obj + returns object value + + + + uint Z_OBJ_HANDLE(zval zv) + value.obj.handle + returns the object handle for object value + + + + zend_object_handlers* Z_OBJ_HT_P(zval zv) + value.obj.handlers + returns the handler table for object value + + + + zend_class_entry* Z_OBJCE(zval zv) + value.obj + returns the class entry for object value + + + + HashTable* Z_OBJPROP(zval zv) + value.obj + returns the properties of object value + + + + HashTable* Z_OBJPROP(zval zv) + value.obj + returns the properties of object value + + + + HashTable* Z_OBJDEBUG(zval zv) + value.obj + if an object has the get_debug_info handler set, it is called, else Z_OBJPROP is called + + + + +
+ + + Reference Count Manipulation + + + + Prototype + Description + + + + + + zend_ulong Z_REFCOUNT(zval zv) + returns the reference count of the value + + + + void Z_SET_REFCOUNT(zval zv) + sets the reference count of the value + + + + void Z_ADDREF(zval zv) + increments the reference count of value + + + + void Z_DELREF(zval zv) + decrements the reference count of value + + + + zend_bool Z_ISREF(zval zv) + tells if the zval is a reference + + + + void Z_UNSET_ISREF(zval zv) + set is_ref__gc to 0 + + + + void Z_SET_ISREF(zval zv) + set is_ref__gc to 1 + + + + void Z_SET_ISREF_TO(zval zv, zend_uchar to) + set is_ref__gc to to + + + + +
+ + + The Z_* macros above all take a zval, they are all defined again suffixed with _P to take a pointer to a zval, for example zend_uchar Z_TYPE_P(zval* pzv), and again suffixed with _PP to take a pointer to a pointer to a zval, for example zend_uchar Z_TYPE_PP(zval** ppzv) + + + + Creation, Destruction, Separation and Copying + + + + Prototype + Description + + + + - + + ALLOC_INIT_ZVAL(zval* pzval) + emallocs pzval, and points pzval at a null typed zval for sanity + + + + MAKE_STD_ZVAL(zval* pzval) + emallocs pzval, setting the refcount to 1 + + + + ZVAL_COPY_VALUE(zval* dst, zval* src) + sets the value and type of dst from the value and type of src + + + + INIT_PZVAL_COPY(zval* dst, zval*dst) + performs ZVAL_COPY_VALUE, setting refcount of dst to 1, and setting is_ref__gc to 0 + + + + SEPARATE_ZVAL(zval** ppzval) + if the refcount of ppzval is >1, redirects *ppzval to a newly emalloc'd, copied, and constructed zval of the same type and value + + + + SEPARATE_ZVAL_IF_NOT_REF(zval** ppzval) + if *ppzval is not a reference, will perform SEPARATE_ZVAL on ppzval + + + + SEPARATE_ZVAL_TO_MAKE_IS_REF(zval** ppzval) + if *ppzval is not a reference, performs SEPARATE_ZVAL then Z_SET_ISREF_PP on ppzval + + + + COPY_PZVAL_TO_ZVAL(zval dst, zval** src) + results in dst being a copy of src without affecting the refcount of src + + + + MAKE_COPY_ZVAL(zval** src, zval* dst) + performs INIT_PZVAL_COPY, then zval_copy_ctor on the new zval + + + + +
+ +
+
+ Creating variables and setting values + + + +
-