summaryrefslogtreecommitdiff
path: root/docs
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
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')
-rw-r--r--docs/input-filter.md43
-rw-r--r--docs/mailinglist-rules.md11
-rw-r--r--docs/output-api.md265
-rw-r--r--docs/parameter-parsing-api.md210
-rw-r--r--docs/self-contained-extensions.md212
-rw-r--r--docs/streams.md373
-rw-r--r--docs/unix-build-system.md166
7 files changed, 658 insertions, 622 deletions
diff --git a/docs/input-filter.md b/docs/input-filter.md
index c5307a2155..29de4380fd 100644
--- a/docs/input-filter.md
+++ b/docs/input-filter.md
@@ -1,26 +1,23 @@
-# Input Filter Support in PHP 5
-
-XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
-and can be quite difficult to prevent. Whenever you accept user data
-and somehow display this data back to users, you are likely vulnerable
-to XSS hacks.
-
-The Input Filter support in PHP 5 is aimed at providing the framework
-through which a company-wide or site-wide security policy can be
-enforced. It is implemented as a SAPI hook and is called from the
-treat_data and post handler functions. To implement your own security
-policy you will need to write a standard PHP extension. There is also
-a powerful standard implementation in ext/filter that should suit most
-peoples' needs. However, if you want to implement your own security
-policy, read on.
-
-A simple implementation might look like the following. This stores the
-original raw user data and adds a my_get_raw() function while the normal
-$_POST, $_GET and $_COOKIE arrays are only populated with stripped
-data. In this simple example all I am doing is calling strip_tags() on
-the data.
-
-```
+# Input filter support in PHP
+
+XSS (Cross Site Scripting) hacks are becoming more and more prevalent, and can
+be quite difficult to prevent. Whenever you accept user data and somehow display
+this data back to users, you are likely vulnerable to XSS hacks.
+
+The Input Filter support in PHP is aimed at providing the framework through
+which a company-wide or site-wide security policy can be enforced. It is
+implemented as a SAPI hook and is called from the `treat_data` and post handler
+functions. To implement your own security policy you will need to write a
+standard PHP extension. There is also a powerful standard implementation in
+`ext/filter` that should suit most peoples' needs. However, if you want to
+implement your own security policy, read on.
+
+A simple implementation might look like the following. This stores the original
+raw user data and adds a `my_get_raw()` function while the normal `$_POST`,
+`$_GET` and `$_COOKIE` arrays are only populated with stripped data. In this
+simple example all I am doing is calling `strip_tags()` on the data.
+
+```c
ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
zval *post_array;
zval *get_array;
diff --git a/docs/mailinglist-rules.md b/docs/mailinglist-rules.md
index c76dc7862a..8bdf9752d0 100644
--- a/docs/mailinglist-rules.md
+++ b/docs/mailinglist-rules.md
@@ -1,4 +1,4 @@
-# Mailinglist Rules
+# Mailinglist rules
This is the first file you should be reading before doing any posts on PHP
mailinglists. Following these rules is considered imperative to the success of
@@ -19,7 +19,6 @@ following some basic rules with regards to mailinglist usage will:
d. Increase the general level of good will on planet Earth.
-
Having said that, here are the organizational rules:
1. Respect other people working on the project.
@@ -28,9 +27,9 @@ Having said that, here are the organizational rules:
your post after a good breather or a good nights sleep.
3. Make sure you pick the right mailinglist for your posting. Please review
- the descriptions on the mailinglist overview page
- (http://www.php.net/mailing-lists.php). When in doubt ask a friend or
- someone you trust on IRC.
+ the descriptions on the
+ [mailinglist overview page](https://www.php.net/mailing-lists.php). When
+ in doubt ask a friend or someone you trust on IRC.
4. Make sure you know what you are talking about. PHP is a very large project
that strives to be very open. The flip side is that the core developers
@@ -70,7 +69,7 @@ The next few rules are more some general hints:
new thread.
Finally, additional hints on how to behave inside the virtual community can be
-found in RFC 1855 (http://www.faqs.org/rfcs/rfc1855.html).
+found in [RFC 1855](http://www.faqs.org/rfcs/rfc1855.html).
Happy hacking,
diff --git a/docs/output-api.md b/docs/output-api.md
index 3c23c8e8de..73876c4732 100644
--- a/docs/output-api.md
+++ b/docs/output-api.md
@@ -1,139 +1,136 @@
-API adjustment to the old output control code:
+# API adjustment to the old output control code
- Everything now resides beneath the php_output namespace,
- and there's an API call for every output handler op.
+Everything now resides beneath the php_output namespace, and there's an API call
+for every output handler op.
- Checking output control layers status:
- // Using OG()
- php_output_get_status();
+ Checking output control layers status:
+ // Using OG()
+ php_output_get_status();
- Starting the default output handler:
- // php_start_ob_buffer(NULL, 0, 1);
- php_output_start_default();
+ Starting the default output handler:
+ // php_start_ob_buffer(NULL, 0, 1);
+ php_output_start_default();
- Starting an user handler by zval:
- // php_start_ob_buffer(zhandler, chunk_size, erase);
- php_output_start_user(zhandler, chunk_size, flags);
+ Starting an user handler by zval:
+ // php_start_ob_buffer(zhandler, chunk_size, erase);
+ php_output_start_user(zhandler, chunk_size, flags);
- Starting an internal handler without context:
- // php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase);
- php_output_start_internal(handler_name, handler_name_len, my_php_output_handler_func_t, chunk_size, flags);
-
- Starting an internal handler with context:
- // not possible with old API
- php_output_handler *h;
- h = php_output_handler_create_internal(handler_name, handler_name_len, my_php_output_handler_context_func_t, chunk_size, flags);
- php_output_handler_set_context(h, my_context, my_context_dtor);
- php_output_handler_start(h);
-
- Testing whether a certain output handler has already been started:
- // php_ob_handler_used("output handler name");
- php_output_handler_started(handler_name, handler_name_len);
-
- Flushing one output buffer:
- // php_end_ob_buffer(1, 1);
- php_output_flush();
-
- Flushing all output buffers:
- // not possible with old API
- php_output_flush_all();
-
- Cleaning one output buffer:
- // php_ob_end_buffer(0, 1);
- php_output_clean();
-
- Cleaning all output buffers:
- // not possible with old API
- php_output_clean_all();
-
- Discarding one output buffer:
- // php_ob_end_buffer(0, 0);
- php_output_discard();
-
- Discarding all output buffers:
- // php_ob_end_buffers(0);
- php_output_discard_all();
-
- Stopping (and dropping) one output buffer:
- // php_ob_end_buffer(1, 0)
- php_output_end();
-
- Stopping (and dropping) all output buffers:
- // php_ob_end_buffers(1, 0);
- php_output_end_all();
-
- Retrieving output buffers contents:
- // php_ob_get_buffer(zstring);
- php_output_get_contents(zstring);
-
- Retrieving output buffers length:
- // php_ob_get_length(zlength);
- php_output_get_length(zlength);
-
- Retrieving output buffering level:
- // OG(nesting_level);
- php_output_get_level();
-
- Issue a warning because of an output handler conflict:
- // php_ob_init_conflict("to be started handler name", "to be tested if already started handler name");
- php_output_handler_conflict(new_handler_name, new_handler_name_len, set_handler_name, set_handler_name_len);
-
- Registering a conflict checking function, which will be checked prior starting the handler:
- // not possible with old API, unless hardcoding into output.c
- php_output_handler_conflict_register(handler_name, handler_name_len, my_php_output_handler_conflict_check_t);
-
- Registering a reverse conflict checking function, which will be checked prior starting the specified foreign handler:
- // not possible with old API
- php_output_handler_reverse_conflict_register(foreign_handler_name, foreign_handler_name_len, my_php_output_handler_conflict_check_t);
-
- Facilitating a context from within an output handler callable with ob_start():
- // not possible with old API
- php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ, (void *) &custom_ctx_ptr_ptr);
-
- Disabling of the output handler by itself:
- //not possible with old API
- php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_DISABLE, NULL);
-
- Marking an output handler immutable by itself because of irreversibility of its operation:
- // not possible with old API
- php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL);
-
- Restarting the output handler because of a CLEAN operation:
- // not possible with old API
- if (flags & PHP_OUTPUT_HANDLER_CLEAN) { ... }
-
- Recognizing by the output handler itself if it gets discarded:
- // not possible with old API
- if ((flags & PHP_OUTPUT_HANDLER_CLEAN) && (flags & PHP_OUTPUT_HANDLER_FINAL)) { ... }
-
-
-Output handler hooks
-
- The output handler can change its abilities at runtime. Eg. the gz handler can
- remove the CLEANABLE and REMOVABLE bits when the first output has passed through it;
- or handlers implemented in C to be used with ob_start() can contain a non-global
- context:
- PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ
- pass a void*** pointer as second arg to receive the address of a pointer
- pointer to the opaque field of the output handler context
- PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS
- pass a int* pointer as second arg to receive the flags set for the output handler
- PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL
- pass a int* pointer as second arg to receive the level of this output handler
- (starts with 0)
- PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE
- the second arg is ignored; marks the output handler to be neither cleanable
- nor removable
- PHP_OUTPUT_HANDLER_HOOK_DISABLE
- the second arg is ignored; marks the output handler as disabled
-
-
-Open questions
-
- Should the userland API be adjusted and unified?
-
- Many bits of the manual (and very first implementation) do not comply
- with the behaviour of the current (to be obsoleted) code, thus should
- the manual or the behaviour be adjusted?
-
-END
+ Starting an internal handler without context:
+ // php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase);
+ php_output_start_internal(handler_name, handler_name_len, my_php_output_handler_func_t, chunk_size, flags);
+
+ Starting an internal handler with context:
+ // not possible with old API
+ php_output_handler *h;
+ h = php_output_handler_create_internal(handler_name, handler_name_len, my_php_output_handler_context_func_t, chunk_size, flags);
+ php_output_handler_set_context(h, my_context, my_context_dtor);
+ php_output_handler_start(h);
+
+ Testing whether a certain output handler has already been started:
+ // php_ob_handler_used("output handler name");
+ php_output_handler_started(handler_name, handler_name_len);
+
+ Flushing one output buffer:
+ // php_end_ob_buffer(1, 1);
+ php_output_flush();
+
+ Flushing all output buffers:
+ // not possible with old API
+ php_output_flush_all();
+
+ Cleaning one output buffer:
+ // php_ob_end_buffer(0, 1);
+ php_output_clean();
+
+ Cleaning all output buffers:
+ // not possible with old API
+ php_output_clean_all();
+
+ Discarding one output buffer:
+ // php_ob_end_buffer(0, 0);
+ php_output_discard();
+
+ Discarding all output buffers:
+ // php_ob_end_buffers(0);
+ php_output_discard_all();
+
+ Stopping (and dropping) one output buffer:
+ // php_ob_end_buffer(1, 0)
+ php_output_end();
+
+ Stopping (and dropping) all output buffers:
+ // php_ob_end_buffers(1, 0);
+ php_output_end_all();
+
+ Retrieving output buffers contents:
+ // php_ob_get_buffer(zstring);
+ php_output_get_contents(zstring);
+
+ Retrieving output buffers length:
+ // php_ob_get_length(zlength);
+ php_output_get_length(zlength);
+
+ Retrieving output buffering level:
+ // OG(nesting_level);
+ php_output_get_level();
+
+ Issue a warning because of an output handler conflict:
+ // php_ob_init_conflict("to be started handler name", "to be tested if already started handler name");
+ php_output_handler_conflict(new_handler_name, new_handler_name_len, set_handler_name, set_handler_name_len);
+
+ Registering a conflict checking function, which will be checked prior starting the handler:
+ // not possible with old API, unless hardcoding into output.c
+ php_output_handler_conflict_register(handler_name, handler_name_len, my_php_output_handler_conflict_check_t);
+
+ Registering a reverse conflict checking function, which will be checked prior starting the specified foreign handler:
+ // not possible with old API
+ php_output_handler_reverse_conflict_register(foreign_handler_name, foreign_handler_name_len, my_php_output_handler_conflict_check_t);
+
+ Facilitating a context from within an output handler callable with ob_start():
+ // not possible with old API
+ php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ, (void *) &custom_ctx_ptr_ptr);
+
+ Disabling of the output handler by itself:
+ //not possible with old API
+ php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_DISABLE, NULL);
+
+ Marking an output handler immutable by itself because of irreversibility of its operation:
+ // not possible with old API
+ php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL);
+
+ Restarting the output handler because of a CLEAN operation:
+ // not possible with old API
+ if (flags & PHP_OUTPUT_HANDLER_CLEAN) { ... }
+
+ Recognizing by the output handler itself if it gets discarded:
+ // not possible with old API
+ if ((flags & PHP_OUTPUT_HANDLER_CLEAN) && (flags & PHP_OUTPUT_HANDLER_FINAL)) { ... }
+
+## Output handler hooks
+
+The output handler can change its abilities at runtime. Eg. the gz handler can
+remove the CLEANABLE and REMOVABLE bits when the first output has passed through it;
+or handlers implemented in C to be used with ob_start() can contain a non-global
+context:
+
+ PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ
+ pass a void*** pointer as second arg to receive the address of a pointer
+ pointer to the opaque field of the output handler context
+ PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS
+ pass a int* pointer as second arg to receive the flags set for the output handler
+ PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL
+ pass a int* pointer as second arg to receive the level of this output handler
+ (starts with 0)
+ PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE
+ the second arg is ignored; marks the output handler to be neither cleanable
+ nor removable
+ PHP_OUTPUT_HANDLER_HOOK_DISABLE
+ the second arg is ignored; marks the output handler as disabled
+
+## Open questions
+
+* Should the userland API be adjusted and unified?
+
+Many bits of the manual (and very first implementation) do not comply with the
+behaviour of the current (to be obsoleted) code, thus should the manual or the
+behaviour be adjusted?
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;
}
+```
diff --git a/docs/self-contained-extensions.md b/docs/self-contained-extensions.md
index 84d6aaa685..47f4c636ba 100644
--- a/docs/self-contained-extensions.md
+++ b/docs/self-contained-extensions.md
@@ -1,84 +1,83 @@
-# HOW TO CREATE A SELF-CONTAINED PHP EXTENSION
+# How to create a self-contained PHP extension
- A self-contained extension can be distributed independently of
- the PHP source. To create such an extension, two things are
- required:
+A self-contained extension can be distributed independently of the PHP source.
+To create such an extension, two things are required:
- - Configuration file (config.m4)
- - Source code for your module
+* Configuration file (config.m4)
+* Source code for your module
- We will describe now how to create these and how to put things
- together.
+We will describe now how to create these and how to put things together.
-## PREPARING YOUR SYSTEM
+## Prepairing your system
- While the result will run on any system, a developer's setup needs these
- tools:
+While the result will run on any system, a developer's setup needs these tools:
- GNU autoconf
- GNU libtool
- GNU m4
+* GNU autoconf
+* GNU libtool
+* GNU m4
- All of these are available from
+All of these are available from
ftp://ftp.gnu.org/pub/gnu/
-## CONVERTING AN EXISTING EXTENSION
+## Converting an existing extension
- Just to show you how easy it is to create a self-contained
- extension, we will convert an embedded extension into a
- self-contained one. Install PHP and execute the following
- commands.
+Just to show you how easy it is to create a self-contained extension, we will
+convert an embedded extension into a self-contained one. Install PHP and execute
+the following commands.
- $ mkdir /tmp/newext
- $ cd /tmp/newext
-
- You now have an empty directory. We will copy the files from
- the mysql extension:
-
- $ cp -rp php-4.0.X/ext/mysql/* .
+```bash
+mkdir /tmp/newext
+cd /tmp/newext
+```
- It is time to finish the module. Run:
+You now have an empty directory. We will copy the files from the mysqli
+extension:
- $ phpize
+```bash
+cp -rp php-src/ext/mysqli/* .
+```
- You can now ship the contents of the directory - the extension
- can live completely on its own.
+It is time to finish the module. Run:
- The user instructions boil down to
+```bash
+phpize
+```
- $ ./configure \
- [--with-php-config=/path/to/php-config] \
- [--with-mysql=MYSQL-DIR]
- $ make install
+You can now ship the contents of the directory - the extension can live
+completely on its own.
- The MySQL module will either use the embedded MySQL client
- library or the MySQL installation in MYSQL-DIR.
+The user instructions boil down to
+```bash
+./configure \
+ [--with-php-config=/path/to/php-config] \
+ [--with-mysqli=MYSQL-DIR]
+make install
+```
-## DEFINING THE NEW EXTENSION
+The MySQL module will either use the embedded MySQL client library or the MySQL
+installation in MYSQL-DIR.
- Our demo extension is called "foobar".
+## Defining the new extension
- It consists of two source files "foo.c" and "bar.c"
- (and any arbitrary amount of header files, but that is not
- important here).
+Our demo extension is called "foobar".
- The demo extension does not reference any external
- libraries (that is important, because the user does not
- need to specify anything).
+It consists of two source files `foo.c` and `bar.c` (and any arbitrary amount of
+header files, but that is not important here).
+The demo extension does not reference any external libraries (that is important,
+because the user does not need to specify anything).
- LTLIBRARY_SOURCES specifies the names of the sources files. You can
- name an arbitrary number of source files here.
+`LTLIBRARY_SOURCES` specifies the names of the sources files. You can name an
+arbitrary number of source files here.
-## CREATING THE M4 CONFIGURATION FILE
+## Creating the M4 configuration file
- The m4 configuration can perform additional checks. For a
- self-contained extension, you do not need more than a few
- macro calls.
+The m4 configuration can perform additional checks. For a self-contained
+extension, you do not need more than a few macro calls.
-```
+```m4
PHP_ARG_ENABLE([foobar],
[whether to enable foobar],
[AS_HELP_STRING([--enable-foobar],
@@ -89,81 +88,86 @@ if test "$PHP_FOOBAR" != "no"; then
fi
```
- PHP_ARG_ENABLE will automatically set the correct variables, so
- that the extension will be enabled by PHP_NEW_EXTENSION in shared mode.
-
- The first argument of PHP_NEW_EXTENSION describes the name of the
- extension. The second names the source-code files. The third passes
- $ext_shared which is set by PHP_ARG_ENABLE/WITH to PHP_NEW_EXTENSION.
+`PHP_ARG_ENABLE` will automatically set the correct variables, so that the
+extension will be enabled by `PHP_NEW_EXTENSION` in shared mode.
- Please use always PHP_ARG_ENABLE or PHP_ARG_WITH. Even if you do not
- plan to distribute your module with PHP, these facilities allow you
- to integrate your module easily into the main PHP module framework.
+The first argument of `PHP_NEW_EXTENSION` describes the name of the extension.
+The second names the source-code files. The third passes `$ext_shared` which is
+set by `PHP_ARG_ENABLE/WITH` to `PHP_NEW_EXTENSION`.
-## CREATING SOURCE FILES
+Please use always `PHP_ARG_ENABLE` or `PHP_ARG_WITH`. Even if you do not plan to
+distribute your module with PHP, these facilities allow you to integrate your
+module easily into the main PHP module framework.
- ext_skel can be of great help when creating the common code for all modules
- in PHP for you and also writing basic function definitions and C code for
- handling arguments passed to your functions. See `./ext/ext_skel.php --help`
- for further information.
+## Create source files
- As for the rest, you are currently alone here. There are a lot of existing
- modules, use a simple module as a starting point and add your own code.
+`ext_skel.php` can be of great help when creating the common code for all
+modules in PHP for you and also writing basic function definitions and C code
+for handling arguments passed to your functions. See `./ext/ext_skel.php --help`
+for further information.
+As for the rest, you are currently alone here. There are a lot of existing
+modules, use a simple module as a starting point and add your own code.
-## CREATING THE SELF-CONTAINED EXTENSION
+## Creating the self-contained extension
- Put config.m4 and the source files into one directory. Then, run phpize
- (this is installed during make install by PHP 4.0).
+Put `config.m4` and the source files into one directory. Then, run `phpize`
+(this is installed during `make install` by PHP).
- For example, if you configured PHP with --prefix=/php, you would run
+For example, if you configured PHP with `--prefix=/php`, you would run
- $ /php/bin/phpize
+```bash
+/php/bin/phpize
+```
- This will automatically copy the necessary build files and create
- configure from your config.m4.
+This will automatically copy the necessary build files and create configure from
+your `config.m4`.
- And that's it. You now have a self-contained extension.
+And that's it. You now have a self-contained extension.
-## INSTALLING A SELF-CONTAINED EXTENSION
+## Installing a self-contained extension
- An extension can be installed by running:
+An extension can be installed by running:
- $ ./configure \
- [--with-php-config=/path/to/php-config]
- $ make install
+```bash
+./configure \
+ [--with-php-config=/path/to/php-config]
+make install
+```
-## ADDING SHARED MODULE SUPPORT TO A MODULE
+## Adding shared module support to a module
- In order to be useful, a self-contained extension must be loadable
- as a shared module. I will explain now how you can add shared module
- support to an existing module called foo.
+In order to be useful, a self-contained extension must be loadable as a shared
+module. The following will explain now how you can add shared module support to
+an existing module called `foo`.
- 1. In config.m4, use PHP_ARG_WITH/PHP_ARG_ENABLE. Then you will
- automatically be able to use --with-foo=shared[,..] or
- --enable-foo=shared[,..].
+1. In `config.m4`, use `PHP_ARG_WITH/PHP_ARG_ENABLE`. Then you will
+ automatically be able to use `--with-foo=shared[,..]` or
+ `--enable-foo=shared[,..]`.
- 2. In config.m4, use PHP_NEW_EXTENSION(foo,.., $ext_shared) to enable
- building the extension.
+2. In `config.m4`, use `PHP_NEW_EXTENSION(foo,.., $ext_shared)` to enable
+ building the extension.
- 3. Add the following lines to your C source file:
+3. Add the following lines to your C source file:
-```
- #ifdef COMPILE_DL_FOO
- ZEND_GET_MODULE(foo)
- #endif
+```c
+#ifdef COMPILE_DL_FOO
+ ZEND_GET_MODULE(foo)
+#endif
```
-## PECL SITE CONFORMITY
+## PECL site conformity
- If you plan to release an extension to the PECL website, there are several
- points to be regarded.
+If you plan to release an extension to the PECL website, there are several
+points to be regarded.
- 1. Add LICENSE or COPYING to the package.xml
+1. Add `LICENSE` or `COPYING` to the `package.xml`
- 2. The following should be defined in one of the extension header files
+2. The following should be defined in one of the extension header files
- #define PHP_FOO_VERSION "1.2.3"
+```c
+#define PHP_FOO_VERSION "1.2.3"
+```
- This macros has to be used within your foo_module_entry to indicate the
- extension version.
+This macros has to be used within your foo_module_entry to indicate the
+extension version.
diff --git a/docs/streams.md b/docs/streams.md
index 6ef69c733a..0ec3846d68 100644
--- a/docs/streams.md
+++ b/docs/streams.md
@@ -1,29 +1,26 @@
-An Overview of the PHP Streams abstraction
-==========================================
+# An overview of the PHP streams abstraction
WARNING: some prototypes in this file are out of date.
-The information contained here is being integrated into
-the PHP manual - stay tuned...
-Please send comments to: Wez Furlong <wez@thebrainroom.com>
+## Why streams?
-Why Streams?
-============
You may have noticed a shed-load of issock parameters flying around the PHP
-code; we don't want them - they are ugly and cumbersome and force you to
-special case sockets and files every time you need to work with a "user-level"
-PHP file pointer.
+code; we don't want them - they are ugly and cumbersome and force you to special
+case sockets and files every time you need to work with a "user-level" PHP file
+pointer.
+
Streams take care of that and present the PHP extension coder with an ANSI
stdio-alike API that looks much nicer and can be extended to support non file
based data sources.
-Using Streams
-=============
-Streams use a php_stream* parameter just as ANSI stdio (fread etc.) use a
-FILE* parameter.
+## Using streams
+
+Streams use a `php_stream*` parameter just as ANSI stdio (fread etc.) use a
+`FILE*` parameter.
The main functions are:
+```c
PHPAPI size_t php_stream_read(php_stream * stream, char * buf, size_t count);
PHPAPI size_t php_stream_write(php_stream * stream, const char * buf, size_t
count);
@@ -37,210 +34,234 @@ PHPAPI int php_stream_flush(php_stream * stream);
PHPAPI int php_stream_seek(php_stream * stream, off_t offset, int whence);
PHPAPI off_t php_stream_tell(php_stream * stream);
PHPAPI int php_stream_lock(php_stream * stream, int mode);
+```
These (should) behave in the same way as the ANSI stdio functions with similar
-names: fread, fwrite, fprintf, feof, fgetc, fgets, fclose, fflush, fseek, ftell, flock.
+names: fread, fwrite, fprintf, feof, fgetc, fgets, fclose, fflush, fseek, ftell,
+flock.
+
+## Opening streams
-Opening Streams
-===============
In most cases, you should use this API:
+```c
PHPAPI php_stream *php_stream_open_wrapper(const char *path, const char *mode,
int options, char **opened_path);
+```
Where:
- path is the file or resource to open.
- mode is the stdio compatible mode eg: "wb", "rb" etc.
- options is a combination of the following values:
- IGNORE_PATH (default) - don't use include path to search for the file
- USE_PATH - use include path to search for the file
- IGNORE_URL - do not use plugin wrappers
- REPORT_ERRORS - show errors in a standard format if something
- goes wrong.
- STREAM_MUST_SEEK - If you really need to be able to seek the stream
- and don't need to be able to write to the original
- file/URL, use this option to arrange for the stream
- to be copied (if needed) into a stream that can
- be seek()ed.
-
- opened_path is used to return the path of the actual file opened,
- but if you used STREAM_MUST_SEEK, may not be valid. You are
- responsible for efree()ing opened_path. opened_path may be (and usually
- is) NULL.
+
+* `path` is the file or resource to open.
+* `mode` is the stdio compatible mode eg: "wb", "rb" etc.
+* `options` is a combination of the following values:
+ * `IGNORE_PATH` (default) - don't use include path to search for the file
+ * `USE_PATH` - use include path to search for the file
+ * `IGNORE_URL` - do not use plugin wrappers
+ * `REPORT_ERRORS` - show errors in a standard format if something goes wrong.
+ * `STREAM_MUST_SEEK` - If you really need to be able to seek the stream and
+ don't need to be able to write to the original file/URL, use this option to
+ arrange for the stream to be copied (if needed) into a stream that can be
+ seek()ed.
+* `opened_path` is used to return the path of the actual file opened, but if you
+ used `STREAM_MUST_SEEK`, may not be valid. You are responsible for
+ `efree()ing` `opened_path`.
+* `opened_path` may be (and usually is) `NULL`.
If you need to open a specific stream, or convert standard resources into
-streams there are a range of functions to do this defined in php_streams.h.
-A brief list of the most commonly used functions:
+streams there are a range of functions to do this defined in `php_streams.h`. A
+brief list of the most commonly used functions:
+```c
PHPAPI php_stream *php_stream_fopen_from_file(FILE *file, const char *mode);
- Convert a FILE * into a stream.
+ /* Convert a FILE * into a stream. */
PHPAPI php_stream *php_stream_fopen_tmpfile(void);
- Open a FILE * with tmpfile() and convert into a stream.
+ /* Open a FILE * with tmpfile() and convert into a stream. */
PHPAPI php_stream *php_stream_fopen_temporary_file(const char *dir,
const char *pfx, char **opened_path);
- Generate a temporary file name and open it.
+ /* Generate a temporary file name and open it. */
+```
-There are some network enabled relatives in php_network.h:
+There are some network enabled relatives in `php_network.h`:
+```c
PHPAPI php_stream *php_stream_sock_open_from_socket(int socket, int persistent);
- Convert a socket into a stream.
+ /* Convert a socket into a stream. */
PHPAPI php_stream *php_stream_sock_open_host(const char *host, unsigned short port,
- int socktype, int timeout, int persistent);
- Open a connection to a host and return a stream.
+ int socktype, int timeout, int persistent);
+ /* Open a connection to a host and return a stream. */
PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent,
struct timeval *timeout);
- Open a UNIX domain socket.
-
+ /* Open a UNIX domain socket. */
+```
-Stream Utilities
-================
+## Stream utilities
-If you need to copy some data from one stream to another, you will be please
-to know that the streams API provides a standard way to do this:
+If you need to copy some data from one stream to another, you will be please to
+know that the streams API provides a standard way to do this:
+```c
PHPAPI size_t php_stream_copy_to_stream(php_stream *src,
php_stream *dest, size_t maxlen);
+```
If you want to copy all remaining data from the src stream, pass
-PHP_STREAM_COPY_ALL as the maxlen parameter, otherwise maxlen indicates the
-number of bytes to copy.
-This function will try to use mmap where available to make the copying more
-efficient.
+`PHP_STREAM_COPY_ALL` as the maxlen parameter, otherwise maxlen indicates the
+number of bytes to copy. This function will try to use mmap where available to
+make the copying more efficient.
If you want to read the contents of a stream into an allocated memory buffer,
you should use:
+```c
PHPAPI size_t php_stream_copy_to_mem(php_stream *src, char **buf,
size_t maxlen, int persistent);
+```
-This function will set buf to the address of the buffer that it allocated,
-which will be maxlen bytes in length, or will be the entire length of the
-data remaining on the stream if you set maxlen to PHP_STREAM_COPY_ALL.
-The buffer is allocated using pemalloc(); you need to call pefree() to
-release the memory when you are done.
-As with copy_to_stream, this function will try use mmap where it can.
+This function will set buf to the address of the buffer that it allocated, which
+will be maxlen bytes in length, or will be the entire length of the data
+remaining on the stream if you set maxlen to `PHP_STREAM_COPY_ALL`. The buffer
+is allocated using `pemalloc()`. You need to call `pefree()` to release the
+memory when you are done. As with `copy_to_stream`, this function will try use
+mmap where it can.
-If you have an existing stream and need to be able to seek() it, you
-can use this function to copy the contents into a new stream that can
-be seek()ed:
+If you have an existing stream and need to be able to `seek()` it, you can use
+this function to copy the contents into a new stream that can be `seek()ed`:
+```c
PHPAPI int php_stream_make_seekable(php_stream *origstream, php_stream **newstream);
+```
It returns one of the following values:
-#define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */
-#define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */
-#define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */
-#define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */
-make_seekable will always set newstream to be the stream that is valid
-if the function succeeds.
-When you have finished, remember to close the stream.
+```c
+#define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */
+#define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */
+#define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */
+#define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */
+```
+
+`make_seekable` will always set newstream to be the stream that is valid if the
+function succeeds. When you have finished, remember to close the stream.
-NOTE: If you only need to seek forward, there is no need to call this
-function, as the php_stream_seek can emulate forward seeking when the
-whence parameter is SEEK_CUR.
+NOTE: If you only need to seek forward, there is no need to call this function,
+as the `php_stream_seek` can emulate forward seeking when the whence parameter
+is `SEEK_CUR`.
-NOTE: Writing to the stream may not affect the original source, so it
-only makes sense to use this for read-only use.
+NOTE: Writing to the stream may not affect the original source, so it only makes
+sense to use this for read-only use.
-NOTE: If the origstream is network based, this function will block
-until the whole contents have been downloaded.
+NOTE: If the origstream is network based, this function will block until the
+whole contents have been downloaded.
-NOTE: Never call this function with an origstream that is referenced
-as a resource! It will close the origstream on success, and this
-can lead to a crash when the resource is later used/released.
+NOTE: Never call this function with an origstream that is referenced as a
+resource! It will close the origstream on success, and this can lead to a crash
+when the resource is later used/released.
NOTE: If you are opening a stream and need it to be seekable, use the
-STREAM_MUST_SEEK option to php_stream_open_wrapper();
+`STREAM_MUST_SEEK` option to php_stream_open_wrapper();
+```c
PHPAPI int php_stream_supports_lock(php_stream * stream);
+```
-This function will return either 1 (success) or 0 (failure) indicating whether or
-not a lock can be set on this stream. Typically you can only set locks on stdio streams.
+This function will return either 1 (success) or 0 (failure) indicating whether
+or not a lock can be set on this stream. Typically you can only set locks on
+stdio streams.
-Casting Streams
-===============
-What if your extension needs to access the FILE* of a user level file pointer?
-You need to "cast" the stream into a FILE*, and this is how you do it:
+## Casting streams
+What if your extension needs to access the `FILE*` of a user level file pointer?
+You need to "cast" the stream into a `FILE*`, and this is how you do it:
+
+```c
FILE * fp;
php_stream * stream; /* already opened */
if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void*)&fp, REPORT_ERRORS) == FAILURE) {
RETURN_FALSE;
}
+```
The prototype is:
-PHPAPI int php_stream_cast(php_stream * stream, int castas, void ** ret, int
- show_err);
+```c
+PHPAPI int php_stream_cast(php_stream * stream, int castas, void ** ret, int show_err);
+```
+
+The `show_err` parameter, if non-zero, will cause the function to display an
+appropriate error message of type `E_WARNING` if the cast fails.
-The show_err parameter, if non-zero, will cause the function to display an
-appropriate error message of type E_WARNING if the cast fails.
+`castas` can be one of the following values:
-castas can be one of the following values:
+```txt
PHP_STREAM_AS_STDIO - a stdio FILE*
PHP_STREAM_AS_FD - a generic file descriptor
PHP_STREAM_AS_SOCKETD - a socket descriptor
+```
-If you ask a socket stream for a FILE*, the abstraction will use fdopen to
-create it for you. Be warned that doing so may cause buffered data to be lost
+If you ask a socket stream for a `FILE*`, the abstraction will use fdopen to
+create it for you. Be warned that doing so may cause buffered data to be lost
if you mix ANSI stdio calls on the FILE* with php stream calls on the stream.
If your system has the fopencookie function, php streams can synthesize a
-FILE* on top of any stream, which is useful for SSL sockets, memory based
+`FILE*` on top of any stream, which is useful for SSL sockets, memory based
streams, data base streams etc. etc.
-In situations where this is not desirable, you should query the stream
-to see if it naturally supports FILE *. You can use this code snippet
-for this purpose:
+In situations where this is not desirable, you should query the stream to see if
+it naturally supports `FILE *`. You can use this code snippet for this purpose:
- if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) {
- /* can safely cast to FILE* with no adverse side effects */
- }
+```c
+if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) {
+ /* can safely cast to FILE* with no adverse side effects */
+}
+```
You can use:
+```c
PHPAPI int php_stream_can_cast(php_stream * stream, int castas)
+```
-to find out if a stream can be cast, without actually performing the cast, so
-to check if a stream is a socket you might use:
+to find out if a stream can be cast, without actually performing the cast, so to
+check if a stream is a socket you might use:
+```c
if (php_stream_can_cast(stream, PHP_STREAM_AS_SOCKETD) == SUCCESS) {
/* it can be a socket */
}
+```
-Please note the difference between php_stream_is and php_stream_can_cast;
-stream_is tells you if the stream is a particular type of stream, whereas
-can_cast tells you if the stream can be forced into the form you request.
-The former doesn't change anything, while the later *might* change some
-state in the stream.
+Please note the difference between `php_stream_is` and `php_stream_can_cast`;
+`stream_is` tells you if the stream is a particular type of stream, whereas
+`can_cast` tells you if the stream can be forced into the form you request. The
+former doesn't change anything, while the later *might* change some state in the
+stream.
-Stream Internals
-================
+## Stream internals
-There are two main structures associated with a stream - the php_stream
+There are two main structures associated with a stream - the `php_stream`
itself, which holds some state information (and possibly a buffer) and a
-php_stream_ops structure, which holds the "virtual method table" for the
+`php_stream_ops` structure, which holds the "virtual method table" for the
underlying implementation.
-The php_streams ops struct consists of pointers to methods that implement
-read, write, close, flush, seek, gets and cast operations. Of these, an
-implementation need only implement write, read, close and flush. The gets
-method is intended to be used for streams if there is an underlying method
-that can efficiently behave as fgets. The ops struct also contains a label
-for the implementation that will be used when printing error messages - the
-stdio implementation has a label of "STDIO" for example.
+The `php_streams` ops struct consists of pointers to methods that implement
+read, write, close, flush, seek, gets and cast operations. Of these, an
+implementation need only implement write, read, close and flush. The gets method
+is intended to be used for streams if there is an underlying method that can
+efficiently behave as fgets. The ops struct also contains a label for the
+implementation that will be used when printing error messages - the stdio
+implementation has a label of `STDIO` for example.
-The idea is that a stream implementation defines a php_stream_ops struct, and
-associates it with a php_stream using php_stream_alloc.
+The idea is that a stream implementation defines a `php_stream_ops` struct, and
+associates it with a `php_stream` using `php_stream_alloc`.
-As an example, the php_stream_fopen() function looks like this:
+As an example, the `php_stream_fopen()` function looks like this:
+```c
PHPAPI php_stream * php_stream_fopen(const char * filename, const char * mode)
{
FILE * fp = fopen(filename, mode);
@@ -255,62 +276,64 @@ PHPAPI php_stream * php_stream_fopen(const char * filename, const char * mode)
}
return NULL;
}
+```
-php_stream_stdio_ops is a php_stream_ops structure that can be used to handle
-FILE* based streams.
+`php_stream_stdio_ops` is a `php_stream_ops` structure that can be used to
+handle `FILE*` based streams.
-A socket based stream would use code similar to that above to create a stream
-to be passed back to fopen_wrapper (or it's yet to be implemented successor).
+A socket based stream would use code similar to that above to create a stream to
+be passed back to fopen_wrapper (or it's yet to be implemented successor).
The prototype for php_stream_alloc is this:
+```c
PHPAPI php_stream * php_stream_alloc(php_stream_ops * ops, void * abstract,
size_t bufsize, int persistent, const char * mode)
-
-ops is a pointer to the implementation,
-abstract holds implementation specific data that is relevant to this instance
-of the stream,
-bufsize is the size of the buffer to use - if 0, then buffering at the stream
-level will be disabled (recommended for underlying sources that implement
-their own buffering - such a FILE*),
-persistent controls how the memory is to be allocated - persistently so that
-it lasts across requests, or non-persistently so that it is freed at the end
-of a request (it uses pemalloc),
-mode is the stdio-like mode of operation - php streams places no real meaning
-in the mode parameter, except that it checks for a 'w' in the string when
-attempting to write (this may change).
-
-The mode parameter is passed on to fdopen/fopencookie when the stream is cast
-into a FILE*, so it should be compatible with the mode parameter of fopen().
-
-Writing your own stream implementation
-======================================
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-RULE #1: when writing your own streams: make sure you have configured PHP with
---enable-debug.
-I've taken some great pains to hook into the Zend memory manager to help track
-down allocation problems. It will also help you spot incorrect use of the
-STREAMS_DC, STREAMS_CC and the semi-private STREAMS_REL_CC macros for function
-definitions.
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-RULE #2: Please use the stdio stream as a reference; it will help you
-understand the semantics of the stream operations, and it will always
-be more up to date than these docs :-)
+```
+
+* `ops` is a pointer to the implementation,
+* `abstract` holds implementation specific data that is relevant to this
+ instance of the stream,
+* `bufsize` is the size of the buffer to use - if 0, then buffering at the
+ stream
+* `level` will be disabled (recommended for underlying sources that implement
+ their own buffering - such a `FILE*`)
+* `persistent` controls how the memory is to be allocated - persistently so that
+ it lasts across requests, or non-persistently so that it is freed at the end
+ of a request (it uses pemalloc),
+* `mode` is the stdio-like mode of operation - php streams places no real
+ meaning in the mode parameter, except that it checks for a `w` in the string
+ when attempting to write (this may change).
+
+The mode parameter is passed on to `fdopen/fopencookie` when the stream is cast
+into a `FILE*`, so it should be compatible with the mode parameter of `fopen()`.
+
+## Writing your own stream implementation
+
+* **RULE #1**: when writing your own streams: make sure you have configured PHP
+ with `--enable-debug`.
+ Some great great pains have been taken to hook into the Zend memory manager to
+ help track down allocation problems. It will also help you spot incorrect use
+ of the STREAMS_DC, STREAMS_CC and the semi-private STREAMS_REL_CC macros for
+ function definitions.
+
+* RULE #2: Please use the stdio stream as a reference; it will help you
+ understand the semantics of the stream operations, and it will always be more
+ up to date than these docs :-)
First, you need to figure out what data you need to associate with the
-php_stream. For example, you might need a pointer to some memory for memory
+`php_stream`. For example, you might need a pointer to some memory for memory
based streams, or if you were making a stream to read data from an RDBMS like
MySQL, you might want to store the connection and rowset handles.
-The stream has a field called abstract that you can use to hold this data.
-If you need to store more than a single field of data, define a structure to
-hold it, allocate it (use pemalloc with the persistent flag set
-appropriately), and use the abstract pointer to refer to it.
+The stream has a field called abstract that you can use to hold this data. If
+you need to store more than a single field of data, define a structure to hold
+it, allocate it (use pemalloc with the persistent flag set appropriately), and
+use the abstract pointer to refer to it.
For structured state you might have this:
+```c
struct my_state {
MYSQL conn;
MYSQL_RES * result;
@@ -327,6 +350,7 @@ state->result = mysql_use_result(&state->conn);
stream = php_stream_alloc(&my_ops, state, 0, persistent, "r");
/* now stream->abstract == state */
+```
Once you have that part figured out, you can write your implementation and
define the your own php_stream_ops struct (we called it my_ops in the above
@@ -334,6 +358,7 @@ example).
For example, for reading from this weird MySQL stream:
+```c
static size_t php_mysqlop_read(php_stream * stream, char * buf, size_t count)
{
struct my_state * state = (struct my_state*)stream->abstract;
@@ -354,23 +379,27 @@ static size_t php_mysqlop_read(php_stream * stream, char * buf, size_t count)
such as coping with a buffer size too small to hold the data,
so I won't even go in to how to do that here */
}
+```
-Implement the other operations - remember that write, read, close and flush
-are all mandatory. The rest are optional. Declare your stream ops struct:
+Implement the other operations - remember that write, read, close and flush are
+all mandatory. The rest are optional. Declare your stream ops struct:
+```c
php_stream_ops my_ops = {
php_mysqlop_write, php_mysqlop_read, php_mysqlop_close,
php_mysqlop_flush, NULL, NULL, NULL,
"Strange MySQL example"
}
+```
That's it!
-Take a look at the STDIO implementation in streams.c for more information
-about how these operations work.
+Take a look at the STDIO implementation in streams.c for more information about
+how these operations work.
+
The main thing to remember is that in your close operation you need to release
-and free the resources you allocated for the abstract field. In the case of
-the example above, you need to use mysql_free_result on the rowset, close the
-connection and then use pefree to dispose of the struct you allocated.
-You may read the stream->persistent field to determine if your struct was
-allocated in persistent mode or not.
+and free the resources you allocated for the abstract field. In the case of the
+example above, you need to use mysql_free_result on the rowset, close the
+connection and then use pefree to dispose of the struct you allocated. You may
+read the stream->persistent field to determine if your struct was allocated in
+persistent mode or not.
diff --git a/docs/unix-build-system.md b/docs/unix-build-system.md
index e13053e39e..bdb8d4d146 100644
--- a/docs/unix-build-system.md
+++ b/docs/unix-build-system.md
@@ -1,113 +1,121 @@
-# PHP Build System V5 Overview
-
-- supports Makefile.ins during transition phase
-- not-really-portable Makefile includes have been eliminated
-- supports separate build directories without VPATH by using
- explicit rules only
-- does not waste disk-space/CPU-time for building temporary libraries
- => especially noticeable on slower systems
-- slow recursive make replaced with one global Makefile
-- eases integration of proper dependencies
-- adds PHP_DEFINE(what[, value]) which creates a single include-file
- per what. This will allow more fine-grained dependencies.
-- abandoning the "one library per directory" concept
-- improved integration of the CLI
-- several new targets
- build-modules: builds and copies dynamic modules into modules/
- install-cli: installs the CLI only, so that the install-sapi
- target does only what its name says
-- finally abandoned automake
-- changed some configure-time constructs to run at buildconf-time
-- upgraded shtool to 1.5.4
-- removed $(moduledir) (use EXTENSION_DIR)
-
-## The Reason For a New System
-
-It became more and more apparent that there is a severe need
-for addressing the portability concerns and improving the chance
-that your build is correct (how often have you been told to
-"make clean"? When this is done, you won't need to anymore).
-
-## If You Build PHP on a Unix System
-
-You, as a user of PHP, will notice no changes. Of course, the build
-system will be faster, look better and work smarter.
-
-## If You Are Developing PHP
-
-### Extension developers:
-
-Makefile.ins are abandoned. The files which are to be compiled
-are specified in the config.m4 now using the following macro:
-
+# PHP build system V5 overview
+
+* supports Makefile.ins during transition phase
+* not-really-portable Makefile includes have been eliminated
+* supports separate build directories without VPATH by using explicit rules only
+* does not waste disk-space/CPU-time for building temporary libraries =>
+ especially noticeable on slower systems
+* slow recursive make replaced with one global Makefile
+* eases integration of proper dependencies
+* adds PHP_DEFINE(what[, value]) which creates a single include-file per what.
+ This will allow more fine-grained dependencies.
+* abandoning the "one library per directory" concept
+* improved integration of the CLI
+* several new targets:
+ * `build-modules`: builds and copies dynamic modules into `modules/`
+ * `install-cli`: installs the CLI only, so that the install-sapi target does
+ only what its name says
+* finally abandoned automake
+* changed some configure-time constructs to run at buildconf-time
+* upgraded shtool to 1.5.4
+* removed `$(moduledir)` (use `EXTENSION_DIR`)
+
+## The reason for a new system
+
+It became more and more apparent that there is a severe need for addressing the
+portability concerns and improving the chance that your build is correct (how
+often have you been told to `make clean`? When this is done, you won't need to
+anymore).
+
+## If you build PHP on a Unix system
+
+You, as a user of PHP, will notice no changes. Of course, the build system will
+be faster, look better and work smarter.
+
+## If you are developing PHP
+
+### Extension developers
+
+Makefile.ins are abandoned. The files which are to be compiled are specified in
+the `config.m4` now using the following macro:
+
+```m4
PHP_NEW_EXTENSION(foo, foo.c bar.c baz.cpp, $ext_shared)
+```
-E.g. this enables the extension foo which consists of three source-code
-modules, two in C and one in C++. And, depending on the user's wishes,
-the extension will even be built as a dynamic module.
+E.g. this enables the extension foo which consists of three source-code modules,
+two in C and one in C++. And, depending on the user's wishes, the extension will
+even be built as a dynamic module.
The full syntax:
+```m4
PHP_NEW_EXTENSION(extname, sources [, shared [,sapi_class[, extra-cflags]]])
+```
-Please have a look at acinclude.m4 for the gory details and meanings
-of the other parameters.
+Please have a look at `acinclude.m4` for the gory details and meanings of the
+other parameters.
And that's basically it for the extension side.
-If you previously built sub-libraries for this module, add
-the source-code files here as well. If you need to specify
-separate include directories, do it this way:
+If you previously built sub-libraries for this module, add the source-code files
+here as well. If you need to specify separate include directories, do it this
+way:
+```m4
PHP_NEW_EXTENSION(foo, foo.c mylib/bar.c mylib/gregor.c,,,-I@ext_srcdir@/lib)
+```
-E.g. this builds the three files which are located relative to the
-extension source directory and compiles all three files with the
-special include directive (@ext_srcdir@ is automatically replaced).
+E.g. this builds the three files which are located relative to the extension
+source directory and compiles all three files with the special include directive
+(`@ext_srcdir@` is automatically replaced).
-Now, you need to tell the build system that you want to build files
-in a directory called $ext_builddir/lib:
+Now, you need to tell the build system that you want to build files in a
+directory called `$ext_builddir/lib`:
+```m4
PHP_ADD_BUILD_DIR($ext_builddir/lib)
+```
-Make sure to call this after PHP_NEW_EXTENSION, because $ext_builddir
-is only set by the latter.
+Make sure to call this after `PHP_NEW_EXTENSION`, because `$ext_builddir` is
+only set by the latter.
-If you have a complex extension, you might to need add special
-Make rules. You can do this by calling PHP_ADD_MAKEFILE_FRAGMENT
-in your config.m4 after PHP_NEW_EXTENSION.
+If you have a complex extension, you might to need add special Make rules. You
+can do this by calling `PHP_ADD_MAKEFILE_FRAGMENT` in your `config.m4` after
+`PHP_NEW_EXTENSION`.
This will read a file in the source-dir of your extension called
-Makefile.frag. In this file, $(builddir) and $(srcdir) will be
-replaced by the values which are correct for your extension
-and which are again determined by the PHP_NEW_EXTENSION macro.
+`Makefile.frag`. In this file, `$(builddir)` and `$(srcdir)` will be replaced by
+the values which are correct for your extension and which are again determined
+by the `PHP_NEW_EXTENSION` macro.
-Make sure to prefix *all* relative paths correctly with either
-$(builddir) or $(srcdir). Because the build system does not
-change the working directory anymore, we must use either
-absolute paths or relative ones to the top build-directory.
-Correct prefixing ensures that.
+Make sure to prefix *all* relative paths correctly with either `$(builddir)` or
+`$(srcdir)`. Because the build system does not change the working directory
+anymore, we must use either absolute paths or relative ones to the top
+build-directory. Correct prefixing ensures that.
-### SAPI developers:
+### SAPI developers
-Instead of using PHP_SAPI=foo/PHP_BUILD_XYZ, you will need to type
+Instead of using `PHP_SAPI=foo/PHP_BUILD_XYZ`, you will need to type
+```m4
PHP_SELECT_SAPI(name, type, sources.c)
+```
-I.e. specify the source-code files as above and also pass the
-information regarding how PHP is supposed to be built (shared
-module, program, etc).
+I.e. specify the source-code files as above and also pass the information
+regarding how PHP is supposed to be built (shared module, program, etc).
For example for APXS:
+```m4
PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php7.c php_apache.c)
+```
## General info
-The foundation for the new system is the flexible handling of
-sources and their contexts. With the help of macros you
-can define special flags for each source-file, where it is
-located, in which target context it can work, etc.
+The foundation for the new system is the flexible handling of sources and their
+contexts. With the help of macros you can define special flags for each
+source-file, where it is located, in which target context it can work, etc.
-Have a look at the well documented macros
-PHP_ADD_SOURCES(_X) in acinclude.m4.
+Have a look at the well documented macros `PHP_ADD_SOURCES(_X)` in
+`acinclude.m4`.