phpng-upgrading

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
phpng-upgrading [2015/06/02 03:33]
bjori
phpng-upgrading [2019/05/18 20:02] (current)
santiagolizardo Add missing parenthesis to zend_register_resource example
Line 1: Line 1:
-====== Upgrading PHP extensions from PHP5 to NG ======+====== Upgrading PHP extensions from PHP5 to NG ====== ​
  
 Many of the frequently used API functions have changed, such as the ''​HashTable''​ API; this page intends to document as many as possible of those changes that actually affect the way extension and core code is written. It's highly recommended to read the general information about PHPNG implementation at [[phpng-int]],​ before reading this guide. Many of the frequently used API functions have changed, such as the ''​HashTable''​ API; this page intends to document as many as possible of those changes that actually affect the way extension and core code is written. It's highly recommended to read the general information about PHPNG implementation at [[phpng-int]],​ before reading this guide.
Line 13: Line 13:
 ===== zval ===== ===== zval =====
  
-  * PHPNG doesn'​t require any involvement of pointers to pointers to zval. Most occurrences of **zval%%**%%** variables and parameters have to be changes ​into **zval%%*%%**. The corresponding **Z_*_PP()** macros that work with such variables should be changed into **Z_*_P()**.+  * PHPNG doesn'​t require any involvement of pointers to pointers to zval. Most occurrences of **zval%%**%%** variables and parameters have to be changed ​into **zval%%*%%**. The corresponding **Z_*_PP()** macros that work with such variables should be changed into **Z_*_P()**.
  
   * In many places PHPNG work with zval directly (eliminating need for allocation and deallocation). In these cases corresponding **zval%%*%%** variable should be converted into plain **zval**, macros that use this variable from **Z_*P()** into **Z_*()** and corresponding creation macros from **ZVAL_*(var,​ ...)** into **ZVAL_*(&​var,​ ...)**. Be always careful about passing addresses of **zval** and **&** operator. PHPNG almost never require passing address of **zval%%*%%**. In some places **&** operator should be removed.   * In many places PHPNG work with zval directly (eliminating need for allocation and deallocation). In these cases corresponding **zval%%*%%** variable should be converted into plain **zval**, macros that use this variable from **Z_*P()** into **Z_*()** and corresponding creation macros from **ZVAL_*(var,​ ...)** into **ZVAL_*(&​var,​ ...)**. Be always careful about passing addresses of **zval** and **&** operator. PHPNG almost never require passing address of **zval%%*%%**. In some places **&** operator should be removed.
Line 192: Line 192:
 </​code>​ </​code>​
  
-**Z_STRVAL*()** now should be used as read-only object. It's not possible to assign anything into it. It's possible to modify ​spearate ​characters, but before doing it you must be sure that this string is not referred form everywhere else (it is not interned and its reference-counter is 1). Also after in-place string modification you might need to reset calculated hash value.+**Z_STRVAL*()** now should be used as read-only object. It's not possible to assign anything into it. It's possible to modify ​separate ​characters, but before doing it you must be sure that this string is not referred form everywhere else (it is not interned and its reference-counter is 1). Also after in-place string modification you might need to reset calculated hash value.
  
 <​code>​ <​code>​
Line 204: Line 204:
 Zend has a new **zend_string** API, except that **zend_string** is underlining structure for string representation in **zval**, these structures are also used throughout much of the codebase where **char%%*%%** and **int** were used before. Zend has a new **zend_string** API, except that **zend_string** is underlining structure for string representation in **zval**, these structures are also used throughout much of the codebase where **char%%*%%** and **int** were used before.
  
-**zend_strings** (not **IS_STRING** zvals) may be created using **zend_string_init(char *val, int len, int persistent)** function.+**zend_strings** (not **IS_STRING** zvals) may be created using **zend_string_init(char *val, size_t ​len, int persistent)** function.
 The actual characters may be accessed as **str->​val** and string length as **str->​len**. The hash value of the string should be accessed through **zend_string_hash_val** function. It'll re-calculate hash value if necessary. The actual characters may be accessed as **str->​val** and string length as **str->​len**. The hash value of the string should be accessed through **zend_string_hash_val** function. It'll re-calculate hash value if necessary.
  
Line 270: Line 270:
 - RETURN_STRINGL(implstr.c,​ implstr.len,​ 0); - RETURN_STRINGL(implstr.c,​ implstr.len,​ 0);
 + smart_str str = {0}; + smart_str str = {0};
