rfc:parameter_type_casting_hints

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
rfc:parameter_type_casting_hints [2012/03/04 00:40]
ircmaxell [Philosophy]
rfc:parameter_type_casting_hints [2017/09/22 13:28] (current)
Line 3: Line 3:
   * Date: 2012-03-03   * Date: 2012-03-03
   * Author: Anthony Ferrara <ircmaxell@php.net>   * Author: Anthony Ferrara <ircmaxell@php.net>
-  * Status: In Draft+  * Status: Withdrawn
   * First Published at: https://wiki.php.net/rfc/parameter_type_casting_hints   * First Published at: https://wiki.php.net/rfc/parameter_type_casting_hints
   * Patch: https://gist.github.com/1963999   * Patch: https://gist.github.com/1963999
Line 14: Line 14:
  
 This RFC discusses a method of adding scalar type hints to PHP while attempting to embrace the dynamic nature of PHP variables.  This means that passing a type that does not match the hinted type will cause a cast to happen (if possible, based on the normal type-casting rules used in other areas of the engine).   This RFC discusses a method of adding scalar type hints to PHP while attempting to embrace the dynamic nature of PHP variables.  This means that passing a type that does not match the hinted type will cause a cast to happen (if possible, based on the normal type-casting rules used in other areas of the engine).  
-==== More ==== 
  
-===== Changelog =====+It's worth noting that this RFC does not attempt to add new errors to the casting paradigm in PHP.  It's my feeling that issuing errors (E_NOTICE or E_STRICT) on data-loss from cast operations is important, but a more general issue to PHP.  So as such it does not fall under this specific RFC, but as a more general RFC which can be added to the language as a whole.
  
 +So in an attempt at consistency, this RFC uses the normal [[http://us3.php.net/manual/en/language.types.type-juggling.php|Type Juggling Rules]] that the rest of the engine uses for casting operations.
  
 +===== Implementation =====
 +
 +==== Syntax ==== 
 +
 +The parameters are type hinted using the following syntax:
 +
 +<?php
 +
 +    function test((int) $intParam, (string) $strParam = "foo", (array) $array = array()) {}
 +
 +?>
 +
 +This will cause the following function to always return true for almost any combination of parameters:
 +
 +<?php
 +
 +    function test((int) $int, (float) $float, (bool) $bool, (string) $string) {
 +        return is_int($int) && is_float($float) && is_bool($bool) && is_string($string);
 +    }
 +
 +?>
 +
 +The one exception which will cause the function to not return true, is when the ''$string'' parameter is an object which does not implement __toString, which therefore will throw a Catchable fatal error on conversion to string.  This is the default casting behavior for strings.
 +
 +==== Cast Options ====
 +
 +The following cast types are supported as parameter casts:
 +
 +  * ''(int)'' - Cast to an integer (if not already)
 +  * ''(float)'' - Cast to a float (if not already)
 +  * ''(bool)'' - Cast to a boolean (if not already)
 +  * ''(string)'' - Cast to a string (if not already)
 +  * ''(array)'' - Cast to an array (if not already)
 +  * ''(object)'' - Cast to an object (if not already)
 +
 +Note that the final 2 options (array and object) are there for both completeness, and to provide a less-strict type-hint (to be consistent with the new additions).
 +
 +==== Default Values ==== 
 +
 +For consistency, only matching types are allowed to be the default to a type-casted parameter.  So ''(int) $foo = null'' and ''(int) $foo = 1'' are both supported, but ''(int) $foo = "1"'' will generate an ''E_COMPILE_ERROR''.
 +
 +If ''null'' is not the default value, any attempt to pass ''null'' to a function which has a casting type hint will cause a cast from null to occur.  If ''null'' is the default value for the parameter, passing ''null'' will not trigger a cast.  So:
 +
 +    function test1((int) $foo) { echo gettype($foo); }
 +    function test2((int) $foo = null) { echo gettype($foo); }
 +    
 +Calling ''test1(null)'' will produce ''int'' as the output.  Calling ''test2(null)'' will produce ''null'' as the output.
 +
 +==== Backwards compatibility breaks ====
 +
 +This patch does not break existing functionality (with one exception of a C level API change that is not a public API).  Current code will execute as normal.
 +
 +===== Patch Details =====
 +
 +==== Cast Type Definitions ====
 +
 +The patch adds a series of "cast" definitions to the C type constants currently in use by the core.  They are implemented in a way that the destination type of the cast can be found by masking the cast against 0x0F.  They are:
 +
 +  * ''IS_NULL_CAST 0x010''
 +  * ''IS_LONG_CAST 0x011''
 +  * ''IS_DOUBLE_CAST 0x012''
 +  * ''IS_BOOL_CAST 0x013''
 +  * ''IS_ARRAY_CAST 0x014''
 +  * ''IS_OBJECT_CAST 0x015''
 +  * ''IS_STRING_CAST 0x016''
 +
 +These are used to distinguish casting declarations in OPCode from a possible future implementation of more strict casts.  
 +
 +These have also been added to the ''zend_get_type_by_const()'' function to return the cast string that would be used.
 +==== API Changes ==== 
 +
 +One API change was necessary for the cast to work.  The third paramater of ''zend_verify_arg_type'' was changed from a single pointer zval, to a double pointer zval.  This allows the argument to be separated if the cast happens and a copy-on-write event to be triggered.  All implementations of this function in trunk have been updated (only occurs in the Zend directory).
 +
 +==== References ====
 +
 +To prevent odd behavior, it is a ''E_COMPILE_ERROR'' to define a parameter as both cast-hinted and a reference.  This prevents issues where passing a variable to a function by reference changes the type of the original argument and possibly destroys data in the original variable.
 +
 +==== Parser Tokens ====
 +
 +No new parser tokens or reserved words are created by this RFC / implementation.
 +
 +===== Changelog =====
rfc/parameter_type_casting_hints.1330821601.txt.gz · Last modified: 2017/09/22 13:28 (external edit)