summaryrefslogtreecommitdiff
path: root/docs/parameter-parsing-api.md
diff options
context:
space:
mode:
authorPeter Kokot <peterkokot@gmail.com>2019-04-21 15:33:20 +0200
committerPeter Kokot <peterkokot@gmail.com>2019-04-21 15:33:20 +0200
commit1c94aac89e0d7dfbd5efc15ec1862214b22603d1 (patch)
treed03f294d1354b121d5f8bf0daa681f92c750bed1 /docs/parameter-parsing-api.md
parent80f3c69ae925b09068b0642306a8a14a42c7d25c (diff)
downloadphp-git-1c94aac89e0d7dfbd5efc15ec1862214b22603d1.tar.gz
[ci skip] Fix CS in Markdown files
Checked and quickfixed with Markdown linter - 80 columns line width (~) - code highlighting - ... Some most obvious outdated content updated a bit more.
Diffstat (limited to 'docs/parameter-parsing-api.md')
-rw-r--r--docs/parameter-parsing-api.md210
1 files changed, 106 insertions, 104 deletions
diff --git a/docs/parameter-parsing-api.md b/docs/parameter-parsing-api.md
index f65c19a723..d4d24b1dbf 100644
--- a/docs/parameter-parsing-api.md
+++ b/docs/parameter-parsing-api.md
@@ -1,133 +1,140 @@
-Fast Parameter Parsing API
-==========================
+# Fast Parameter Parsing API
-In PHP 7, a "Fast Parameter Parsing API" was introduced. See
+In PHP 7, a "Fast Parameter Parsing API" was introduced. See
+[RFC](https://wiki.php.net/rfc/fast_zpp).
- https://wiki.php.net/rfc/fast_zpp
+This API uses inlining to improve applications performance compared with the
+`zend_parse_parameters()` function described below.
-This API uses inlining to improve applications performance compared
-with the zend_parse_parameters() function described below.
+## Parameter parsing functions
+Borrowing from Python's example, there is a set of functions that given the
+string of type specifiers, can parse the input parameters and store the results
+in the user specified variables. This avoids using `IS_*` checks and
+`convert_to_*` conversions. The functions also check for the appropriate number
+of parameters, and try to output meaningful error messages.
-Parameter parsing functions
-===========================
+## Prototypes
-Borrowing from Python's example, there is a set of functions that
-given the string of type specifiers, can parse the input parameters
-and store the results in the user specified variables. This avoids
-using IS_* checks and convert_to_* conversions. The functions also
-check for the appropriate number of parameters, and try to output
-meaningful error messages.
-
-
-Prototypes
-----------
+```c
/* Implemented. */
int zend_parse_parameters(int num_args, char *type_spec, ...);
int zend_parse_parameters_ex(int flags, int num_args, char *type_spec, ...);
+```
-The zend_parse_parameters() function takes the number of parameters
-passed to the extension function, the type specifier string, and the
-list of pointers to variables to store the results in. The _ex() version
-also takes 'flags' argument -- current only ZEND_PARSE_PARAMS_QUIET can
-be used as 'flags' to specify that the function should operate quietly
-and not output any error messages.
+The `zend_parse_parameters()` function takes the number of parameters passed to
+the extension function, the type specifier string, and the list of pointers to
+variables to store the results in. The _ex() version also takes 'flags' argument
+-- current only `ZEND_PARSE_PARAMS_QUIET` can be used as 'flags' to specify that
+the function should operate quietly and not output any error messages.
-Both functions return SUCCESS or FAILURE depending on the result.
+Both functions return `SUCCESS` or `FAILURE` depending on the result.
-The auto-conversions are performed as necessary. Arrays, objects, and
-resources cannot be auto-converted.
+The auto-conversions are performed as necessary. Arrays, objects, and resources
+cannot be auto-converted.
PHP 5.3 includes a new function (actually implemented as macro):
+```c
int zend_parse_parameters_none();
+```
-This returns SUCCESS if no argument has been passed to the function,
-FAILURE otherwise.
+This returns `SUCCESS` if no argument has been passed to the function, `FAILURE`
+otherwise.
PHP 5.5 includes a new function:
+```c
int zend_parse_parameter(int flags, int arg_num, zval **arg, const char *spec, ...);
+```
-This function behaves like zend_parse_parameters_ex() except that instead of
+This function behaves like `zend_parse_parameters_ex()` except that instead of
reading the arguments from the stack, it receives a single zval to convert
(passed with double indirection). The passed zval may be changed in place as
part of the conversion process.
-See also https://wiki.php.net/rfc/zpp_improv#expose_zend_parse_arg_as_zend_parse_parameter
-
-
-Type specifiers
----------------
- The following list shows the type specifier, its meaning and the parameter
- types that need to be passed by address. All passed parameters are set
- if the PHP parameter is non optional and untouched if optional and the
- parameter is not present. The only exception is O where the zend_class_entry*
- has to be provided on input and is used to verify the PHP parameter is an
- instance of that class.
-
- a - array (zval*)
- A - array or object (zval*)
- b - boolean (zend_bool)
- C - class (zend_class_entry*)
- d - double (double)
- f - function or array containing php method call info (returned as
- zend_fcall_info and zend_fcall_info_cache)
- h - array (returned as HashTable*)
- H - array or HASH_OF(object) (returned as HashTable*)
- l - long (zend_long)
- L - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (zend_long, ZEND_LONG_MAX/ZEND_LONG_MIN)
- o - object of any type (zval*)
- O - object of specific type given by class entry (zval*, zend_class_entry)
- p - valid path (string without null bytes in the middle) and its length (char*, size_t)
- P - valid path (string without null bytes in the middle) as zend_string (zend_string*)
- r - resource (zval*)
- s - string (with possible null bytes) and its length (char*, size_t)
- S - string (with possible null bytes) as zend_string (zend_string*)
- z - the actual zval (zval*)
- * - variable arguments list (0 or more)
- + - variable arguments list (1 or more)
-
- The following characters also have a meaning in the specifier string:
- | - indicates that the remaining parameters are optional, they
- should be initialized to default values by the extension since they
- will not be touched by the parsing function if they are not
- passed to it.
- / - use SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows
- ! - the parameter it follows can be of specified type or NULL. If NULL is
- passed and the output for such type is a pointer, then the output
- pointer is set to a native NULL pointer.
- For 'b', 'l' and 'd', an extra argument of type zend_bool* must be
- passed after the corresponding bool*, zend_long* or double* arguments,
- respectively. A non-zero value will be written to the zend_bool if a
- PHP NULL is passed.
-
-
-Note on 64bit compatibility
----------------------------
-Please note that since version 7 PHP uses zend_long as integer type and
-zend_string with size_t as length, so make sure you pass zend_longs to "l"
-and size_t to strings length (i.e. for "s" you need to pass char * and size_t),
-not the other way round!
+See also
+[Expose zend_parse_arg() as zend_parse_parameter()](https://wiki.php.net/rfc/zpp_improv#expose_zend_parse_arg_as_zend_parse_parameter).
+
+## Type specifiers
+
+The following list shows the type specifier, its meaning and the parameter types
+that need to be passed by address. All passed parameters are set if the PHP
+parameter is non optional and untouched if optional and the parameter is not
+present. The only exception is O where the zend_class_entry* has to be provided
+on input and is used to verify the PHP parameter is an instance of that class.
+
+```txt
+a - array (zval*)
+A - array or object (zval*)
+b - boolean (zend_bool)
+C - class (zend_class_entry*)
+d - double (double)
+f - function or array containing php method call info (returned as
+ zend_fcall_info and zend_fcall_info_cache)
+h - array (returned as HashTable*)
+H - array or HASH_OF(object) (returned as HashTable*)
+l - long (zend_long)
+L - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (zend_long, ZEND_LONG_MAX/ZEND_LONG_MIN)
+o - object of any type (zval*)
+O - object of specific type given by class entry (zval*, zend_class_entry)
+p - valid path (string without null bytes in the middle) and its length (char*, size_t)
+P - valid path (string without null bytes in the middle) as zend_string (zend_string*)
+r - resource (zval*)
+s - string (with possible null bytes) and its length (char*, size_t)
+S - string (with possible null bytes) as zend_string (zend_string*)
+z - the actual zval (zval*)
+* - variable arguments list (0 or more)
++ - variable arguments list (1 or more)
+```
+
+The following characters also have a meaning in the specifier string:
+
+* `|` - indicates that the remaining parameters are optional, they should be
+ initialized to default values by the extension since they will not be touched
+ by the parsing function if they are not passed to it.
+* `/` - use SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows
+* `!` - the parameter it follows can be of specified type or NULL. If NULL is
+ passed and the output for such type is a pointer, then the output pointer is
+ set to a native NULL pointer. For 'b', 'l' and 'd', an extra argument of type
+ zend_bool* must be passed after the corresponding bool*, zend_long* or
+ double* arguments, respectively. A non-zero value will be written to the
+ zend_bool if a PHP NULL is passed.
+
+## Note on 64bit compatibility
+
+Please note that since version 7 PHP uses `zend_long` as integer type and
+`zend_string` with `size_t` as length, so make sure you pass `zend_long`s to "l"
+and `size_t` to strings length (i.e. for "s" you need to pass char `*` and
+`size_t`), not the other way round!
Both mistakes might cause memory corruptions and segfaults:
-1)
- char *str;
- long str_len; /* XXX THIS IS WRONG!! Use size_t instead. */
- zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &str_len)
-2)
- int num; /* XXX THIS IS WRONG!! Use zend_long instead. */
- zend_parse_parameters(ZEND_NUM_ARGS(), "l", &num)
+* 1
+
+```c
+char *str;
+long str_len; /* XXX THIS IS WRONG!! Use size_t instead. */
+zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &str_len)
+```
+
+* 2
+
+```c
+int num; /* XXX THIS IS WRONG!! Use zend_long instead. */
+zend_parse_parameters(ZEND_NUM_ARGS(), "l", &num)
+```
-If you're in doubt, use check_parameters.php script to the parameters
-and their types (it can be found in ./scripts/dev/ directory of PHP sources):
+If you're in doubt, use check_parameters.php script to the parameters and their
+types (it can be found in `./scripts/dev/` directory of PHP sources):
-# php ./scripts/dev/check_parameters.php /path/to/your/sources/
+```bash
+php ./scripts/dev/check_parameters.php /path/to/your/sources/
+```
+## Examples
-Examples
---------
+```c
/* Gets a long, a string and its length, and a zval */
zend_long l;
char *s;
@@ -138,7 +145,6 @@ if (zend_parse_parameters(ZEND_NUM_ARGS(), "lsz",
return;
}
-
/* Gets an object of class specified by my_ce, and an optional double. */
zval *obj;
double d = 0.5;
@@ -148,7 +154,6 @@ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|d",
return;
}
-
/* Gets an object or null, and an array.
If null is passed for object, obj will be set to NULL. */
zval *obj;
@@ -158,7 +163,6 @@ if (zend_parse_parameters(ZEND_NUM_ARGS(), "o!a",
return;
}
-
/* Gets a separated array which can also be null. */
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/!",
@@ -171,7 +175,7 @@ zend_long l1, l2, l3;
char *s;
/*
* The function expects a pointer to a size_t in this case, not a long
- * or any other type. If you specify a type which is larger
+ * or any other type. If you specify a type which is larger
* than a 'size_t', the upper bits might not be initialized
* properly, leading to random crashes on platforms like
* Tru64 or Linux/Alpha.
@@ -190,13 +194,11 @@ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(),
return;
}
-
/* Function that accepts only varargs (0 or more) */
int i, num_varargs;
zval *varargs = NULL;
-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &varargs, &num_varargs) == FAILURE) {
return;
}
@@ -209,7 +211,6 @@ if (varargs) {
efree(varargs);
}
-
/* Function that accepts a string, followed by varargs (1 or more) */
char *str;
@@ -243,3 +244,4 @@ for (i = 0; i < num_varargs; i++) {
if (zend_parse_parameters_none() == FAILURE) {
return;
}
+```