-+ smart_str_appendl(str,​ " ", sizeof("​ ") - 1); ++ smart_str_appendl(&str, " ", sizeof("​ ") - 1); 
-+ smart_str_0(str);​++ smart_str_0(&str);
 + if (str.s) { + if (str.s) {
 +   ​RETURN_STR(str.s);​ +   ​RETURN_STR(str.s);​
Line 499: Line 499:
      ​zend_object_std_init(&​intern->​std,​ ce TSRMLS_CC);      ​zend_object_std_init(&​intern->​std,​ ce TSRMLS_CC);
      ...      ...
-     ​custom_object_handlers.offset = XtOffsetof(struct custom_obj, std);+     ​custom_object_handlers.offset = XtOffsetOf(struct custom_obj, std);
      ​custom_object_handlers.free_obj = custom_free_storage;​      ​custom_object_handlers.free_obj = custom_free_storage;​
  
 +     ​intern->​std.handlers = custom_object_handlers;​
 +    ​
      ​return &​intern->​std;​      ​return &​intern->​std;​
 } }
Line 532: Line 534:
 ===== Resources ===== ===== Resources =====
  
-  * **zval**s of type **IS_RESOURCE** don't keep resource handle anymore. Resource handle can't be retrieved using **Z_LVAL*()**. Instead you should use **Z_RES*()** macro to retrieve the resource record directly. The resource record is represented by **zend_resource** structure. It contains ''​type''​ - resource type, ''​ptr''​ - pointer to actual data, ''​handle''​ - numeric resource index (for compatibility) and service fields for reference counter. Actually this **zend_resurce** structure is a replacement for indirectly referred **zend_rsrc_list_entry**. All occurances ​of **zend_rsrc_list_entry** should be replaced by **zend_resource**.+  * **zval**s of type **IS_RESOURCE** don't keep resource handle anymore. Resource handle can't be retrieved using **Z_LVAL*()**. Instead you should use **Z_RES*()** macro to retrieve the resource record directly. The resource record is represented by **zend_resource** structure. It contains ''​type''​ - resource type, ''​ptr''​ - pointer to actual data, ''​handle''​ - numeric resource index (for compatibility) and service fields for reference counter. Actually this **zend_resurce** structure is a replacement for indirectly referred **zend_rsrc_list_entry**. All occurrences ​of **zend_rsrc_list_entry** should be replaced by **zend_resource**.
  
   * <​del>​**zend_list_find()**</​del>​ function is removed, because resources are accessed directly.   * <​del>​**zend_list_find()**</​del>​ function is removed, because resources are accessed directly.
Line 553: Line 555:
  
  
-  * <​del>​**ZEND_REGISTER_RESOURCE/​ZEND_FETCH_RESOURCE()**</​del>​ are droped ​ +  * <​del>​**ZEND_REGISTER_RESOURCE/​ZEND_FETCH_RESOURCE()**</​del>​ are dropped ​ 
  
 <​code>​ <​code>​
Line 569: Line 571:
  
 - REGISTER_RESOURCE(return_value,​ result, le_result); - REGISTER_RESOURCE(return_value,​ result, le_result);
