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/18 19:21] francoisrfc:zpp-conversion-rules [2021/03/27 14:25] (current) – Move to inactive ilutov
Line 1: Line 1:
 +====== PHP RFC: Type parsing modifications ======
 +  * Version: 0.4
 +  * Date: 2015-02-22
 +  * Author: François Laupretre, francois@php.net
 +  * Status: Inactive
 +  * First Published at: https://wiki.php.net/rfc/zpp-conversion-rules
  
-Current :+ 
 +===== Introduction ===== 
 + 
 +This RFC proposes changes in the ruleset used to filter 
 +and convert input arguments to internal functions. 
 + 
 +===== History ===== 
 + 
 +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]]. 
 + 
 +While the discussion mostly opposed 'weak' and 'strict' mode proponents, 
 +each camp showing use cases to prove it was right, we decided to gather all these use cases 
 +and go exploring another way : search a single-mode compromise that would satisfy both camps.  
 + 
 +It was soon clear that the strongest argument of strict-typing proponents was that 
 +'weak' mode was way too permissive, allowing, for instance, true or '7 years' as integer value. 
 + 
 +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 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 ruleset, these mechanisms must keep implementing the same logic. 
 + 
 +===== Proposal ===== 
 + 
 +==== Current ruleset ==== 
 + 
 +The ZPP ruleset authorizes implicit conversions for IS_NULL, IS_FALSE, 
 +IS_TRUE, IS_LONG, IS_DOUBLE, and IS_STRING zval types only. 
 + 
 +Actually, it also implement a mechanism for (object -> string) but, as this one 
 +will remain unchanged, it will be ignored here. 
 + 
 +The following table shows the current rules used to accept and convert an input zval through 
 +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>  |
  
   * (1) false if null, true if non null   * (1) false if null, true if non null
Line 13: 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
  
-is_numeric_str_function() behavior :+The conversion of IS_STRING to int/float is done through _is_numeric_string_ex()
 +Among others, this function has the following behavior :
  
-  * Skip leading spaces +  * Stop conversion at first non digit character with no error (ignore every trailing char).
-  * Stop conversion at first non digit character with no error+
  
 +==== Proposed changes ====
  
-Future :+  * Disable IS_FALSE/IS_NULL to anything except 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 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. 
 +  * 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() : 
 + 
 +  * Add a check for trailing characters : trailing blanks are accepted, the first non-blank character encountered raises an error (note that blanks are supported as leading or trailing chars only). 
 +   
 +==== Future ruleset ==== 
 + 
 +This table shows a synthetic view of the resulting ruleset ('-' means 'Disabled'):
  
 ^            ^  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 ^ 
-^ null          |  Yes    |  No       No     | No        |  No         No       +^ null          | <native> |  -              | -         |         -         
-^ bool          |  No      Native   Native | Yes (1)    Yes (1)   |  No       | +^ bool          |  -       <native> <native> | Yes (1)    Yes (1)  |  Yes (5)  | 
-^ strict_bool   |  No      Native  |  Native | No        |  No        |  No       +^ long          |  -       |  -       |  -       <native>  |  (2)      |  (3)      | 
-^ long          |  No     |  No      |  No     Native    |  (2)       |  (3)      | +double        |        |  -       |  -       | Yes       <native>   (4)      | 
-strict_long    No      No      |  No     | Native    |  No        |  No       +string        |  -       |        |  -       | Yes        Yes      | <native>  |
-^ double        |  No     |  No      |  No     | Yes       |  Native    |  (4)      | +
-strict_double |  No      No      |  No     | No        |  Native    |  No       +
-^ string        |  No      No      |  No     | Yes        Yes       |  Native   | +
-^ strict_string |  No      No      |  No     | No        |  No        |  Native   |+
  
   * (1) false if null, true if non null   * (1) false if null, true if non null
Line 38: 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() :
 +
 +  * Ignore trailing blanks
 +  * Error on any non-blank trailing char
 +
 +===== Backward Incompatible Changes =====
 +
 +Every change we propose here is a BC break.
 +
 +===== Proposed PHP Version(s) =====
 +
 +7.0.
 +
 +===== RFC Impact =====
 +
 +Every internal functions are potentially impacted.
 +
 +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 the function implemeneting
 +(string -> int/float) and will reserve it for ZPP. As long as it is not clearly needed,
 +we'll keep a common code for every string to number conversions in PHP.
 +
 +==== To Opcache ====
 +
 +None
 +
 +==== New Constants ====
 +
 +None
 +
 +==== php.ini Defaults ====
 +
 +===== Open Issues =====
 +
 +===== Unaffected PHP Functionality =====
 +
 +===== Future Scope =====
 +
 +String to numeric conversion can be improved and accept a richer syntax.
 +
 +===== Proposed Voting Choices =====
 +
 +Requires a 2/3 majority.
 +
 +Vote will be a single-choice yes/no vote.
 +
 +Voting date is not planned yet.
 +
 +===== Patches and Tests =====
 +
 +Work in progress.
 +
 +As soon as patch is available, extensive testing must be performed to evaluate
 +overall BC breaks.
 +
 +===== Implementation =====
 +After the project is implemented, this section should contain 
 +  - the version(s) it was merged to
 +  - a link to the git commit(s)
 +  - a link to the PHP manual entry for the feature
  
-is_numeric_str_function() behavior :+===== References =====
  
-  * Skip leading spaces +===== Rejected Features ===== 
-  * Ignore trailing spaces +Keep this updated with features that were discussed on the mail lists.
-  * Error on non-blank trailing chars+
  
rfc/zpp-conversion-rules.1424287289.txt.gz · Last modified: 2017/09/22 13:28 (external edit)