rfc:var_type

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:var_type [2016/06/25 15:23] – Fixed date fleshgrinderrfc:var_type [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== PHP RFC: var_type ====== ====== PHP RFC: var_type ======
-  * Version: 0.0+  * Version: 1.0
   * Date: 2016-06-25   * Date: 2016-06-25
   * Author: Richard Fussenegger <php@fleshgrinder.com>   * Author: Richard Fussenegger <php@fleshgrinder.com>
-  * Status: Under Discussion+  * Status: Declined
   * First Published at: https://wiki.php.net/rfc/var_type   * First Published at: https://wiki.php.net/rfc/var_type
  
Line 57: Line 57:
 <code php> <code php>
 /** /**
- * Get the type of a variable.+ * Get the type of a variable’s current value.
  *  *
  * The returned value is a string that corresponds to one of the `TYPE_*`  * The returned value is a string that corresponds to one of the `TYPE_*`
Line 75: Line 75:
  * is encountered.  * is encountered.
  *  *
- * ## Differences to Other Variable Functions+ * ## Differences to Other Functions
  * This function will return `TYPE_OBJECT` for incomplete objects (refer  * This function will return `TYPE_OBJECT` for incomplete objects (refer
  * to {@see unserialize}) whereas {@see is_object} returns **FALSE**.  * to {@see unserialize}) whereas {@see is_object} returns **FALSE**.
Line 84: Line 84:
  * The same is true for {@see is_resource} which returns **FALSE** for  * The same is true for {@see is_resource} which returns **FALSE** for
  * invalid or unknown resource types ({@see get_resource_type}) while  * invalid or unknown resource types ({@see get_resource_type}) while
- _typeof_ returns `TYPE_RESOURCE` for the same reason as above.+ _var_type_ returns `TYPE_RESOURCE` for the same reason as above.
  *  *
  * These differences also illustrate the different purposes of them.  * These differences also illustrate the different purposes of them.
  * Functions like {@see is_object} and {@see is_resource} are meant for  * Functions like {@see is_object} and {@see is_resource} are meant for
  * validating if a given variable is of a legal type that can be used to  * validating if a given variable is of a legal type that can be used to
- * work with. The result of _typeof_ is meant for debugging purposes and+ * work with. The result of _var_type_ is meant for debugging purposes and
  * not type checks. Hence, conditions like  * not type checks. Hence, conditions like
- * `if (typeof($var) === TYPE_RESOURCE)` are not encouraged and better+ * `if (var_type($var) === TYPE_RESOURCE)` are not encouraged and better
  * replaced with `if (is_resource($var))`.  * replaced with `if (is_resource($var))`.
  *  *
Line 105: Line 105:
  
 <code php> <code php>
-echo typeof([]);           // array +echo var_type([]);           // array 
-echo typeof(true);         // bool +echo var_type(true);         // bool 
-echo typeof(0.0);          // float +echo var_type(0.0);          // float 
-echo typeof(0);            // int +echo var_type(0);            // int 
-echo typeof(null);         // null +echo var_type(null);         // null 
-echo typeof(new stdClass); // object +echo var_type(new stdClass); // object 
-echo typeof(STDIN);        // resource +echo var_type(STDIN);        // resource 
-echo typeof('');           // string+echo var_type('');           // string
  
 $fh = tmpfile(); $fh = tmpfile();
 fclose($fh); fclose($fh);
-echo typeof($fh);          // resource+echo var_type($fh);          // resource
 </code> </code>
  
-=== Differences to Other Variable Functions ===+=== Differences to Other Functions ===
 The ''var_type()'' function returns ''object'' for incomplete objects which are an instance of ''__PHP_Incomplete_Class'' (see [[https://secure.php.net/unserialize|unserialize()]]), whereas ''is_object()'' returns **FALSE**. The same is true for resources of unknown resource type where ''is_resource()'' returns **FALSE**. The reason for this difference is simple: these functions serve different purposes. The ''is_*'' functions are meant for flow control and validation, while the ''var_type()'' function is meant to retrieve type information in string form for later usage. In other words, it is not encouraged nor was it ever encouraged to implement something like ''if (var_type($var) === 'resource')''. The idiomatic way to perform this kind of check is ''if (is_resource($var))''. Consistency between these functions, in this regard, is not desirable because it makes it unclear to users when to use which function, as was already mentioned earlier. The ''var_type()'' function returns ''object'' for incomplete objects which are an instance of ''__PHP_Incomplete_Class'' (see [[https://secure.php.net/unserialize|unserialize()]]), whereas ''is_object()'' returns **FALSE**. The same is true for resources of unknown resource type where ''is_resource()'' returns **FALSE**. The reason for this difference is simple: these functions serve different purposes. The ''is_*'' functions are meant for flow control and validation, while the ''var_type()'' function is meant to retrieve type information in string form for later usage. In other words, it is not encouraged nor was it ever encouraged to implement something like ''if (var_type($var) === 'resource')''. The idiomatic way to perform this kind of check is ''if (is_resource($var))''. Consistency between these functions, in this regard, is not desirable because it makes it unclear to users when to use which function, as was already mentioned earlier.
  
Line 126: Line 126:
 === Unknown Type === === Unknown Type ===
 There is still a default path in the C code that would result in the returned type being ''unknown''. This happens if none of the existing type checks available in C results in a positive check. In other words: this should never happen. The documentation above clearly states that this is actually an impossible situation, and encourages users to file a bug with a detailed description for us to account for it, if they manage to provoke such a situation. There is still a default path in the C code that would result in the returned type being ''unknown''. This happens if none of the existing type checks available in C results in a positive check. In other words: this should never happen. The documentation above clearly states that this is actually an impossible situation, and encourages users to file a bug with a detailed description for us to account for it, if they manage to provoke such a situation.
 +
 +==== Prefix Choice ====
 +The function prefix ''var_'' was chosen on purpose because another possibly more suitable prefix like ''val_'' or ''value_'' would introduce a new prefix to the PHP ecosystem. It is true that this function can be used with the return value of functions too as well as with literal values, however, exactly the same argument is true for ''var_dump()'' and ''var_export()''. The goal of this RFC is it to improve consistency and not to introduce more inconsistencies. The assumption that the type of a variable is the type of its current value is furthermore logical and comprehensible. Last but not least, this function is probably not going to be used with literal values at all, since the type of them is definitely known to the developer writing the code. It might be used for return values of functions but the use cases seem very, very limited without storing the actual value to a variable first.
 +
 +==== Performance ====
 +The new ''​var_type()''​ function is faster if full utilization of interned strings is possible because it can utilize globally cached strings for the type names. It makes no sense to optimize the old ''gettype()'' function in the same manner since caching of the old type names makes no sense, they are not useful in any other context and would occupy additional memory globally for a single function.
 +
 +Note well that the various ''is_*'' functions are still faster and ''var_type()'' is not meant to compete with them, again, they serve different purposes.
  
 ==== Phasing Out of gettype ==== ==== Phasing Out of gettype ====
-This RFC does **not** propose a deprecation of ''gettype()'' in PHP 7.x because it is a widely used function and there are currently no plans on how to deal with its counterpart ''settype()''. However, a //soft deprecation// of ''gettype()'' is recommended, this means that the documentation page of ''gettype()'' will be updated with an informational box that recommends the usage of ''var_type()'' in favor of ''gettype()'' and any references to ''gettype()'' in the manual should be replaced with ''var_type()''.+This RFC does **not** propose a deprecation of ''gettype()'' in PHP 7.x because it is a widely used function and there are currently no plans on how to deal with its counterpart ''settype()''Even if there would be plans, a true deprecation of ''gettype()'' would be a bad idea in any context because libraries and applications need the ability to offer their users an upgrade path. This path would be very bumpy if PHP is emitting deprecation errors upon the usage of ''gettype()''. Such a library or application fallback might be necessary in situations like we see [[https://github.com/doctrine/annotations/blob/master/lib/Doctrine/Common/Annotations/DocParser.php#L756-L789|here it in Doctrine annotations]]. The solution for such situations would be something like: 
 + 
 +<code php> 
 +if ((var_type($var) === $user_type || gettype($var) === $user_type) || $var instanceof $user_type) { 
 +    // ... 
 +
 +</code> 
 + 
 +However, a //soft deprecation// of ''gettype()'' is recommended, this means that the documentation page of ''gettype()'' will be updated with an informational box that recommends the usage of ''var_type()'' in favor of ''gettype()'' and any references to ''gettype()'' in the manual should be replaced with ''var_type()''
 + 
 +It is further recommended to tackle the deprecation and a possible removal of the ''gettype()'' function together with a proper solution for ''settype()'' in a future major release. A possible approach could be to emit an ''E_STRICT'' in PHP 8, deprecate in PHP 9, and remove in PHP 10; or any other combination that results in a long adoption period.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 147: Line 165:
  
 ==== New Constants ==== ==== New Constants ====
-The introduction of ''TYPE_*'' constants for the various data types of PHP is a logical additional extension to minimize magic strings in userland software an to avoid typos that might lead to bugs. That being said, the existence of these constants is not essential to this feature and has a separate voting poll.+The introduction of ''TYPE_*'' constants for the various data types of PHP is a logical additional extension to minimize magic strings in userland software an to avoid typos that might lead to bugs. That being said, the existence of these constants is not essential to this feature and has a separate voting poll. Note that the usage of the constants within an e.g. ''switch'' actually makes the code slower due to the additional look ups for these constants. Their usage is only of interest to remove magic strings from userland code and improve the design of software in general.
  
 <code php> <code php>
Line 170: Line 188:
  */  */
 const TYPE_CALLABLE = 'callable'; const TYPE_CALLABLE = 'callable';
- 
-/** 
- * Name of the regular scalar data type bool's negative value. 
- * 
- * @link https://secure.php.net/language.types.boolean 
- */ 
-const TYPE_FALSE = 'false'; 
  
 /** /**
Line 191: Line 202:
  */  */
 const TYPE_INT = 'int'; const TYPE_INT = 'int';
 +
 +/**
 + * Name of the pseudo data type iterable.
 + *
 + * @link https://secure.php.net/language.types.iterable
 + */
 +const TYPE_ITERABLE = 'iterable';
  
 /** /**
Line 219: Line 237:
  */  */
 const TYPE_STRING = 'string'; const TYPE_STRING = 'string';
- 
-/** 
- * Name of the regular scalar data type bool's positive value. 
- * 
- * @link https://secure.php.net/language.types.boolean 
- */ 
-const TYPE_TRUE = 'true'; 
 </code> </code>
  
Line 243: Line 254:
 ===== Future Scope ===== ===== Future Scope =====
 ==== Userland ==== ==== Userland ====
-  * New ''var_info()'' function that returns a human readable explanation of the variable in plain English for inclusion in error messages.+  * New ''[[rfc:var_info|var_info()]]'' function that returns a human readable explanation of the variable in plain English for inclusion in error messages.
   * New ''resource_is_closed()'' function that allows direct checks whether a resource is closed/invalid to avoid constructs like:<code php>   * New ''resource_is_closed()'' function that allows direct checks whether a resource is closed/invalid to avoid constructs like:<code php>
 if (is_resource($var) === false && var_type($var) === 'resource') { if (is_resource($var) === false && var_type($var) === 'resource') {
Line 258: Line 269:
 ===== Proposed Voting Choices ===== ===== Proposed Voting Choices =====
 This RFC will have two polls, one for the introduction of the ''var_type()'' function and one for the new ''TYPE_*'' constants in userland. Both require a 50%+1 majority to be accepted as they do not change the language's syntax. This RFC will have two polls, one for the introduction of the ''var_type()'' function and one for the new ''TYPE_*'' constants in userland. Both require a 50%+1 majority to be accepted as they do not change the language's syntax.
 +
 +Voting opened on 2016-07-08 and will end on 2016-07-22 for both votes.
 +
 +== Function ==
 +<doodle title="Accept var_type function?" auth="fleshgrinder" voteType="single" closed="false">
 +   * Yes
 +   * No
 +</doodle>
 +
 +== Constants ==
 +<doodle title="Accept type constants?" auth="fleshgrinder" voteType="single" closed="true">
 +   * Yes
 +   * No
 +</doodle>
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
 The [[https://github.com/php/php-src/pull/1935|GitHub Pull Request #1935]] contains the implementation as well as tests for the new function. The changes in the PR are considered final, however, a thorough code review would be much appreciated and might result in minor changes. The [[https://github.com/php/php-src/pull/1935|GitHub Pull Request #1935]] contains the implementation as well as tests for the new function. The changes in the PR are considered final, however, a thorough code review would be much appreciated and might result in minor changes.
- 
-===== Implementation ===== 
-  - Merged to Version: //?// 
-  - Git Commits: //?// 
-  - PHP Manual: https://secure.php.net/var_type 
  
 ===== References ===== ===== References =====
rfc/var_type.1466868225.txt.gz · Last modified: 2017/09/22 13:28 (external edit)