-+ RETURN_RES(zend_register_resource(result,​ le_result);++ RETURN_RES(zend_register_resource(result,​ le_result));
 </​code>​ </​code>​
  
Line 603: Line 605:
 ===== Parameters Parsing API changes ===== ===== Parameters Parsing API changes =====
  
-  * PHPNG doesn'​t work with **zval%%**%%** anymoreso it doesn't need **'Z'** specifier anymore. It must be replaced by **'z'**.+  * The **'​l'​** specifier now expects a ''​zend_long''​ argumentinstead of a ''​long'' ​argument.
 <​code>​ <​code>​
-zval **pzv; +long lval
-- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "​Z",​ &pzv) == FAILURE) { +zend_long lval
-zval *zv+  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &lval) == FAILURE) {
-if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zv) == FAILURE) {+
 </​code>​ </​code>​
  
-  * in addition to **'​s'​** specifier that expects string, PHPNG introduced **'​S'​** specifier that also expects string, but places argument into **zend_string** variable. In some cases direct usage of **zend_string** is preferred. (For example when received string used as a key in HashTable API.+  * The length argument of the **'​s'​** specifier now expects a ''​size_t''​ variable instead of an ''​int''​ variable. 
 +<​code>​ 
 +  char *str; 
 +- int len; 
 ++ size_t len; 
 +  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "​s",​ &str, &len) == FAILURE) { 
 +</​code>​ 
 + 
 +  * In addition to **'​s'​** specifier that expects string, PHPNG introduced **'​S'​** specifier that also expects string, but places argument into **zend_string** variable. In some cases direct usage of **zend_string** is preferred. (For example when received string used as a key in HashTable API.
 <​code>​ <​code>​
 - char *str; - char *str;
Line 618: Line 627:
 + zend_string *str; + zend_string *str;
 + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "​S",​ &str) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "​S",​ &str) == FAILURE) {
 +</​code>​
 +
 +  * PHPNG doesn'​t work with **zval%%**%%** anymore, so it doesn'​t need **'​Z'​** specifier anymore. It must be replaced by **'​z'​**.
 +<​code>​
 +- zval **pzv;
 +- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "​Z",​ &pzv) == FAILURE) {
 ++ zval *zv;
 ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "​z",​ &zv) == FAILURE) {
 </​code>​ </​code>​
  
Line 628: Line 645:
 </​code>​ </​code>​
  
-  * arguments passed by reference should be assigned into the referenced value. It's possible to separte ​such arguments, to get referenced value at first place.+  * arguments passed by reference should be assigned into the referenced value. It's possible to separate ​such arguments, to get referenced value at first place.
 <​code>​ <​code>​
 - zval **ret; - zval **ret;
Line 645: Line 662:
 Information about each function call recorded in a chain of zend_execute_data structures. EG(current_execute_data) points into ''​call frame''​ of currently executed functions (previously zend_execute_data structures were created only for user-level PHP functions). I'll try to explain the difference between old and new call frame structures field by field. Information about each function call recorded in a chain of zend_execute_data structures. EG(current_execute_data) points into ''​call frame''​ of currently executed functions (previously zend_execute_data structures were created only for user-level PHP functions). I'll try to explain the difference between old and new call frame structures field by field.
  
-  * **zend_execute_data.opline** - instruction pointer of the currently executed user function. For internal functions its value is undefined. (previously for interanl ​functions its value was NULL)+  * **zend_execute_data.opline** - instruction pointer of the currently executed user function. For internal functions its value is undefined. (previously for internal ​functions its value was NULL)
  
   * <​del>​**zend_execute_data.function_state**</​del>​ - this field was removed. **zend_execute_data.call** should be used instead.   * <​del>​**zend_execute_data.function_state**</​del>​ - this field was removed. **zend_execute_data.call** should be used instead.
Line 673: Line 690:
   * **zend_execute_data.return_value** - pointer to **zval%%*%%** where the currently executed op_array should store the result. It may be NULL if call doesn'​t care about return value. (this is a new field).   * **zend_execute_data.return_value** - pointer to **zval%%*%%** where the currently executed op_array should store the result. It may be NULL if call doesn'​t care about return value. (this is a new field).
  
-Arguments to functions stored in **zval** slots directly after **zend_execute_data** structure. they may be accessed using **ZEND_CALL_ARG(execute_data,​ arg_num)** macro. For user PHP functions first argument overlaps with first ''​compiled ​cariable''​ - CV0, etc. In case caller passes more arguments that callee receives, all extra arguments are copied to be after all used by calee CVs and TMP variables.+Arguments to functions stored in **zval** slots directly after **zend_execute_data** structure. they may be accessed using **ZEND_CALL_ARG(execute_data,​ arg_num)** macro. For user PHP functions first argument overlaps with first ''​compiled ​variable''​ - CV0, etc. In case caller passes more arguments that callee receives, all extra arguments are copied to be after all used by callee ​CVs and TMP variables.
  
    
 ===== Executor Globals - EG() Changes ===== ===== Executor Globals - EG() Changes =====
  
-  * **EG(symbol_table)** - was turned to be a **zend_array** (previously it was a **HashTable**). It's not a bog problem to reach underlining HashTable+  * **EG(symbol_table)** - was turned to be a **zend_array** (previously it was a **HashTable**). It's not a big problem to reach underlining HashTable
  
 <​code>​ <​code>​
phpng-upgrading.1433216002.txt.gz · Last modified: 2017/09/22 13:28 (external edit)