rfc:zpp_improv
no way to compare when less than two revisions

Differences

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


Previous revision
Next revision
rfc:zpp_improv [2013/01/16 22:33] – [Changelog] cataphract
Line 1: Line 1:
 +====== Request for Comments: zend_parse_parameters() improvements ======
 +  * Version: 1.0
 +  * Date: 2013-01-02
 +  * Author: Gustavo Lopes <cataphract@php.net>
 +  * Status: Under Discussion
 +  * First Published at: https://wiki.php.net/rfc/zpp_improv
 +
 +
 +Proposes two improvements to ''zend_parse_parameters()'': allow ''!'' for non pointer types and expose ''zend_parse_arg()'' as ''zend_parse_parameter()''.
 +
 +===== Introduction =====
 +
 +The native function ''zend_parse_parameters()'' (henceforth zpp) is used by internal PHP functions to parse the function arguments into native types or to merely extract the zvals from the stack. It's a variadic function that takes a format string and a matching list of pointers that serve as output parameters.
 +
 +The conversions that zpp does to transform the passed zvals into native types are not trivial. For instance, it can convert a string into a "long", but not all strings will be accepted and some will be accepted but will emit a warning. As many variables end up at some point as arguments to internal functions, the behavior of zpp ends affecting how PHP's users perceive PHP's type system to work. Consequently, consistency in internal function parameter parsing is highly desirable. As zpp behavior is not trivial, achieving such consistency depends on PHP internal functions' implementations using zpp correctly.
 +
 +Unfortunately, zpp is also inflexible. One is restricted to a single format string, which makes implementing overloads difficult. Common solutions include calling zpp quietly several times until it succeeds (signaling a correct set of arguments) and fetching the zvals without conversion, following with explicit conversions (hopefully with convert_to_xx_ex(), not simply convert_to_xx()). These can cause several problems -- confusing error messages (or absence of them) and unanticipated side effects of failed zpp calls (which change the arguments directly in the stack, as part as the conversion procedure, until it finds a failing condition) in the first case, and using casting behavior instead of zpp behavior in the second case (convert_to_int_ex() will happily and silently convert a resource into an integer).  
 +
 +===== Expose zend_parse_arg() as zend_parse_parameter() =====
 +
 +<code>int zend_parse_parameter(int flags, int arg_num TSRMLS_DC, zval **arg, const char *spec, ...)</code>
 +
 +Exposing ''zend_parse_arg()'' as ''zend_parse_parameter()'' is the first change. It allows one to do type conversions with zpp-like semantics. These are specially useful in scenarios where a parameter may take several scalar types. For instance, one may want to accept an arbitrary number of integers (which we want to parse with zpp semantics) and expect them in an array, perhaps even also allowing a bare integer too; one may want to accept something that will be used as an array key (which can be either and int or a string);
 +one may want to accept integer and double numbers. A search for IS_LONG reveals many situations where this need arises.
 +
 +===== Allow ! for non pointers =====
 +
 +<code>
 +long l;
 +zend_bool is_null;
 +zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!", &l, &is_null)
 +</code>
 +
 +Allowing ''!'' for non pointer types ''l''/''L'', ''d'' and ''b'' through an extra output pointer is the second change.
 +
 +For the specifiers ''l''/''L'', ''d'' and ''b'', ''NULL'' values are reported as ''0'', ''0.'', or ''false''. But sometimes one wants to distinguish ''NULL'' from those other values -- for instance, to give ''NULL'' the same effect as the argument
 +not having been passed.
 +
 +Currently, the only way to otherwise have zpp semantics (without duplicating its logic) is to fetch the raw zval from the stack and check whether it's ''NULL'' (with zpp itself or its relatives) and then run zpp again. That is not an elegant solution.
 +
 +Since this came up in the discussion: this change is only marginally related to "skipped parameters proposal" and no one preempts (or even makes significantly less useful) the other. If you want to bring this up on the list, please make sure you have read carefully these two posts: [[http://grokbase.com/p/php/php-internals/127k3r5ppj/php-dev-zend-parse-parameters-improvements|post one]] and [[http://grokbase.com/p/php/php-internals/127nwx6h2y/php-dev-zend-parse-parameters-improvements|post two]].
 +
 +===== Proposal and Patch =====
 +
 +The patch is available as a [[https://github.com/cataphract/php-src/compare/zpp_improv|branch]] on github.
 +
 +===== Mailing list discussion =====
 +
 +The mailing list discussion is available [[http://grokbase.com/p/php/php-internals/127j49y02w/zend-parse-parameters-improvements|here]].
 +
 +===== Voting =====
 +
 +Voting ends not before Wednesday, January 16th 2013. The PHP language is not changed, so a 50%+1 majority is required.
 +
 +<doodle title="Accept these improvements for PHP 5.5?" auth="cataphract" voteType="single" closed="true">
 +   * Yes
 +   * No
 +</doodle>
 +
 +===== Changelog =====
 +
 +* 2013-01-02: Initial revision
 +* 2013-01-09: Opened voting
 +* 2013-01-16: Closed voting
  
rfc/zpp_improv.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1