rfc:zpp-conversion-rules

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:zpp-conversion-rules [2015/02/19 20:10] zeevrfc:zpp-conversion-rules [2021/03/27 14:25] (current) – Move to inactive ilutov
Line 1: Line 1:
-====== PHP RFC: Coercive Types for Function Arguments ====== +====== PHP RFC: Type parsing modifications ====== 
-  * Version: 0.1 +  * Version: 0.4 
-  * Date: 2015-02-19 +  * Date: 2015-02-22 
-  * Author: François Laupretre francois@php.net>, Zeev Suraski <zeev@php.net> +  * Author: François Laupretrefrancois@php.net 
-  * Status: Draft+  * Status: Inactive
   * First Published at: https://wiki.php.net/rfc/zpp-conversion-rules   * First Published at: https://wiki.php.net/rfc/zpp-conversion-rules
  
Line 9: Line 9:
 ===== Introduction ===== ===== Introduction =====
  
-This RFC proposes to implement a new set of rules to be used when parsing +This RFC proposes changes in the ruleset used to filter 
-internal function arguments.+and convert input arguments to internal functions. 
 + 
 +===== History =====
  
 The changes proposed here are based on concerns that arose during the discussion about The changes proposed here are based on concerns that arose during the discussion about
 [[https://wiki.php.net/rfc/scalar_type_hints|scalar type hints]]. [[https://wiki.php.net/rfc/scalar_type_hints|scalar type hints]].
  
-While the discussion focused on a dual-mode approach, with people opposing use cases +While the discussion mostly opposed 'weak' and 'strict' mode proponents, 
-about so-called 'weak' and 'strict' typingsome of us decided to search for +each camp showing use cases to prove it was right, we decided to gather all these use cases 
-a compromise that would satisfy both camps.+and go exploring another way : search single-mode compromise that would satisfy both camps. 
  
 It was soon clear that the strongest argument of strict-typing proponents was that It was soon clear that the strongest argument of strict-typing proponents was that
-'weak' mode was way too permissive, +'weak' mode was way too permissive, allowing, for instance, true or '7 years' as integer value.
-allowing, for instance, true or '7 years' as integer value+
- +
-As the proposed argument type hinting mechanism is aligned on the ZPP behavior, +
-and as everyone seemed to agree it should remain so, it was decided to propose a new more +
-restrictive ruleset to be implemented in ZPP and zend_parse_parameters().+
  
-Sothis RFC presents a new ruleset for parameter parsing and implicit conversions.+As the 'weak' mode of the proposed type hinting mechanism was based on the ZPP layer, 
 +and as everyone agreed any single-mode mechanism should keep using it, 
 +we decided to propose a new more restrictive ruleset to be implemented in ZPP.
  
-Note: In the rest of the document, 'ZPP' means 'Z_PARAM macros and zend_parse_parameters()' +Note: In the whole document, we use the 'ZPP' term as a union set including Z_PARAM macros, zend_parse_arg_xxx() functions, and zend_parse_parameters() 
-as, whatever the final implementationboth mechanisms must remain in sync.+as, whatever the rulesetthese mechanisms must keep implementing the same logic.
  
 ===== Proposal ===== ===== Proposal =====
Line 43: Line 42:
  
 The following table shows the current rules used to accept and convert an input zval through The following table shows the current rules used to accept and convert an input zval through
-the ZPP layer :+ZPP :
  
 ^            ^  Zval type  ^^^^^^^^ ^            ^  Zval type  ^^^^^^^^
 ^  ZPP type  ^ IS_NULL        ^ IS_FALSE     ^ IS_TRUE      ^ IS_LONG   ^ IS_DOUBLE ^ IS_STRING ^ ^  ZPP type  ^ IS_NULL        ^ IS_FALSE     ^ IS_TRUE      ^ IS_LONG   ^ IS_DOUBLE ^ IS_STRING ^
 ^ bool       | Yes (-> false) | <native>     | <native>     | Yes (1)   | Yes (1)   | Yes (2)   | ^ bool       | Yes (-> false) | <native>     | <native>     | Yes (1)   | Yes (1)   | Yes (2)   |
-^ long       | Yes (-> 0)     | Yes (-> 0)   | Yes (-> 1)   | <native>  | Yes       | (3)       |+^ long       | Yes (-> 0)     | Yes (-> 0)   | Yes (-> 1)   | <native>  | Yes (5)   | (3)       |
 ^ double     | Yes (-> 0.0)   | Yes (-> 0.0) | Yes (-> 1.0) | Yes       | <native>  | (4)       | ^ double     | Yes (-> 0.0)   | Yes (-> 0.0) | Yes (-> 1.0) | Yes       | <native>  | (4)       |
 ^ string     | Yes (-> ""   | Yes (-> "" | Yes (-> "1") | Yes       | Yes       | <native>  | ^ string     | Yes (-> ""   | Yes (-> "" | Yes (-> "1") | Yes       | Yes       | <native>  |
Line 56: Line 55:
   * (3) Run string through is_numeric_str_function() and detect error. If double returned, convert it to long   * (3) Run string through is_numeric_str_function() and detect error. If double returned, convert it to long
   * (4) Run string through is_numeric_str_function() and detect error. If int returned, convert it to double   * (4) Run string through is_numeric_str_function() and detect error. If int returned, convert it to double
 +  * (5) Discard fractional part, if any
  
 The conversion of IS_STRING to int/float is done through _is_numeric_string_ex(). The conversion of IS_STRING to int/float is done through _is_numeric_string_ex().
 Among others, this function has the following behavior : Among others, this function has the following behavior :
  
-  * Stop conversion at first non digit character with no error (this is what authorizes '7 years' as integer).+  * Stop conversion at first non digit character with no error (ignore every trailing char).
  
 ==== Proposed changes ==== ==== Proposed changes ====
  
-  * Disable IS_FALSE/IS_NULL to anything but bool (native)+  * Disable IS_FALSE/IS_NULL to anything except bool. 
-  * Disable (IS_STRING -> bool) +  * IS_STRING to bool: Convert every string that would be converted to 0 or 0.0 to false, instead of just “0”. 
-  * Disable IS_NULL conversion to every ZPP type. It causes IS_NULL to be systematically rejected by every Z_PARAM macro except Z_PARAM_ZVAL.+  * Disable IS_NULL to be accepted for any ZPP type except the new 'null'.
   * Disable (IS_DOUBLE -> long) if the fractional part of the input value is non null.   * Disable (IS_DOUBLE -> long) if the fractional part of the input value is non null.
   * When converting from IS_STRING to long, reject conversion if string contains the representation of a number with a non null fractional part.   * When converting from IS_STRING to long, reject conversion if string contains the representation of a number with a non null fractional part.
 +  * Add a 'null' ZPP type. This type accepts IS_NULL only. While quite useless for input arguments, it is used as return type and as element of union types.
  
 In _is_numeric_string_ex() : In _is_numeric_string_ex() :
Line 79: Line 80:
  
 ^            ^  Zval type  ^^^^^^^^ ^            ^  Zval type  ^^^^^^^^
-^  ZPP type     ^ IS_NULL ^ IS_FALSE ^ IS_TRUE  ^ IS_LONG   ^ IS_DOUBLE ^  IS_STRING ^ +^  ZPP type     ^ IS_NULL  ^ IS_FALSE ^ IS_TRUE  ^ IS_LONG   ^ IS_DOUBLE ^  IS_STRING ^ 
-^ bool          |  -      | <native> | <native> | Yes (1)    Yes (1)   |  -        +^ null          | <native> |  -       | -        | -          -        | -         | 
-^ long          |  -      |  -        -       | <native>  |  (2)       |  (3)      | +^ bool          |  -       | <native> | <native> | Yes (1)    Yes (1)  |  Yes (5)  
-^ double        |  -      |  -        -       | Yes       | <native>   |  (4)      | +^ long          |  -       |  -        -       | <native>  |  (2)      |  (3)      | 
-^ string        |  -      |  -        -       | Yes        Yes       | <native>  |+^ double        |  -       |  -        -       | Yes       | <native>  |  (4)      | 
 +^ string        |  -       |  -        -       | Yes        Yes      | <native>  |
  
   * (1) false if null, true if non null   * (1) false if null, true if non null
Line 89: Line 91:
   * (3) Run string through is_numeric_str_function() and detect error. If double with null fractional part returned, convert to long, else error   * (3) Run string through is_numeric_str_function() and detect error. If double with null fractional part returned, convert to long, else error
   * (4) Run string through is_numeric_str_function() and detect error. If int returned, convert to double   * (4) Run string through is_numeric_str_function() and detect error. If int returned, convert to double
 +  * (5) If string is numeric and contains a representation of a null number (anything that would convert to 0 or 0.0), or if string is empty, -> false, otherwise -> true.
  
 and the new behavior of _is_numeric_string_ex() : and the new behavior of _is_numeric_string_ex() :
Line 97: Line 100:
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
  
-Every restriction of the ruleset causes a BC break.+Every change we propose here is a BC break.
  
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
  
-Because of BC breaks, requires a major version, so 7.0.+7.0.
  
 ===== RFC Impact ===== ===== RFC Impact =====
Line 108: Line 111:
  
 Any code converting a string to a number is potentially impacted. If this cause Any code converting a string to a number is potentially impacted. If this cause
-an unacceptable BC break, we'll create a private copy of this function specific +an unacceptable BC break, we'll create a private copy of the function implemeneting 
-for argument parsing. As long as it is not needed, it is better if every string to +(string -> int/float) and will reserve it for ZPP. As long as it is not clearly needed, 
-numeric conversion uses the same code.+we'll keep a common code for every string to number conversions in PHP.
  
 ==== To Opcache ==== ==== To Opcache ====
Line 121: Line 124:
  
 ==== php.ini Defaults ==== ==== php.ini Defaults ====
- 
-None 
  
 ===== Open Issues ===== ===== Open Issues =====
- 
-Coming soon... 
  
 ===== Unaffected PHP Functionality ===== ===== Unaffected PHP Functionality =====
Line 132: Line 131:
 ===== Future Scope ===== ===== Future Scope =====
  
-The set of supported numeric strings can be extended. +String to numeric conversion can be improved and accept a richer syntax.
- +
-String to numeric conversion can be made smarter and accept more.+
  
 ===== Proposed Voting Choices ===== ===== Proposed Voting Choices =====
rfc/zpp-conversion-rules.1424376649.txt.gz · Last modified: 2017/09/22 13:28 (external edit)