NameDateSize

..11-Nov-2013

.gdbinit18-Dec-201210.7 KiB

acconfig.h.in18-Dec-201228

acinclude.m418-Dec-201273.7 KiB

build/18-Dec-2012

buildconf18-Dec-2012668

buildconf.bat18-Dec-2012353

ChangeLog18-Dec-2012374.4 KiB

ChangeLog.1999.gz18-Dec-201276.9 KiB

ChangeLog.2000.gz18-Dec-2012155.8 KiB

ChangeLog.2001.gz18-Dec-2012193.4 KiB

ChangeLog.2002.gz18-Dec-2012256.2 KiB

ChangeLog.2003.gz18-Dec-2012179.5 KiB

ChangeLog.2004.gz18-Dec-2012131.5 KiB

CODING_STANDARDS18-Dec-201210.8 KiB

config.guess18-Dec-201243.8 KiB

config.sub18-Dec-201232.6 KiB

configure.in18-Dec-201244.3 KiB

CREDITS18-Dec-201291

ext/18-Dec-2012

EXTENSIONS18-Dec-201222.2 KiB

footer18-Dec-2012137

genfiles18-Dec-2012459

header18-Dec-20121.1 KiB

INSTALL18-Dec-201285.4 KiB

LICENSE18-Dec-20123.1 KiB

ltmain.sh18-Dec-2012195 KiB

main/18-Dec-2012

makedist18-Dec-20123.5 KiB

Makefile.frag18-Dec-2012919

Makefile.gcov18-Dec-20121.9 KiB

Makefile.global18-Dec-20125.2 KiB

makerpm18-Dec-20125.2 KiB

netware/18-Dec-2012

NEWS18-Dec-2012235.3 KiB

pear/18-Dec-2012

php.gif18-Dec-20122.5 KiB

php.ini-dist18-Dec-201244.1 KiB

php.ini-recommended18-Dec-201247.7 KiB

php5.spec.in18-Dec-20121.5 KiB

README.EXT_SKEL18-Dec-20127 KiB

README.EXTENSIONS18-Dec-20121.5 KiB

README.input_filter18-Dec-20125.8 KiB

README.PARAMETER_PARSING_API18-Dec-20124 KiB

README.PHP4-TO-PHP5-THIN-CHANGES18-Dec-20124.6 KiB

README.QNX18-Dec-20122.1 KiB

README.SELF-CONTAINED-EXTENSIONS18-Dec-20124.6 KiB

README.STREAMS18-Dec-201215 KiB

README.SUBMITTING_PATCH18-Dec-20123.9 KiB

README.SVN-RULES18-Dec-20125.7 KiB

README.TESTING18-Dec-20126.5 KiB

README.TESTING218-Dec-20124.8 KiB

README.UNIX-BUILD-SYSTEM18-Dec-20124.2 KiB

README.UPDATE_5_218-Dec-201237.7 KiB

README.WIN32-BUILD-SYSTEM18-Dec-20126.1 KiB

README.Zeus18-Dec-20124.2 KiB

regex/18-Dec-2012

run-tests.php18-Dec-201267.2 KiB

sapi/02-Jun-2012

scripts/18-Dec-2012

server-tests-config.php18-Dec-20122.1 KiB

server-tests.php18-Dec-201250.5 KiB

snapshot18-Dec-2012108

stamp-h.in18-Dec-201210

stub.c18-Dec-20121

svnclean.bat18-Dec-201250

tests/18-Dec-2012

TODO18-Dec-20125 KiB

TODO-5.118-Dec-2012163

TODO-PHP518-Dec-20123.7 KiB

TSRM/18-Dec-2012

UPGRADING18-Dec-201217 KiB

vcsclean18-Dec-2012297

win32/18-Dec-2012

Zend/18-Dec-2012

README.EXT_SKEL

1(NOTE: you may also want to take a look at the pear package
2         PECL_Gen, a PHP-only alternative for this script that
3             supports way more extension writing tasks and is 
4             supposed to replace ext_skel completely in the long run ...)
5
6WHAT IT IS
7
8  It's a tool for automatically creating the basic framework for a PHP module
9  and writing C code handling arguments passed to your functions from a simple
10  configuration file. See an example at the end of this file.
11
12HOW TO USE IT
13
14  Very simple. First, change to the ext/ directory of the PHP 4 sources. If
15  you just need the basic framework and will be writing all the code in your
16  functions yourself, you can now do
17
18   ./ext_skel --extname=module_name
19
20  and everything you need is placed in directory module_name. 
21
22  [ Note that GNU awk is likely required for this script to work.  Debian 
23    systems seem to default to using mawk, so you may need to change the 
24    #! line in skeleton/create_stubs and the cat $proto | awk line in
25    ext_skel to use gawk explicitly. ]
26
27  If you don't need to test the existence of any external header files, 
28  libraries or functions in them, the module is already almost ready to be 
29  compiled in PHP.  Just remove 3 comments in your_module_name/config.m4, 
30  change back up to PHP sources top directory, and do
31
32    ./buildconf; ./configure --enable-module_name; make
33
34  But if you already have planned the overall scheme of your module, what
35  functions it will contain, their return types and the arguments they take
36  (a very good idea) and don't want to bother yourself with creating function
37  definitions and handling arguments passed yourself, it's time to create a
38  function definitions file, which you will give as an argument to ext_skel
39  with option
40
41    --proto=filename.
42
43FORMAT OF FUNCTION DEFINITIONS FILE
44
45  All the definitions must be on one line. In it's simplest form, it's just
46  the function name, e.g.
47
48    my_function
49
50  but then you'll be left with an almost empty function body without any
51  argument handling.
52
53  Arguments are given in parenthesis after the function name, and are of
54  the form 'argument_type argument_name'. Arguments are separated from each
55  other with a comma and optional space. Argument_type can be one of int,
56  bool, double, float, string, array, object or mixed.
57
58  An optional argument is separated from the previous by an optional space,
59  then '[' and of course comma and optional space, like all the other
60  arguments. You should close a row of optional arguments with same amount of
61  ']'s as there where '['s. Currently, it does not harm if you forget to do it
62  or there is a wrong amount of ']'s, but this may change in the future.
63
64    An additional short description may be added after the parameters. 
65  If present it will be filled into the 'proto' header comments in the stubs
66  code and the <refpurpose> tag in the XML documentation.
67
68  An example:
69
70    my_function(int arg1, int arg2 [, int arg3 [, int arg4]]) this is my 1st
71
72  Arguments arg3 and arg4 are optional.
73
74  If possible, the function definition should also contain it's return type
75  in front of the definition. It's not actually used for any C code generating
76  purposes but PHP in-source documentation instead, and as such, very useful.
77  It can be any of int, double, string, bool, array, object, resource, mixed
78  or void.
79
80  The file must contain nothing else but function definitions, no comments or
81  empty lines.
82
83OTHER OPTIONS
84
85    --no-help
86
87  By default, ext_skel creates both comments in the source code and a test
88  function to help first time module writers to get started and testing
89  configuring and compiling their module. This option turns off all such things
90  which may just annoy experienced PHP module coders. Especially useful with
91
92    --stubs=file
93
94  which will leave out also all module specific stuff and write just function
95  stubs with function value declarations and passed argument handling, and
96  function entries and definitions at the end of the file, for copying and
97  pasting into an already existing module.
98
99    --assign-params
100    --string-lens
101
102  By default, function proto 'void foo(string bar)' creates the following:
103     ...
104     zval **bar;
105     ... (zend_get_parameters_ex() called in the middle...)
106     convert_to_string_ex(bar);
107
108  Specifying both of these options changes the generated code to:
109     ...
110     zval **bar_arg;
111     int bar_len;
112     char *bar = NULL;
113     ... (zend_get_parameters_ex() called in the middle...)
114     convert_to_string_ex(bar_arg);
115     bar = Z_STRVAL_PP(bar_arg);
116     bar_len = Z_STRLEN_PP(bar_arg);
117
118  You shouldn't have to ask what happens if you leave --string-lens out. If you
119  have to, it's questionable whether you should be reading this document.
120
121    --with-xml[=file]
122
123  Creates the basics for phpdoc .xml file.
124
125    --full-xml
126
127  Not implemented yet. When or if there will ever be created a framework for
128  self-contained extensions to use phpdoc system for their documentation, this
129  option enables it on the created xml file.
130
131CURRENT LIMITATIONS, BUGS AND OTHER ODDITIES
132
133  Only arguments of types int, bool, double, float, string and array are
134  handled. For other types you must write the code yourself. And for type
135  mixed, it wouldn't even be possible to write anything, because only you
136  know what to expect.
137  
138  It can't handle correctly, and probably never will, variable list of
139  of arguments. (void foo(int bar [, ...])
140
141  Don't trust the generated code too much. It tries to be useful in most of
142  the situations you might encounter, but automatic code generation will never
143  beat a programmer who knows the real situation at hand. ext_skel is generally
144  best suited for quickly generating a wrapper for c-library functions you
145  might want to have available in PHP too.
146
147  This program doesn't have a --help option. It has --no-help instead.
148
149EXAMPLE
150
151  The following _one_ line
152
153  bool my_drawtext(resource image, string text, resource font, int x, int y [, int color])
154
155  will create this function definition for you (note that there are a few
156  question marks to be replaced by you, and you must of course add your own
157  value definitions too):
158
159/* {{{ proto bool my_drawtext(resource image, string text, resource font, int x, int y[, int color])
160    */
161PHP_FUNCTION(my_drawtext)
162{
163    zval **image, **text, **font, **x, **y, **color;
164    int argc;
165    int image_id = -1;
166    int font_id = -1;
167
168    argc = ZEND_NUM_ARGS();
169    if (argc < 5 || argc > 6 || zend_get_parameters_ex(argc, &image, &text, &font, &x, &y, &color) == FAILURE) {
170        WRONG_PARAM_COUNT;
171    }
172
173    ZEND_FETCH_RESOURCE(???, ???, image, image_id, "???", ???_rsrc_id);
174    ZEND_FETCH_RESOURCE(???, ???, font, font_id, "???", ???_rsrc_id);
175
176    switch (argc) {
177        case 6:
178            convert_to_long_ex(color);
179            /* Fall-through. */
180        case 5:
181            convert_to_long_ex(y);
182            convert_to_long_ex(x);
183            /* font: fetching resources already handled. */
184            convert_to_string_ex(text);
185            /* image: fetching resources already handled. */
186            break;
187        default:
188            WRONG_PARAM_COUNT;
189    }
190
191    php_error(E_WARNING, "my_drawtext: not yet implemented");
192}
193/* }}} */
194
195

README.EXTENSIONS

1Between PHP 4.0.6 and 4.1.0, the Zend module struct changed in a way
2that broke both source and binary compatibility.  If you are
3maintaining a third party extension, here's how to update it:
4
5If this was your old module entry:
6
7zend_module_entry foo_module_entry = {
8    "foo",                /* extension name */
9    foo_functions,        /* extension function list */
10    NULL,                 /* extension-wide startup function */
11    NULL,                 /* extension-wide shutdown function */
12    PHP_RINIT(foo),       /* per-request startup function */
13    PHP_RSHUTDOWN(foo),   /* per-request shutdown function */
14    PHP_MINFO(foo),       /* information function */
15    STANDARD_MODULE_PROPERTIES
16};
17
18Here's how it should look if you want your code to build with PHP
194.1.0 and up:
20
21zend_module_entry foo_module_entry = {
22#if ZEND_MODULE_API_NO >= 20010901
23    STANDARD_MODULE_HEADER,
24#endif
25    "foo",                /* extension name */
26    foo_functions,        /* extension function list */
27    NULL,                 /* extension-wide startup function */
28    NULL,                 /* extension-wide shutdown function */
29    PHP_RINIT(foo),       /* per-request startup function */
30    PHP_RSHUTDOWN(foo),   /* per-request shutdown function */
31    PHP_MINFO(foo),       /* information function */
32#if ZEND_MODULE_API_NO >= 20010901
33    FOO_VERSION,          /* extension version number (string) */
34#endif
35    STANDARD_MODULE_PROPERTIES
36};
37
38If you don't care about source compatibility with earlier PHP releases
39than 4.1.0, you can drop the #if/#endif lines.
40

README.input_filter

1Input Filter Support in PHP 5
2-----------------------------
3
4XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
5and can be quite difficult to prevent.  Whenever you accept user data
6and somehow display this data back to users, you are likely vulnerable
7to XSS hacks.
8
9The Input Filter support in PHP 5 is aimed at providing the framework
10through which a company-wide or site-wide security policy can be
11enforced.  It is implemented as a SAPI hook and is called from the
12treat_data and post handler functions.  To implement your own security
13policy you will need to write a standard PHP extension.  There is also
14a powerful standard implementation in ext/filter that should suit most
15peoples' needs.  However, if you want to implement your own security 
16policy, read on.
17
18A simple implementation might look like the following.  This stores the
19original raw user data and adds a my_get_raw() function while the normal
20$_POST, $_GET and $_COOKIE arrays are only populated with stripped
21data.  In this simple example all I am doing is calling strip_tags() on
22the data.  If register_globals is turned on, the default globals that
23are created will be stripped ($foo) while a $RAW_foo is created with the
24original user input.
25
26ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
27        zval *post_array;
28        zval *get_array;
29        zval *cookie_array;
30ZEND_END_MODULE_GLOBALS(my_input_filter)
31
32#ifdef ZTS
33#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
34#else
35#define IF_G(v) (my_input_filter_globals.v)
36#endif
37
38ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
39
40zend_function_entry my_input_filter_functions[] = {
41    PHP_FE(my_get_raw,   NULL)
42    {NULL, NULL, NULL}
43};
44
45zend_module_entry my_input_filter_module_entry = {
46    STANDARD_MODULE_HEADER,
47    "my_input_filter",
48    my_input_filter_functions,
49    PHP_MINIT(my_input_filter),
50    PHP_MSHUTDOWN(my_input_filter),
51    NULL,
52    PHP_RSHUTDOWN(my_input_filter),
53    PHP_MINFO(my_input_filter),
54    "0.1",
55    STANDARD_MODULE_PROPERTIES
56};
57
58PHP_MINIT_FUNCTION(my_input_filter)
59{
60    ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
61
62    REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
63    REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
64    REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
65
66    sapi_register_input_filter(my_sapi_input_filter);
67    return SUCCESS;
68}
69
70PHP_RSHUTDOWN_FUNCTION(my_input_filter)
71{
72    if(IF_G(get_array)) {
73        zval_ptr_dtor(&IF_G(get_array));
74        IF_G(get_array) = NULL;
75    }
76    if(IF_G(post_array)) {
77        zval_ptr_dtor(&IF_G(post_array));
78        IF_G(post_array) = NULL;
79    }
80    if(IF_G(cookie_array)) {
81        zval_ptr_dtor(&IF_G(cookie_array));
82        IF_G(cookie_array) = NULL;
83    }
84    return SUCCESS;
85}
86
87PHP_MINFO_FUNCTION(my_input_filter)
88{
89    php_info_print_table_start();
90    php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
91    php_info_print_table_row( 2, "Revision", "$Revision$");
92    php_info_print_table_end();
93}
94
95/* The filter handler. If you return 1 from it, then PHP also registers the
96 * (modified) variable. Returning 0 prevents PHP from registering the variable;
97 * you can use this if your filter already registers the variable under a
98 * different name, or if you just don't want the variable registered at all. */
99SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
100{
101    zval new_var;
102    zval *array_ptr = NULL;
103    char *raw_var;
104    int var_len;
105
106    assert(*val != NULL);
107
108    switch(arg) {
109        case PARSE_GET:
110            if(!IF_G(get_array)) {
111                ALLOC_ZVAL(array_ptr);
112                array_init(array_ptr);
113                INIT_PZVAL(array_ptr);
114            }
115            IF_G(get_array) = array_ptr;
116            break;
117        case PARSE_POST:
118            if(!IF_G(post_array)) {
119                ALLOC_ZVAL(array_ptr);
120                array_init(array_ptr);
121                INIT_PZVAL(array_ptr);
122            }
123            IF_G(post_array) = array_ptr;
124            break;
125        case PARSE_COOKIE:
126            if(!IF_G(cookie_array)) {
127                ALLOC_ZVAL(array_ptr);
128                array_init(array_ptr);
129                INIT_PZVAL(array_ptr);
130            }
131            IF_G(cookie_array) = array_ptr;
132            break;
133    }
134    Z_STRLEN(new_var) = val_len;
135    Z_STRVAL(new_var) = estrndup(*val, val_len);
136    Z_TYPE(new_var) = IS_STRING;
137
138    var_len = strlen(var);
139    raw_var = emalloc(var_len+5);  /* RAW_ and a \0 */
140    strcpy(raw_var, "RAW_");
141    strlcat(raw_var,var,var_len+5);
142
143    php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
144
145    php_strip_tags(*val, val_len, NULL, NULL, 0);
146
147    *new_val_len = strlen(*val);
148    return 1;
149}
150
151PHP_FUNCTION(my_get_raw)
152{
153    long arg;
154    char *var;
155    int var_len;
156    zval **tmp;
157    zval *array_ptr = NULL;
158    HashTable *hash_ptr;
159    char *raw_var;
160
161    if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
162        return;
163    }
164
165    switch(arg) {
166        case PARSE_GET:
167            array_ptr = IF_G(get_array);
168            break;
169        case PARSE_POST:
170            array_ptr = IF_G(post_array);
171            break;
172        case PARSE_COOKIE:
173            array_ptr = IF_G(post_array);
174            break;
175    }
176
177    if(!array_ptr) RETURN_FALSE;
178
179    /*
180     * I'm changing the variable name here because when running with register_globals on,
181     * the variable will end up in the global symbol table
182     */
183    raw_var = emalloc(var_len+5);  /* RAW_ and a \0 */
184    strcpy(raw_var, "RAW_");
185    strlcat(raw_var,var,var_len+5);
186    hash_ptr = HASH_OF(array_ptr);
187
188    if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
189        *return_value = **tmp;
190        zval_copy_ctor(return_value);
191    } else {
192        RETVAL_FALSE;
193    }
194    efree(raw_var);
195}
196
197

README.PARAMETER_PARSING_API

1New parameter parsing functions
2===============================
3
4It should be easier to parse input parameters to an extension function.
5Hence, borrowing from Python's example, there are now a set of functions
6that given the string of type specifiers, can parse the input parameters
7and store the results in the user specified variables. This avoids most
8of the IS_* checks and convert_to_* conversions. The functions also
9check for the appropriate number of parameters, and try to output
10meaningful error messages.
11
12
13Prototypes
14----------
15/* Implemented. */
16int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);
17int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...);
18
19The zend_parse_parameters() function takes the number of parameters
20passed to the extension function, the type specifier string, and the
21list of pointers to variables to store the results in. The _ex() version
22also takes 'flags' argument -- current only ZEND_PARSE_PARAMS_QUIET can
23be used as 'flags' to specify that the function should operate quietly
24and not output any error messages.
25
26Both functions return SUCCESS or FAILURE depending on the result.
27
28The auto-conversions are performed as necessary. Arrays, objects, and
29resources cannot be auto-converted.
30
31
32Type specifiers
33---------------
34 a  - array
35 b  - boolean, stored in zend_bool
36 d  - double
37 f  - function or array containing php method call info (returned as 
38      zend_fcall_info* and zend_fcall_info_cache*)
39 h  - array (returned as HashTable*)
40 l  - long
41 o  - object (of any type)
42 O  - object (of specific type, specified by class entry)
43 r  - resource (stored in zval)
44 s  - string (with possible null bytes) and its length
45 z  - the actual zval
46
47 The following characters also have a meaning in the specifier string:
48    | - indicates that the remaining parameters are optional, they
49        should be initialized to default values by the extension since they
50        will not be touched by the parsing function if they are not
51        passed to it.
52    / - use SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows
53    ! - the parameter it follows can be of specified type or NULL (only applies
54        to 's', 'a', 'o', 'O', 'r', 'h', 'C', 'z', and 'Z'). If NULL is passed,
55        the results pointer is set to NULL as well.
56
57Examples
58--------
59/* Gets a long, a string and its length, and a zval */
60long l;
61char *s;
62int s_len;
63zval *param;
64if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsz",
65                          &l, &s, &s_len, &param) == FAILURE) {
66    return;
67}
68
69
70/* Gets an object of class specified by my_ce, and an optional double. */
71zval *obj;
72double d = 0.5;
73zend_class_entry *my_ce;
74if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|d",
75                          &obj, my_ce, &d) == FAILURE) {
76    return;
77}
78
79
80/* Gets an object or null, and an array.
81   If null is passed for object, obj will be set to NULL. */
82zval *obj;
83zval *arr;
84if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!a",
85                          &obj, &arr) == FAILURE) {
86    return;
87}
88
89
90/* Gets a separated array which can also be null. */
91zval *arr;
92if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!",
93                          &arr) == FAILURE) {
94    return;
95}
96
97
98/* Get only the first three parameters (useful for varargs functions). */
99zval *z;
100zend_bool b;
101zval *r;
102if (zend_parse_parameters(3 TSRMLS_CC, "zbr!",
103                          &z, &b, &r) == FAILURE) {
104    return;
105}
106
107
108/* Get either a set of 3 longs or a string. */
109long l1, l2, l3;
110char *s;
111/* 
112 * The function expects a pointer to a integer in this case, not a long
113 * or any other type.  If you specify a type which is larger
114 * than a 'int', the upper bits might not be initialized
115 * properly, leading to random crashes on platforms like
116 * Tru64 or Linux/Alpha.
117 */
118int length;
119
120if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
121                             "lll", &l1, &l2, &l3) == SUCCESS) {
122    /* manipulate longs */
123} else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
124                                    "s", &s, &length) == SUCCESS) {
125    /* manipulate string */
126} else {
127    /* output error */
128
129    return;
130}
131

README.PHP4-TO-PHP5-THIN-CHANGES

11. strrpos() and strripos() now use the entire string as a needle.  Be aware
2   that the existing scripts may no longer work as you expect.
3
4   EX :
5   <?php
6   var_dump(strrpos("ABCDEF","DEF"));
7   var_dump(strrpos("ABCDEF","DAF"));
8   ?>
9
10   Will give you different results. The former returns 3 while the latter
11   returns false rather than the position of the last occurrence of 'D'.
12   The same applies to strripos().
13
142. Illegal use of string offsets causes E_ERROR instead of E_WARNING.
15
16   EX :
17   <?php
18   $a = "foo";
19   unset($a[0][1][2]);
20   ?>
21
22   Fatal error: Cannot use string offset as an array in ... on line 1
23
243. array_merge() was changed to accept only arrays. If a non-array variable is
25   passed, a E_WARNING will be thrown for every such parameter. Be careful
26   because your code may start emitting E_WARNING out of the blue.
27
284. Be careful when porting from ext/mysql to ext/mysqli. The following
29   functions return NULL when no more data is available in the result set
30   (ext/mysql's functions return FALSE).
31
32    - mysqli_fetch_row()
33    - mysqli_fetch_array()
34    - mysqli_fetch_assoc()
35
365. PATH_TRANSLATED server variable is no longer set implicitly under
37   Apache2 SAPI in contrast to the situation in PHP 4, where it is set to the
38   same value as the SCRIPT_FILENAME server variable when it is not populated
39   by Apache.  This change was made to comply with the CGI specification.
40   Please refer to bug #23610 for further information.
41
426. Starting PHP 5.0.0 the T_ML_CONSTANT constant is no longer defined by the
43   ext/tokenizer extension. If error_reporting is set to E_ALL notices will
44   be produced. Instead of T_ML_CONSTANT for /* */ the T_COMMENT constant 
45   is used, thus both // and /* */ are resolved as the T_COMMENT constant.
46   However the PHPDoc style comments /** */ ,which starting PHP 5 are parsed
47   by PHP, are recongnized as T_DOC_COMMENT.
48
497. $_SERVER should be populated with argc and argv if variables_order
50   includes "S".  If you have specifically configured your system to not
51   create $_SERVER, then of course it shouldn't be there.  The change was to
52   always make argc and argv available in the CLI version regardless of the
53   variables_order setting.  As in, the CLI version will now always populate
54   the global $argc and $argv variables.
55
568. In some cases classes must be declared before used. It only happens only
57   if some of the new features of PHP 5 are used. Otherwise the behaviour is
58   the old.
59   Example 1 (works with no errors):
60   <?php
61   $a = new a();
62   class a {
63   }
64   ?>
65 
66   Example 2 (throws an error):
67   <?php 
68   $a = new a();
69   interface b{
70   }
71   class a implements b {
72   } 
73   ?>
74
75   Output (example 2) :
76   Fatal error: Class 'a' not found in /tmp/cl.php on line 2
77
789. get_class() starting PHP 5 returns the name of the class as it was
79   declared which may lead to problems in older scripts that rely on
80   the previous behaviour - the class name is lowercased. Expect the
81   same behaviour from get_parent_class() when applicable.
82   Example :
83   <?php
84   class FooBar {
85   }
86   class ExtFooBar extends FooBar{}
87   $a = new FooBar();
88   var_dump(get_class($a), get_parent_class($a));
89   ?>
90
91   Output (PHP 4):
92   string(6) "foobar"
93   string(9) "extfoobar"
94
95   Output (PHP 5):
96   string(6) "FooBar"
97   string(9) "ExtFooBar"
98   ----------------------------------------------------------------------
99   Example code that will break :
100   //....
101   function someMethod($p) {
102     if (get_class($p) != 'helpingclass') {
103       return FALSE;
104     }
105     //...
106   }
107   //...
108   Possible solution is to search for get_class() and get_parent_class() in
109   all your scripts and use strtolower().
110
11110. get_class_methods() returns the names of the methods of a class as they
112   declared. In PHP4 the names are all lowercased.
113   Example code :
114   <?php
115   class Foo{
116     function doFoo(){}
117     function hasFoo(){}
118   }
119   var_dump(get_class_methods("Foo")); 
120   ?>
121   Output (PHP4):
122   array(2) {
123     [0]=>
124     string(5) "dofoo"
125     [1]=>
126     string(6) "hasfoo"
127   }
128   Output (PHP5):
129   array(2) {
130     [0]=>
131     string(5) "doFoo"
132     [1]=>
133     string(6) "hasFoo"
134   }
135
13611. Assignment $this is impossible. Starting PHP 5.0.0 $this has special
137    meaning in class methods and is recognized by the PHP parser. The latter
138    will generate a parse error when assignment to $this is found
139    Example code :
140    <?php
141    class Foo {
142      function assignNew($obj) {
143        $this = $obj;
144      }
145    }
146    $a = new Foo();
147    $b = new Foo();
148    $a->assignNew($b);
149    echo "I was executed\n";
150    ?>
151    Output (PHP 4):
152    I was executed
153    Output (PHP 5):
154    PHP Fatal error:  Cannot re-assign $this in /tmp/this_ex.php on line 4
155
156

README.QNX

1QNX4 Installation Notes
2-----------------------
3
4NOTE: General installation instructions are in the INSTALL file 
5
6
71. To compile and test PHP3 you have to grab, compile and install:
8    - GNU dbm library or another db library;
9    - GNU bison (1.25 or later; 1.25 tested);
10    - GNU flex (any version supporting -o and -P options; 2.5.4 tested);
11    - GNU diffutils (any version supporting -w option; 2.7 tested);
12
132. To use CVS version you may need also:
14    - GNU CVS (1.9 tested);
15    - GNU autoconf (2.12 tested);
16    - GNU m4 (1.3 or later preferable; 1.4 tested);
17
183. To run configure define -lunix in command line:
19    LDFLAGS=-lunix ./configure
20
214. To use Sybase SQL Anywhere define ODBC_QNX and CUSTOM_ODBC_LIBS in
22    command line and run configure with --with-custom-odbc:
23    CFLAGS=-DODBC_QNX LDFLAGS=-lunix CUSTOM_ODBC_LIBS="-ldblib -lodbc" ./configure --with-custom-odbc=/usr/lib/sqlany50
24   If you have SQL Anywhere version 5.5.00, then you have to add 
25    CFLAGS=-DSQLANY_BUG
26   to workaround its SQLFreeEnv() bug. Other versions has not been tested,
27   so try without this flag first.
28
295. To build the Apache module, you may have to hardcode an include path for 
30   alloc.h in your Apache base directory:
31    - APACHE_DIRECTORY/src/httpd.h: 
32        change  #include "alloc.h"
33        to      #include "APACHE_DIRECTORY/src/alloc.h"
34   Unless you want to use system regex library, you have to hardcode also
35   a path to regex.h:
36    - APACHE_DIRECTORY/src/conf.h:  
37        change  #include <regex.h>
38        to      #include "APACHE_DIRECTORY/src/regex/regex.h"
39   I don't know so far why this required for QNX, may be it is Watcom 
40   compiler problem.
41
42  If you building Apache module with SQL Anywhere support, you'll get
43  symbol conflict with BOOL. It is defined in Apache (httpd.h) and in 
44  SQL Anywhere (odbc.h). This has nothing to do with PHP, so you have to 
45  fix it yourself someway.
46
476. With above precautions, it should compile as is and pass regression
48    tests completely:
49        make
50        make check
51        make install
52
53    Don't bother me unless you really sure you made that all but it 
54    still doesn't work.
55
56June 28, 1998
57Igor Kovalenko -- owl@infomarket.ru
58

README.SELF-CONTAINED-EXTENSIONS

1$Id$
2=============================================================================
3
4HOW TO CREATE A SELF-CONTAINED PHP EXTENSION
5
6  A self-contained extension can be distributed independently of
7  the PHP source. To create such an extension, two things are
8  required:
9
10  - Configuration file (config.m4)
11  - Source code for your module
12
13  We will describe now how to create these and how to put things
14  together.
15
16PREPARING YOUR SYSTEM
17
18  While the result will run on any system, a developer's setup needs these
19  tools:
20
21    GNU autoconf
22    GNU automake
23    GNU libtool
24    GNU m4
25
26  All of these are available from 
27
28    ftp://ftp.gnu.org/pub/gnu/
29
30CONVERTING AN EXISTING EXTENSION
31
32  Just to show you how easy it is to create a self-contained
33  extension, we will convert an embedded extension into a
34  self-contained one. Install PHP and execute the following
35  commands.
36  
37     $ mkdir /tmp/newext
38     $ cd /tmp/newext
39
40  You now have an empty directory. We will copy the files from
41  the mysql extension:
42
43     $ cp -rp php-4.0.X/ext/mysql/* .
44
45  It is time to finish the module. Run:
46
47     $ phpize
48
49  You can now ship the contents of the directory - the extension
50  can live completely on its own.
51
52  The user instructions boil down to
53
54     $ ./configure \
55            [--with-php-config=/path/to/php-config] \
56            [--with-mysql=MYSQL-DIR]
57     $ make install
58
59  The MySQL module will either use the embedded MySQL client 
60  library or the MySQL installation in MYSQL-DIR.
61
62
63DEFINING THE NEW EXTENSION
64
65  Our demo extension is called "foobar".
66
67  It consists of two source files "foo.c" and "bar.c"
68  (and any arbitrary amount of header files, but that is not
69  important here).
70  
71  The demo extension does not reference any external 
72  libraries (that is important, because the user does not
73  need to specify anything).
74
75
76  LTLIBRARY_SOURCES specifies the names of the sources files. You can
77  name an arbitrary number of source files here.
78
79CREATING THE M4 CONFIGURATION FILE
80
81  The m4 configuration can perform additional checks. For a 
82  self-contained extension, you do not need more than a few
83  macro calls.
84
85------------------------------------------------------------------------------
86PHP_ARG_ENABLE(foobar,whether to enable foobar,
87[  --enable-foobar            Enable foobar])
88
89if test "$PHP_FOOBAR" != "no"; then
90  PHP_NEW_EXTENSION(foobar, foo.c bar.c, $ext_shared)
91fi
92------------------------------------------------------------------------------
93
94  PHP_ARG_ENABLE will automatically set the correct variables, so
95  that the extension will be enabled by PHP_NEW_EXTENSION in shared mode.
96
97  The first argument of PHP_NEW_EXTENSION describes the name of the
98  extension.  The second names the source-code files.  The third passes
99  $ext_shared which is set by PHP_ARG_ENABLE/WITH to PHP_NEW_EXTENSION.
100  
101  Please use always PHP_ARG_ENABLE or PHP_ARG_WITH. Even if you do not
102  plan to distribute your module with PHP, these facilities allow you
103  to integrate your module easily into the main PHP module framework.
104
105CREATING SOURCE FILES
106
107  ext_skel can be of great help when creating the common code for all modules
108  in PHP for you and also writing basic function definitions and C code for
109  handling arguments passed to your functions. See README.EXT_SKEL for further
110  information.
111
112  As for the rest, you are currently alone here. There are a lot of existing
113  modules, use a simple module as a starting point and add your own code.
114
115
116CREATING THE SELF-CONTAINED EXTENSION
117
118  Put config.m4 and the source files into one directory. Then, run phpize
119  (this is installed during make install by PHP 4.0).
120
121  For example, if you configured PHP with --prefix=/php, you would run
122
123     $ /php/bin/phpize
124
125  This will automatically copy the necessary build files and create
126  configure from your config.m4.
127
128  And that's it. You now have a self-contained extension.
129
130INSTALLING A SELF-CONTAINED EXTENSION
131
132  An extension can be installed by running:
133
134     $ ./configure \
135            [--with-php-config=/path/to/php-config]
136     $ make install
137
138ADDING SHARED MODULE SUPPORT TO A MODULE
139
140  In order to be useful, a self-contained extension must be loadable
141  as a shared module. I will explain now how you can add shared module 
142  support to an existing module called foo.
143
144  1. In config.m4, use PHP_ARG_WITH/PHP_ARG_ENABLE. Then you will
145     automatically be able to use --with-foo=shared[,..] or
146     --enable-foo=shared[,..].
147
148  2. In config.m4, use PHP_NEW_EXTENSION(foo,.., $ext_shared) to enable
149     building the extension.
150
151  3. Add the following lines to your C source file:
152
153        #ifdef COMPILE_DL_FOO
154        ZEND_GET_MODULE(foo)
155        #endif
156

README.STREAMS

1An Overview of the PHP Streams abstraction
2==========================================
3$Id$
4
5WARNING: some prototypes in this file are out of date.
6The information contained here is being integrated into
7the PHP manual - stay tuned...
8
9Please send comments to: Wez Furlong <wez@thebrainroom.com>
10
11Why Streams?
12============
13You may have noticed a shed-load of issock parameters flying around the PHP
14code; we don't want them - they are ugly and cumbersome and force you to
15special case sockets and files every time you need to work with a "user-level"
16PHP file pointer.
17Streams take care of that and present the PHP extension coder with an ANSI
18stdio-alike API that looks much nicer and can be extended to support non file
19based data sources.
20
21Using Streams
22=============
23Streams use a php_stream* parameter just as ANSI stdio (fread etc.) use a
24FILE* parameter.
25
26The main functions are:
27
28PHPAPI size_t php_stream_read(php_stream * stream, char * buf, size_t count);
29PHPAPI size_t php_stream_write(php_stream * stream, const char * buf, size_t
30        count);
31PHPAPI size_t php_stream_printf(php_stream * stream TSRMLS_DC, 
32        const char * fmt, ...);
33PHPAPI int php_stream_eof(php_stream * stream);
34PHPAPI int php_stream_getc(php_stream * stream);
35PHPAPI char *php_stream_gets(php_stream * stream, char *buf, size_t maxlen);
36PHPAPI int php_stream_close(php_stream * stream);
37PHPAPI int php_stream_flush(php_stream * stream);
38PHPAPI int php_stream_seek(php_stream * stream, off_t offset, int whence);
39PHPAPI off_t php_stream_tell(php_stream * stream);
40PHPAPI int php_stream_lock(php_stream * stream, int mode);
41
42These (should) behave in the same way as the ANSI stdio functions with similar
43names: fread, fwrite, fprintf, feof, fgetc, fgets, fclose, fflush, fseek, ftell, flock.
44
45Opening Streams
46===============
47In most cases, you should use this API:
48
49PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode,
50    int options, char **opened_path TSRMLS_DC);
51
52Where:
53    path is the file or resource to open.
54    mode is the stdio compatible mode eg: "wb", "rb" etc.
55    options is a combination of the following values:
56        IGNORE_PATH  (default) - don't use include path to search for the file
57        USE_PATH        - use include path to search for the file
58        IGNORE_URL      - do not use plugin wrappers
59        REPORT_ERRORS   - show errors in a standard format if something
60                          goes wrong.
61        STREAM_MUST_SEEK - If you really need to be able to seek the stream
62                           and don't need to be able to write to the original
63                           file/URL, use this option to arrange for the stream
64                           to be copied (if needed) into a stream that can
65                           be seek()ed.
66                           
67    opened_path is used to return the path of the actual file opened,
68    but if you used STREAM_MUST_SEEK, may not be valid.  You are
69    responsible for efree()ing opened_path.  opened_path may be (and usually
70    is) NULL.
71
72If you need to open a specific stream, or convert standard resources into
73streams there are a range of functions to do this defined in php_streams.h.
74A brief list of the most commonly used functions:
75
76PHPAPI php_stream *php_stream_fopen_from_file(FILE *file, const char *mode);
77    Convert a FILE * into a stream.
78
79PHPAPI php_stream *php_stream_fopen_tmpfile(void);
80    Open a FILE * with tmpfile() and convert into a stream.
81
82PHPAPI php_stream *php_stream_fopen_temporary_file(const char *dir,
83    const char *pfx, char **opened_path TSRMLS_DC);
84    Generate a temporary file name and open it.
85
86There are some network enabled relatives in php_network.h:
87
88PHPAPI php_stream *php_stream_sock_open_from_socket(int socket, int persistent);
89    Convert a socket into a stream.
90
91PHPAPI php_stream *php_stream_sock_open_host(const char *host, unsigned short port,
92        int socktype, int timeout, int persistent);
93    Open a connection to a host and return a stream.
94
95PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent,
96    struct timeval *timeout);
97    Open a UNIX domain socket.
98   
99
100Stream Utilities
101================
102
103If you need to copy some data from one stream to another, you will be please
104to know that the streams API provides a standard way to do this:
105
106PHPAPI size_t php_stream_copy_to_stream(php_stream *src,
107    php_stream *dest, size_t maxlen);
108
109If you want to copy all remaining data from the src stream, pass
110PHP_STREAM_COPY_ALL as the maxlen parameter, otherwise maxlen indicates the
111number of bytes to copy.
112This function will try to use mmap where available to make the copying more
113efficient.
114
115If you want to read the contents of a stream into an allocated memory buffer,
116you should use:
117
118PHPAPI size_t php_stream_copy_to_mem(php_stream *src, char **buf,
119    size_t maxlen, int persistent);
120
121This function will set buf to the address of the buffer that it allocated,
122which will be maxlen bytes in length, or will be the entire length of the
123data remaining on the stream if you set maxlen to PHP_STREAM_COPY_ALL.
124The buffer is allocated using pemalloc(); you need to call pefree() to
125release the memory when you are done.
126As with copy_to_stream, this function will try use mmap where it can.
127
128If you have an existing stream and need to be able to seek() it, you
129can use this function to copy the contents into a new stream that can
130be seek()ed:
131
132PHPAPI int php_stream_make_seekable(php_stream *origstream, php_stream **newstream);
133
134It returns one of the following values:
135#define PHP_STREAM_UNCHANGED    0 /* orig stream was seekable anyway */
136#define PHP_STREAM_RELEASED     1 /* newstream should be used; origstream is no longer valid */
137#define PHP_STREAM_FAILED       2 /* an error occurred while attempting conversion */
138#define PHP_STREAM_CRITICAL     3 /* an error occurred; origstream is in an unknown state; you should close origstream */
139
140make_seekable will always set newstream to be the stream that is valid
141if the function succeeds.
142When you have finished, remember to close the stream.
143
144NOTE: If you only need to seek forward, there is no need to call this
145function, as the php_stream_seek can emulate forward seeking when the
146whence parameter is SEEK_CUR.
147
148NOTE: Writing to the stream may not affect the original source, so it
149only makes sense to use this for read-only use.
150
151NOTE: If the origstream is network based, this function will block
152until the whole contents have been downloaded.
153
154NOTE: Never call this function with an origstream that is referenced
155as a resource! It will close the origstream on success, and this
156can lead to a crash when the resource is later used/released.
157
158NOTE: If you are opening a stream and need it to be seekable, use the
159STREAM_MUST_SEEK option to php_stream_open_wrapper();
160
161PHPAPI int php_stream_supports_lock(php_stream * stream);
162
163This function will return either 1 (success) or 0 (failure) indicating whether or
164not a lock can be set on this stream. Typically you can only set locks on stdio streams.
165
166Casting Streams
167===============
168What if your extension needs to access the FILE* of a user level file pointer?
169You need to "cast" the stream into a FILE*, and this is how you do it:
170
171FILE * fp;
172php_stream * stream; /* already opened */
173
174if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void*)&fp, REPORT_ERRORS) == FAILURE)    {
175    RETURN_FALSE;
176}
177
178The prototype is:
179
180PHPAPI int php_stream_cast(php_stream * stream, int castas, void ** ret, int
181        show_err);
182
183The show_err parameter, if non-zero, will cause the function to display an
184appropriate error message of type E_WARNING if the cast fails.
185
186castas can be one of the following values:
187PHP_STREAM_AS_STDIO - a stdio FILE*
188PHP_STREAM_AS_FD - a generic file descriptor
189PHP_STREAM_AS_SOCKETD - a socket descriptor
190
191If you ask a socket stream for a FILE*, the abstraction will use fdopen to
192create it for you.  Be warned that doing so may cause buffered data to be lost
193if you mix ANSI stdio calls on the FILE* with php stream calls on the stream.
194
195If your system has the fopencookie function, php streams can synthesize a
196FILE* on top of any stream, which is useful for SSL sockets, memory based
197streams, data base streams etc. etc.
198
199In situations where this is not desirable, you should query the stream
200to see if it naturally supports FILE *.  You can use this code snippet
201for this purpose:
202
203    if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) {
204        /* can safely cast to FILE* with no adverse side effects */
205    }
206
207You can use:
208
209PHPAPI int php_stream_can_cast(php_stream * stream, int castas)
210
211to find out if a stream can be cast, without actually performing the cast, so
212to check if a stream is a socket you might use:
213
214if (php_stream_can_cast(stream, PHP_STREAM_AS_SOCKETD) == SUCCESS)  {
215    /* it can be a socket */
216}
217
218Please note the difference between php_stream_is and php_stream_can_cast;
219stream_is tells you if the stream is a particular type of stream, whereas
220can_cast tells you if the stream can be forced into the form you request.
221The former doesn't change anything, while the later *might* change some
222state in the stream.
223
224Stream Internals
225================
226
227There are two main structures associated with a stream - the php_stream
228itself, which holds some state information (and possibly a buffer) and a
229php_stream_ops structure, which holds the "virtual method table" for the
230underlying implementation.
231
232The php_streams ops struct consists of pointers to methods that implement
233read, write, close, flush, seek, gets and cast operations.  Of these, an
234implementation need only implement write, read, close and flush.  The gets
235method is intended to be used for streams if there is an underlying method
236that can efficiently behave as fgets.  The ops struct also contains a label
237for the implementation that will be used when printing error messages - the
238stdio implementation has a label of "STDIO" for example.
239
240The idea is that a stream implementation defines a php_stream_ops struct, and
241associates it with a php_stream using php_stream_alloc.
242
243As an example, the php_stream_fopen() function looks like this:
244
245PHPAPI php_stream * php_stream_fopen(const char * filename, const char * mode)
246{
247    FILE * fp = fopen(filename, mode);
248    php_stream * ret;
249    
250    if (fp) {
251        ret = php_stream_alloc(&php_stream_stdio_ops, fp, 0, 0, mode);
252        if (ret)
253            return ret;
254
255        fclose(fp);
256    }
257    return NULL;
258}
259
260php_stream_stdio_ops is a php_stream_ops structure that can be used to handle
261FILE* based streams.
262
263A socket based stream would use code similar to that above to create a stream
264to be passed back to fopen_wrapper (or it's yet to be implemented successor).
265
266The prototype for php_stream_alloc is this:
267
268PHPAPI php_stream * php_stream_alloc(php_stream_ops * ops, void * abstract,
269        size_t bufsize, int persistent, const char * mode)
270
271ops is a pointer to the implementation,
272abstract holds implementation specific data that is relevant to this instance
273of the stream,
274bufsize is the size of the buffer to use - if 0, then buffering at the stream
275level will be disabled (recommended for underlying sources that implement
276their own buffering - such a FILE*),
277persistent controls how the memory is to be allocated - persistently so that
278it lasts across requests, or non-persistently so that it is freed at the end
279of a request (it uses pemalloc),
280mode is the stdio-like mode of operation - php streams places no real meaning
281in the mode parameter, except that it checks for a 'w' in the string when
282attempting to write (this may change).
283
284The mode parameter is passed on to fdopen/fopencookie when the stream is cast
285into a FILE*, so it should be compatible with the mode parameter of fopen().
286
287Writing your own stream implementation
288======================================
289
290!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
291RULE #1: when writing your own streams: make sure you have configured PHP with
292--enable-debug.
293I've taken some great pains to hook into the Zend memory manager to help track
294down allocation problems.  It will also help you spot incorrect use of the
295STREAMS_DC, STREAMS_CC and the semi-private STREAMS_REL_CC macros for function
296definitions.
297!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
298
299RULE #2: Please use the stdio stream as a reference; it will help you
300understand the semantics of the stream operations, and it will always
301be more up to date than these docs :-)
302
303First, you need to figure out what data you need to associate with the
304php_stream.  For example, you might need a pointer to some memory for memory
305based streams, or if you were making a stream to read data from an RDBMS like
306MySQL, you might want to store the connection and rowset handles.
307
308The stream has a field called abstract that you can use to hold this data.
309If you need to store more than a single field of data, define a structure to
310hold it, allocate it (use pemalloc with the persistent flag set
311appropriately), and use the abstract pointer to refer to it.
312
313For structured state you might have this:
314
315struct my_state {
316    MYSQL conn;
317    MYSQL_RES * result;
318};
319
320struct my_state * state = pemalloc(sizeof(struct my_state), persistent);
321
322/* initialize the connection, and run a query, using the fields in state to
323 * hold the results */
324
325state->result = mysql_use_result(&state->conn);
326
327/* now allocate the stream itself */
328stream = php_stream_alloc(&my_ops, state, 0, persistent, "r");
329
330/* now stream->abstract == state */
331
332Once you have that part figured out, you can write your implementation and
333define the your own php_stream_ops struct (we called it my_ops in the above
334example).
335
336For example, for reading from this weird MySQL stream:
337
338static size_t php_mysqlop_read(php_stream * stream, char * buf, size_t count)
339{
340    struct my_state * state = (struct my_state*)stream->abstract;
341
342    if (buf == NULL && count == 0)  {
343        /* in this special case, php_streams is asking if we have reached the
344         * end of file */
345        if (... at end of file ...)
346            return EOF;
347        else
348            return 0;
349    }
350    
351    /* pull out some data from the stream and put it in buf */
352    ... mysql_fetch_row(state->result) ...
353    /* we could do something strange, like format the data as XML here,
354        and place that in the buf, but that brings in some complexities,
355        such as coping with a buffer size too small to hold the data,
356        so I won't even go in to how to do that here */
357}
358
359Implement the other operations - remember that write, read, close and flush
360are all mandatory.  The rest are optional.  Declare your stream ops struct:
361
362php_stream_ops my_ops = {
363    php_mysqlop_write, php_mysqlop_read, php_mysqlop_close,
364    php_mysqlop_flush, NULL, NULL, NULL,
365    "Strange MySQL example"
366}
367
368Thats it!
369
370Take a look at the STDIO implementation in streams.c for more information
371about how these operations work.
372The main thing to remember is that in your close operation you need to release
373and free the resources you allocated for the abstract field.  In the case of
374the example above, you need to use mysql_free_result on the rowset, close the
375connection and then use pefree to dispose of the struct you allocated.
376You may read the stream->persistent field to determine if your struct was
377allocated in persistent mode or not.
378
379vim:tw=78:et
380

README.SUBMITTING_PATCH

1Submitting Patch for PHP
2========================
3
4This document describes how to submit a patch for PHP. Since you are
5reading this document, you are willing to submit a patch for PHP.
6Please keep reading! Submitting a patch for PHP is easy. The hard
7part is making it acceptable for inclusion into our repository. :-)
8
9How to create patch?  
10-------------------- 
11We use Subversion (SVN) for revision control.  You need to get the
12source from SVN in order to create a patch.  Read
13http://www.php.net/svn.php for help on using SVN.  You can check out
14older branches, but make sure you get trunk as well and make your
15patch work there.
16
17Read CODING_STANDARDS file before you start working.
18
19Now you are ready to create a patch. Modify source to fix a bug in PHP or
20add a new feature to PHP. After you finished editing, please test your
21patch. Read README.TESTING for testing.
22
23After you finish testing your patch, take diff file using 
24"svn diff > your.patch" command.
25
26Read README.TESTING for submitting a test script for your patch. This is
27not strictly required, but it is preferred to submit a test script along
28with your patch. Making new test script is very easy. It also helps us
29to understand what you have been fixed or added to PHP.
30
31
32Tips for creating patch 
33----------------------- 
34If you would like to fix multiple bugs. It is easier for us if you
35could create 1 patch for 1 bug, but this is not strictly required.
36Note though that you might get little response, if your patch is
37too hard to review.
38
39If you would like change/add many lines, it is better to ask module
40maintainer and/or internals@lists.php.net, or pear-dev@lists.php.net if
41you are patching PEAR. Official module maintainers can be found in
42EXTENSIONS file in PHP source.
43
44If you are new to SVN (Subversion), visit
45http://svnbook.red-bean.com/ for details.
46
47
48Check list for submitting patch
49-------------------------------
50 - Did you run "make test" to check if your patch didn't break
51   other features?
52 - Did you compile PHP with --enable-debug and check the PHP and
53   web server error logs when you test your patch?
54 - Did you build PHP for multi-threaded web servers. (Optional)
55 - Did you create test script for "make test"? (Recommended)
56 - Did you update SVN source before you take final patch?
57 - Did you read the patch again?
58
59
60Where to send your patch?
61-------------------------
62If you are patching C source, send the patch to internals@lists.php.net. 
63If you are patching a module, you should also send the patch to the 
64maintainer. Official module maintainers are listed in EXTENSION file 
65in source.
66
67If you are patching PEAR, send the patch to pear-dev@lists.php.net.
68
69Please add the prefix "[PATCH]" to your email subject and make sure
70to include the patch as a MIME attachment even if it is short. 
71
72NOTE: only MIME attachments of type 'text/*' are accepted. The
73      easiest way to accomplish this, is to make the extension
74      '.txt'.
75
76Test scripts should be included in the same email.
77Explain what has been fixed/added/changed by your patch.
78
79Finally, add the bug Id(s) which can be closed by your patch, if any.
80
81
82What happens after you submit your patch
83---------------------------------------- 
84If your patch is easy to review and has obviously no side-effects,
85it might take up to a few hours until someone commits it.
86
87Because this is a volunteer-driven effort, more complex patches will
88require more patience on your side. 
89
90If you did not receive any feedback in a few days, please consider
91resubmitting the description of your patch, along-side with
92these questions:
93
94- Is my patch too hard to review? Because of which factors?
95- Should I split it up in multiple parts?
96- Are there any unwanted whitespace changes?
97
98
99What happens when your patch is applied?
100---------------------------------------- 
101Your name will be included together with your email address in the SVN 
102commit log. If your patch affects end-users, a brief description
103and your name might be added to the NEWS file.
104
105
106Thank you for submitting patch for PHP!
107

README.SVN-RULES

1====================
2  SVN Commit Rules
3====================
4
5This is the first file you should be reading after you get your SVN account.
6We'll assume you're basically familiar with SVN, but feel free to post
7your questions on the mailing list. Please have a look at
8http://svnbook.red-bean.com/ for more detailed information on SVN.
9
10PHP is developed through the efforts of a large number of people.
11Collaboration is a Good Thing(tm), and SVN lets us do this. Thus, following
12some basic rules with regards to SVN usage will::
13
14   a. Make everybody happier, especially those responsible for maintaining
15      the SVN itself.
16
17   b. Keep the changes consistently well documented and easily trackable.
18
19   c. Prevent some of those 'Oops' moments.
20
21   d. Increase the general level of good will on planet Earth.
22
23Having said that, here are the organizational rules::
24
25   1. Respect other people working on the project.
26
27   2. Discuss any significant changes on the list before committing and get
28      confirmation from the release manager for the given branch.
29
30   3. Look at EXTENSIONS file to see who is the primary maintainer of
31      the code you want to contribute to.
32
33   4. If you "strongly disagree" about something another person did, don't
34      start fighting publicly - take it up in private email.
35
36   5. If you don't know how to do something, ask first!
37
38   6. Test your changes before committing them. We mean it. Really.
39      To do so use "make test".
40
41   7. For development use the --enable-maintainer-zts switch to ensure your
42      code handles TSRM correctly and doesn't break for thos who need that.
43
44Currently we have the following branches in use::
45
46  trunk             Will become PHP 6.0. This CVS branch is for active development.
47
48  branches/PHP_5_3  Is used to release the PHP 5.3.x series. It still allows for
49                    larger enhancements.
50
51  branches/PHP_5_2  Is used to release the PHP 5.2.x series. Only bugfixes are permitted
52                    on this branch (Consult the releasemaster prior to commit).
53
54  branches/PHP_5_1  This branch is closed.
55
56  branches/PHP_4_4  This branch is closed.
57
58The next few rules are more of a technical nature::
59
60   1. All changes should first go to trunk and then get merged from trunk
61      (aka MFH'ed) to all other relevant branches.
62
63   2. DO NOT TOUCH ChangeLog! It is automagically updated from the commit
64      messages every day. Woe be to those who attempt to mess with it.
65
66   3. All news updates intended for public viewing, such as new features,
67      bug fixes, improvements, etc., should go into the NEWS file of the
68      *first* to be released version with the given change. In other words
69      any NEWS file change only needs to done in one branch.
70
71      NB! Lines, starting with @ will go automagically into NEWS file, but
72      this is NOT recommended, though. Please, add news entries directly to
73      NEWS file and don't forget to keep them adjusted and sorted.
74
75   4. Do not commit multiple file and dump all messages in one commit. If you
76      modified several unrelated files, commit each group separately and
77      provide a nice commit message for each one. See example below.
78
79   5. Do write your commit message in such a way that it makes sense even
80      without the corresponding diff. One should be able to look at it, and
81      immediately know what was modified. Definitely include the function name
82      in the message as shown below.
83
84   6. In your commit messages, keep each line shorter than 80 characters. And
85      try to align your lines vertically, if they wrap. It looks bad otherwise.
86
87   7. If you modified a function that is callable from PHP, prepend PHP to
88      the function name as shown below.
89
90
91The format of the commit messages is pretty simple.
92
93Use a - to start a new item in your commit message.
94
95If a line begins with #, it is taken to be a comment and will not appear
96in the ChangeLog. Everything else goes into the ChangeLog.
97
98It is important to note that if your comment or news logline spans multiple
99lines, you have to put # at the beginning of **every** such line.
100
101Example. Say you modified two files, datetime.c and string.c. In datetime.c you
102added a new format option for the date() function, and in string.c you fixed a
103memory leak in php_trim(). Don't commit both of these at once. Commit them
104separately and try to make sure your commit messages look something like the
105following.
106
107For datetime.c::
108
109  - Added new 'K' format modifier to date() for printing out number of days
110    until New Year's Eve.
111
112For string.c::
113
114  - Fixed a memory leak in php_trim() resulting from improper use of zval_dtor().
115  #- Man, that thing was leaking all over the place!
116
117The # lines will be omitted from the ChangeLog automagically.
118
119Use the [DOC] tag in your log message whenever you feel that your changes
120imply a documentation modification. The php-doc team will automatically
121get notified about your commit through the php-doc mailing list.
122
123If you fix some bugs, you should note the bug ID numbers in your
124commit message. Bug ID should be prefixed by "#" for easier access to
125bug report when developers are browsing CVS via LXR or Bonsai.
126
127Example::
128
129  Fixed bug #14016 (pgsql notice handler double free crash bug.)
130
131If you don't see your messages in ChangeLog right away, don't worry!
132These files are updated once a day, so your stuff will not show up until
133somewhat later.
134
135When you change the NEWS file for a bug fix, then please keep the bugs
136sorted in decreasing order under the fixed version.
137
138You can use LXR (http://lxr.php.net/) and Bonsai (http://bonsai.php.net/)
139to look at PHP SVN repository in various ways.
140
141To receive daily updates to ChangeLog and NEWS, send an empty message to
142php-cvs-daily-subscribe@lists.php.net.
143
144Happy hacking,
145
146PHP Team
147

README.TESTING

1[IMPORTANT NOTICE]
2------------------
3 Failed tests usualy indicate a problem with your local system setup
4and not within PHP itself (at least for official PHP release versions).
5You may decide to automaticaly submit a test summary to our QA workflow
6at the end of a test run.
7 Please do *not* submit a failed test as a bug or ask for help on why
8it failed on your system without providing substantial backup information
9on *why* the test failed on your special setup. Thank you :-)
10
11
12[Testing Basics] 
13----------------
14 The easiest way to test your PHP build is to run "make test" from the
15command line after successfully compiling. This will run the complete
16tests for all enabled functionalities and extensions using the PHP
17CLI binary.
18 To execute test scripts, you must build PHP with some SAPI, then you
19type "make test" to execute all or some test scripts saved under
20"tests" directory under source root directory.
21
22Usage:
23make test
24
25 "make test" basically executes "run-tests.php" script
26under the source root (parallel builds will not work). Therefore you
27can execute the script as follows:
28
29TEST_PHP_EXECUTABLE=sapi/cli/php \
30sapi/cli/php [-c /path/to/php.ini] run-tests.php [ext/foo/tests/GLOB]
31
32
33[Which "php" executable "make test" look for]
34---------------------------------------------
35If you are running the run-tests.php script from the command line (as above)
36you must set the TEST_PHP_EXECUTABLE environment variable to explicitly
37select the PHP executable that is to be tested, that is, used to run the test scripts.
38
39If you run the tests using make test, the PHP CLI and CGI executables are 
40automatically set for you. "make test" executes "run-tests.php" script with the CLI binary.  Some
41test scripts such as session must be executed by CGI SAPI. Therefore,
42you must build PHP with CGI SAPI to perform all tests.
43
44NOTE: PHP binary executing "run-tests.php" and php binary used for
45executing test scripts may differ. If you use different PHP binary for
46executing "run-tests.php" script, you may get errors.
47
48
49[Which php.ini is used]
50-----------------------
51 "make test" uses the same php.ini file as it would once installed.
52The tests have been written to be independent of that php.ini file,
53so if you find a test that is affected by a setting, please report
54this, so we can address the issue.
55
56
57[Which test scripts are executed]
58---------------------------------
59 "run-tests.php" ("make test"), without any arguments executes all
60test scripts by extracting all directories named "tests"
61from the source root and any subdirectories below. If there are files,
62which have a "phpt" extension, "run-tests.php" looks at the sections
63in these files, determines whether it should run it, by evaluating
64the 'SKIP' section. If the test is eligible for execution, the 'FILE'
65section is extracted into a ".php" file (with the same name besides 
66the extension) and gets executed.
67When an argument is given or TESTS environment variable is set, the
68GLOB is expanded by the shell and any file with extension "*.phpt" is
69regarded as a test file.
70
71 Tester can easily execute tests selectively with as follows.
72
73Examples:
74./sapi/cli/php run-tests.php ext/mbstring/*
75./sapi/cli/php run-tests.php ext/mbstring/020.phpt
76
77
78[Test results]
79--------------
80 Test results are printed to standard output. If there is a failed test, 
81the "run-tests.php" script saves the result, the expected result and the
82code executed to the test script directory. For example, if 
83ext/myext/tests/myext.phpt fails to pass, the following files are created:
84
85ext/myext/tests/myext.php   - actual test file executed
86ext/myext/tests/myext.log   - log of test execution (L)
87ext/myext/tests/myext.exp   - expected output (E)
88ext/myext/tests/myext.out   - output from test script (O)
89ext/myext/tests/myext.diff  - diff of .out and .exp (D)
90
91 Failed tests are always bugs. Either the test is bugged or not considering
92factors applying to the tester's environment, or there is a bug in PHP.
93If this is a known bug, we strive to provide bug numbers, in either the
94test name or the file name. You can check the status of such a bug, by
95going to: http://bugs.php.net/12345 where 12345 is the bug number.
96For clarity and automated processing, bug numbers are prefixed by a hash
97sign '#' in test names and/or test cases are named bug12345.phpt.
98
99NOTE: The files generated by tests can be selected by setting the
100environment variable TEST_PHP_LOG_FORMAT. For each file you want to be
101generated use the character in brackets as shown above (default is LEOD).
102The php file will be generated always.
103
104NOTE: You can set environment variable TEST_PHP_DETAILED to enable
105detailed test information.
106
107[Automated testing]
108 If you like to keep up to speed, with latest developments and quality
109assurance, setting the environment variable NO_INTERACTION to 1, will not
110prompt the tester for any user input.
111
112Normally, the exit status of "make test" is zero, regardless of the results
113of independent tests. Set the environment variable REPORT_EXIT_STATUS to 1,
114and "make test" will set the exit status ("$?") to non-zero, when an
115individual test has failed.
116
117Example script to be run by cron(1):
118========== qa-test.sh =============
119#!/bin/sh
120
121CO_DIR=$HOME/cvs/php5
122MYMAIL=qa-test@domain.com
123TMPDIR=/var/tmp
124TODAY=`date +"%Y%m%d"`
125
126# Make sure compilation enviroment is correct
127CONFIGURE_OPTS='--disable-all --enable-cli --with-pcre'
128export MAKE=gmake
129export CC=gcc
130
131# Set test environment
132export NO_INTERACTION=1
133export REPORT_EXIT_STATUS=1
134
135cd $CO_DIR
136cvs update . >>$TMPDIR/phpqatest.$TODAY
137./cvsclean ; ./buildconf ; ./configure $CONFIGURE_OPTS ; $MAKE
138$MAKE test >>$TMPDIR/phpqatest.$TODAY 2>&1
139if test $? -gt 0
140then
141        cat $TMPDIR/phpqatest.$TODAY | mail -s"PHP-QA Test Failed for $TODAY" $MYMAIL
142fi
143========== end of qa-test.sh =============
144
145NOTE: the exit status of run-tests.php will be 1 when
146REPORT_EXIT_STATUS is set. The result of "make test" may be higher
147than that. At present, gmake 3.79.1 returns 2, so it is
148advised to test for non-zero, rather then a specific value.
149
150
151[Creating new test files]
152-------------------------
153 Writing test file is very easy if you are used to PHP. 
154See the HOWTO at http://qa.php.net/write-test.php
155
156
157[How to help us]
158----------------
159 If you find bug in PHP, you can submit bug report AND test script 
160for us. You don't have to write complete script, just give us test
161script with following format. Please test the script and make sure
162you write the correct ACTUAL OUTPUT and EXPECTED OUTPUT before you
163submit.
164
165<?php
166/* 
167Bug #12345
168substr() bug. Do not return expected string.
169
170ACTUAL OUTPUT
171XYXA
172
173EXPECTED OUTPUT
174ABCD
175*/
176
177$str = "XYZABCD";
178echo substr($str,3,7);
179
180?>
181

README.TESTING2

1[IMPORTANT NOTICE]
2------------------
3This is an addendum to README.TESTING with additional information 
4specific to server-tests.php.
5
6server-tests.php is backward compatible with tests developed for
7the original run-tests.php script.  server-tests is *not* used by
8'make test'.  server-tests was developed to provide support for
9testing PHP under it's primary environment, HTTP, and can run the
10PHP tests under any of the SAPI modules that are direct executables, 
11or are accessable via HTTP.
12
13[New features]
14----------------
15* Command line interface:
16  You can run 'php server-tests.php -h' to get all the possible options.
17* Configuration file:
18  the -c argument will allow you to use a configuration file.  This is
19  handy if you are testing multiple environments and need various options
20  depending on the environment.
21  see server-tests-config.php for details.
22* CGI Emulation:
23  Will emulate a CGI environment when testing with the cgi sapi executable.
24* HTTP testing:
25  can be configured to run test scripts through an HTTP server running
26  on localhost.  localhost is required since either the web server must
27  alias a directory to the php source directory, or the test scripts
28  must be copied to a directory under the web server 
29  (see config options TEST_WEB_BASE_URL, TEST_BASE_PATH, and TEST_WEB_EXT)
30* New sections supported for test files (see below)
31
32When running tests over http, tests that require ini settings different that what
33the web server runs under will be skipped.  Since the test harness defines a number
34of ini settings by default, the web server may require special configuration to
35make testing work.
36
37[Example Usage]
38----------------
39Some (but not all!) examples of usage:
40
411. run tests from the php source directory
42    php server-tests.php -p /path/to/php-cli
43
442. run tests using cgi emulation
45    php server-tests.php -p /path/to/php-cgi
46
473. run tests over http, copying test files into document root
48    php server-tests.php -w -u http://localhost/test -m /path/to/htdocs/test
49
504. run tests over http, php sources have been aliased in web server
51    php server-tests.php -w -u http://localhost/test
52    
535. run tests using configuration file
54    php server-tests.php -c /path/to/server-tests-config.php
55
566. run tests using configuration file, but overriding some settings:
57   (config file must be first)
58    php server-tests.php -c /path/to/server-tests-config.php -w -t 3 -d /path/to/testdir
59
60NOTE: configuration as described in README.TESTING still works.
61
62[New Test Sections] 
63----------------
64In addition to the traditional test sections 
65(see http://qa.php.net/write-test.php), several new sections are available 
66under server-tests.
67
68--POST--
69This is not a new section, but not multipart posts are supported for testing
70file uploads, or other types of POST data.
71
72--CGI--
73This section takes no value.  It merely provides a simple marker for tests
74that MUST be run as CGI, even if there is no --POST-- or --GET-- sections
75in the test file.
76
77--DESCRIPTION--
78Not used for anything, just a section for documenting the test
79
80--ENV--
81This section get's eval()'d to help build an environment for the 
82execution of the test.  This can be used to change environment
83vars that are used for CGI emulation, or simply to set env vars
84for cli testing.  A full example looks like:
85
86  --ENV--
87  return <<<END
88  PATH_TRANSLATED=$filename
89  PATH_INFO=$scriptname
90  SCRIPT_NAME=$scriptname
91  END;
92
93Some variables are made easily available for use in this section, they
94include:
95  $filename     full native path to file, will become PATH_TRANSLATED
96  $filepath     =dirname($filename)
97  $scriptname   this is what will become SCRIPT_NAME unless you override it
98  $docroot      the equivelant of DOCUMENT_ROOT under Apache
99  $cwd          the directory that the test is being initiated from
100  $this->conf   all server-tests configuration vars
101  $this->env    all environment variables that will get passed to the test
102
103
104--REQUEST--
105This section is also eval'd, and is similar in nature to --ENV--.  However,
106this section is used to build the url used in an HTTP request.  Valid values
107to set in this section would include:
108  SCRIPT_NAME   The inital part of the request url
109  PATH_INFO     The pathinfo part of a request url
110  FRAGMENT      The fragment section of a url (after #)
111  QUERY_STRING  The query part of a url (after ?)
112
113  --REQUEST--
114  return <<<END
115  PATH_INFO=/path/info
116  END;
117
118--HEADERS--
119This section is also eval'd.  It is used to provide additional headers sent
120in an HTTP request, such as content type for multipart posts, cookies, etc.
121
122  --HEADERS--
123  return <<<END
124  Content-Type=multipart/form-data; boundary=---------------------------240723202011929
125  Content-Length=100
126  END;
127
128--EXPECTHEADERS--
129This section can be used to define what headers are required to be
130received back from a request, and is checked in addition to the
131regular expect sections.  For example:
132
133  --EXPECTHEADERS--
134  Status: 404
135
136
137
138

README.UNIX-BUILD-SYSTEM

1PHP Build System V5 Overview
2
3- supports Makefile.ins during transition phase
4- not-really-portable Makefile includes have been eliminated
5- supports separate build directories without VPATH by using
6  explicit rules only
7- does not waste disk-space/CPU-time for building temporary libraries
8  => especially noticeable on slower systems
9- slow recursive make replaced with one global Makefile
10- eases integration of proper dependencies
11- adds PHP_DEFINE(what[, value]) which creates a single include-file
12  per what.  This will allow more fine-grained dependencies.
13- abandoning the "one library per directory" concept
14- improved integration of the CLI
15- several new targets
16  build-modules: builds and copies dynamic modules into modules/
17  install-cli: installs the CLI only, so that the install-sapi
18               target does only what its name says
19- finally abandoned automake (still requires aclocal at this time)
20- changed some configure-time constructs to run at buildconf-time
21- upgraded shtool to 1.5.4
22- removed $(moduledir) (use EXTENSION_DIR)
23
24The Reason For a New System
25
26It became more and more apparent that there is a severe need
27for addressing the portability concerns and improving the chance
28that your build is correct (how often have you been told to
29"make clean"? When this is done, you won't need to anymore).
30
31
32If You Build PHP on a Unix System
33
34
35You, as a user of PHP, will notice no changes.  Of course, the build
36system will be faster, look better and work smarter.
37
38
39
40If You Are Developing PHP
41
42
43
44
45Extension developers:
46
47Makefile.ins are abandoned.  The files which are to be compiled
48are specified in the config.m4 now using the following macro:
49
50PHP_NEW_EXTENSION(foo, foo.c bar.c baz.cpp, $ext_shared)
51
52E.g. this enables the extension foo which consists of three source-code
53modules, two in C and one in C++.  And, depending on the user's wishes,
54the extension will even be built as a dynamic module.
55
56The full syntax:
57
58PHP_NEW_EXTENSION(extname, sources [, shared [,sapi_class[, extra-cflags]]])
59
60Please have a look at acinclude.m4 for the gory details and meanings
61of the other parameters.
62
63And that's basically it for the extension side.
64
65If you previously built sub-libraries for this module, add
66the source-code files here as well.  If you need to specify
67separate include directories, do it this way:
68
69PHP_NEW_EXTENSION(foo, foo.c mylib/bar.c mylib/gregor.c,,,-I@ext_srcdir@/lib)
70
71E.g. this builds the three files which are located relative to the
72extension source directory and compiles all three files with the
73special include directive (@ext_srcdir@ is automatically replaced).
74
75Now, you need to tell the build system that you want to build files
76in a directory called $ext_builddir/lib:
77
78PHP_ADD_BUILD_DIR($ext_builddir/lib)
79
80Make sure to call this after PHP_NEW_EXTENSION, because $ext_builddir
81is only set by the latter.
82
83If you have a complex extension, you might to need add special
84Make rules.  You can do this by calling PHP_ADD_MAKEFILE_FRAGMENT
85in your config.m4 after PHP_NEW_EXTENSION.
86
87This will read a file in the source-dir of your extension called
88Makefile.frag.  In this file, $(builddir) and $(srcdir) will be
89replaced by the values which are correct for your extension
90and which are again determined by the PHP_NEW_EXTENSION macro.
91
92Make sure to prefix *all* relative paths correctly with either
93$(builddir) or $(srcdir).  Because the build system does not
94change the working directory anymore, we must use either
95absolute paths or relative ones to the top build-directory.
96Correct prefixing ensures that.
97
98
99SAPI developers:
100
101Instead of using PHP_SAPI=foo/PHP_BUILD_XYZ, you will need to type
102
103PHP_SELECT_SAPI(name, type, sources.c)
104
105I.e. specify the source-code files as above and also pass the
106information regarding how PHP is supposed to be built (shared
107module, program, etc).
108
109For example for APXS:
110
111PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php5.c php_apache.c)
112
113
114
115General info
116
117The foundation for the new system is the flexible handling of
118sources and their contexts.  With the help of macros you
119can define special flags for each source-file, where it is
120located, in which target context it can work, etc.
121
122Have a look at the well documented macros
123PHP_ADD_SOURCES(_X) in acinclude.m4.
124

README.UPDATE_5_2

1PHP 5.2 UPDATE INFO
2
3===============================
4Changes in PHP datetime support
5===============================
6
7Since PHP 5.1, there has been an extension named 'date' in the PHP core. This
8is the new implementation of PHP's datetime support. Although it will attempt
9to guess your system's timezone setting, you should set the timezone manually.
10You can do this in any of three ways:
11
121) in your php.ini using the date.timezone INI directive
132) on your system using the TZ environmental variable
143) from your script using the convenience function date_default_timezone_set()
15
16All supported timezones are listed in the PHP Manual at
17http://www.php.net/manual/timezones.php.
18
19With the advent of PHP 5.2, there are object representations of the date and
20timezone, named DateTime and DateTimeZone respectively. You can see the methods
21and constants available to the new classes by running
22
23php --rc DateTime
24php --rc DateTimeZone
25
26under PHP CLI - or see the PHP Manual under Date/Time functions, or the 'NEW
27FEATURES' section below. All methods map to existing procedural date functions.
28
29==================================
30Items from the NEWS file explained
31==================================
32
33- Added new error mode E_RECOVERABLE_ERROR. (Derick, Marcus, Tony)
34
35  Some of the existing E_ERROR conditions have been converted to something that
36  you can catch with a user-defined error handler. If an E_RECOVERABLE_ERROR is
37  not handled, it will behave in the same way as E_ERROR behaves in all versions
38  of PHP. Errors of this type are logged as 'Catchable fatal error'.
39
40
41- Changed E_ALL error reporting mode to include E_RECOVERABLE_ERROR. (Marcus)
42
43  This change means that the value of the E_ALL error_reporting constant is now
44  6143, where the previous value was 2047. If you are setting the error_reporting
45  mode from either the Apache config file or the .htaccess files, you will need
46  to adjust the value accordingly. The same applies if you use the numeric value
47  rather than the constant in your PHP scripts.
48
49
50- Added support for constructors in interfaces to force constructor signature
51  checks in implementations. (Marcus)
52
53  Starting with PHP 5.2, interfaces can have constructors. However, if you choose
54  to declare a constructor in an interface, each class implementing that interface
55  MUST include a constructor with a signature matching that of the base interface
56  constructor. By 'signature' we mean the parameter and return type definitions,
57  including any type hints and including whether the data is passed by reference
58  or by value.
59
60
61- Changed __toString to be called wherever applicable. (Marcus)
62
63  The magic method __toString() will now be called in a string context, that
64  is, anywhere an object is used as a string. When implementing your __toString()
65  method in a class, you should be aware that the script will terminate if
66  your function throws an exception.
67
68  The PHP 5.0/5.1 fallback - returning a string that contains the object
69  identifier - has been dropped in PHP 5.2. It became problematic because
70  an object identifier cannot be considered unique. This change will mean
71  that your application is flawed if you have relied on the object identifier
72  as a return value. An attempt to use that value as a string will now result
73  in a catchable fatal error (see above).
74
75  Even with __toString(), objects cannot be used as array indices or keys. We
76  may add built-in hash support for this at a later date, but for PHP 5.2 you
77  will need to either provide your own hashing or use the new SPL function
78  spl_object_hash().
79
80
81- Added RFC2397 (data: stream) support. (Marcus)
82
83  The introduction of the 'data' URL scheme has the potential to lead to a
84  change of behaviour under Windows. If you are working with an NTFS
85  file system and making use of meta streams in your application, and if you
86  just happen to be using a file with the name 'data:' that is accessed without
87  any path information - it won't work any more. The fix is to use the 'file:'
88  protocol when accessing it.
89
90  There is information about the RFC at http://www.faqs.org/rfcs/rfc2397.html.
91
92
93- Added allow_url_include ini directive to complement allow_url_fopen. (Rasmus)
94
95  This useful option makes it possible to differentiate between standard
96  file operations on remote files, and the inclusion of remote files. While the
97  former is usually desirable, the latter can be a security risk if used naively.
98  Starting with PHP 5.2, you can allow remote file operations while
99  disallowing the inclusion of remote files in local scripts. In fact, this
100  is the default configuration.
101
102
103- Dropped abstract static class functions. (Marcus)
104
105  Due to an oversight, PHP 5.0 and 5.1 allowed abstract static functions in
106  classes. In PHP 5.2, only interfaces can have them.
107
108
109- Removed extensions (Derick, Tony)
110
111  The filepro and hwapi extensions have been moved to PECL and are no longer
112  part of the PHP distribution. The PECL package version of these extensions
113  will be created according to user demand.
114
115
116- Added extensions (Rasmus, Derick, Pierre)
117
118  The JSON extension implements the JavaScript Object Notation (JSON)
119  data interchange format. This extension is enabled by default.
120
121  The Filter extension validates and filters data, and is designed for
122  use with insecure data such as user input. This extension is enabled
123  by default; the default mode RAW does not impact input data in any way.
124
125  The Zip extension enables you to transparently read or write ZIP
126  compressed archives and the files inside them.
127
128  Please refer to the NEW FEATURES section below or to the PHP Manual
129  for details.
130
131
132- Improved memory manager and increased default memory limit (Dmitry)
133
134  The new memory manager allocates less memory and works faster than the
135  previous incarnation. It allocates memory from the system in large blocks,
136  and then manages the heap by itself. The memory_limit value in php.ini is
137  checked, not for each emalloc() call (as before), but for actual blocks
138  requested from the system. This means that memory_limit is far more
139  accurate than it used to be, since the old memory manager didn't calculate
140  all the memory overhead used by the malloc library.
141
142  Thanks to this new-found accuracy memory usage may appear to have increased,
143  although actually it has not. To accommodate this apparent increase, the
144  default memory_limit setting was also increased - from 8 to 16 megabytes.
145
146
147- Changed priority of PHPRC environment variable on win32 (Dmitry)
148
149  The PHPRC environment variable now takes priority over the path stored
150  in the Windows registry.
151
152
153- CLI SAPI no longer checks cwd for php.ini or the php-cli.ini file (Edin)
154
155  In PHP 5.1 an undocumented feature was added that made the CLI binary check
156  the current working directory for a PHP configuration file, potentially
157  leading to unpredictable behavior if an unexpected configuration file were
158  read. This functionality was removed in 5.2, and PHP will no longer search
159  CWD for the presence of php.ini or php-cli.ini files.
160
161
162- Added a notice when performing modulus 0 operation (Tony)
163
164  In earlier versions of PHP, performing integer % 0 did not emit any
165  warning messages, instead returning an unexpected return value of FALSE.
166  As of PHP 5.2 this operation will emit an E_WARNING, as is the case in all
167  other instances where division by zero is performed.
168
169
170- As a side-effect of a change made to prevent duplicate error messages
171  when error_tracking is On [Ilia], it is now necessary to return FALSE
172  from your error handler in order to populate $php_errormsg. This allows
173  you to fine-grain the levels of the messages stored.
174
175==============================
176Regressions introduced/fixed
177==============================
178
179- In version 5.2.4 a security fix caused a regression for patterns of
180  the form "/foo/*/bar/*". Since version 5.2.5 instead of raising a warning the
181  glob() function will return false when openbase_dir restrictions are violated.
182
183  #See http://bugs.php.net/bug.php?id=41655
184
185  The warning that used to be raised looked like something as follows:
186  Warning: glob() [function.glob]: Unable to access /foo/*/bar/* in /foo.php on line xxx
187  #See http://cvs.php.net/viewvc.cgi/php-src/ext/standard/dir.c?r1=1.169&r2=1.170
188
189  The patch can safely be applied to PHP 5.2.4 as well.
190
191==============================
192Backwards incompatible changes
193==============================
194
195In the PHP core
196===============
197getrusage() will return NULL when passed incompatible arguments
198As of 5.2.1 #See http://cvs.php.net/viewvc.cgi/php-src/ext/standard/microtime.c?r1=1.57&r2=1.58 && ?r1=1.53.2.2&r2=1.53.2.2.2.1
199
200In ext/zip
201==========
202ZipArchive::setCommentName() now returns TRUE on success
203ZipArchive::setCommentIndex() now return TRUE on success
204As of 5.2.1 #See http://cvs.php.net/viewvc.cgi/php-src/ext/zip/php_zip.c?r1=1.1.2.15&r2=1.1.2.16
205
206In ext/spl
207==========
208SplFileObject::getFilename() now returns the filename, not relative/path/to/file
209As of 5.2.1 #See http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/spl_directory.c?r1=1.45.2.27.2.10&r2=1.45.2.27.2.11
210==================
211NEW ERROR MESSAGES
212==================
213
214In the PHP core
215===============
216
217<?php
218
219print 10%0;
220/* Warning:  Division by zero in filename on line n */
221
222echo " ";
223session_regenerate_id();
224/*  Warning:  session_regenerate_id(): Cannot regenerate session id - headers already sent in filename on line n */
225
226str_word_count("string", 4);
227/* Warning:  str_word_count(): Invalid format value 4 in filename on line n */
228
229strripos("foo", "f", 4);
230/* Notice:  strripos(): Offset is greater than the length of haystack string in filename on line n */
231
232strrpos("foo", "f", 4);
233/* Notice:  strrpos(): Offset is greater than the length of haystack string in filename on line n */
234
235/* when allow_url_include is OFF (default) */
236include "data:;base64,PD9waHAgcGhwaW5mbygpOz8+";
237/* Warning:  include(): URL file-access is disabled in the server configuration in filename on line n */
238
239/* when allow_url_include is OFF (default) */
240include "php://input";
241/* Warning:  include(): URL file-access is disabled in the server configuration in filename on line n */
242As of 5.2.1 #See http://cvs.php.net/viewvc.cgi/php-src/ext/standard/php_fopen_wrapper.c?r1=1.45.2.4.2.3&r2=1.45.2.4.2.4
243
244?>
245
246OO related in the PHP core
247==========================
248
249<?php
250
251interface foo {
252}
253class bar implements foo, foo {
254}
255/* Fatal error: Class bar cannot implement previously implemented interface foo in filename on line n */
256
257
258class foo {
259    public $bar;
260    function __get($var)
261    {
262        return $this->bar;
263    }
264}
265
266$foo = new foo;
267$bar =& $foo->prop;
268/* Notice: Indirect modification of overloaded property foo::$prop has no effect in filename on line n */
269
270
271class foo implements iterator {
272    public function current() {
273
274    }
275    public function next() {
276
277    }
278    public function key() {
279
280    }
281    public function valid() {
282
283    }
284    public function rewind() {
285
286    }
287}
288
289$foo = new foo();
290foreach($foo as &$ref) {}
291/* Fatal error: An iterator cannot be used with foreach by reference in filename on line n */
292
293
294class foo {
295    private function __construct() {
296    }
297}
298class bar extends foo {
299    public function __construct() {
300        parent::__construct();
301        /* Fatal error:  Cannot call private foo::__construct() in filename on line n */
302    }
303}
304new bar;
305
306
307abstract class foo {
308    abstract static function bar();
309    /* Strict Standards:  Static function foo::bar() should not be abstract in filename on line n */
310}
311
312
313stream_filter_register("", "class");
314/* Warning:  stream_filter_register(): Filter name cannot be empty in filename on line n */
315
316stream_filter_register("filter", "");
317/* Warning:  stream_filter_register(): Class name cannot be empty in filename on line n */
318
319
320class foo {
321    public function __toString() {
322        throw new Exception;
323    }
324}
325try {
326    print new foo;
327    /* Fatal error:  Method foo::__toString() must not throw an exception in filename on line n */
328} catch(Exception $e) {}
329
330
331class foo {}
332$foo = new foo;
333print $foo;
334/* Catchable fatal error:  Object of class foo could not be converted to string in filename on line n */
335
336?>
337
338In the bzip2 extension
339======================
340
341<?php
342
343bzopen("", "w");
344/* Warning:  bzopen(): filename cannot be empty in filename on line n */
345
346bzopen("foo", "a");
347/* Warning:  bzopen(): 'a' is not a valid mode for bzopen(). Only 'w' and 'r' are supported in filename on line n */
348
349$fp = fopen("foo", "w");
350bzopen($fp, "r");
351/* Warning:  bzopen(): cannot read from a stream opened in write only mode in filename on line n */
352
353?>
354
355In the date extension
356=====================
357
358<?php
359
360strtotime("today", "now");'
361/* Warning:  strtotime() expects parameter 2 to be long, string given in filename on line n */
362
363new DateTime(new stdclass);
364/* Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct() expects parameter 1 to be string, object given' in filename:n */
365As of 5.2.1 #See http://cvs.php.net/viewvc.cgi/php-src/ext/date/php_date.c?r1=1.43.2.45.2.33&r2=1.43.2.45.2.34
366?>
367
368In the dBase extension
369======================
370
371<?php
372
373dbase_open("foo", -1);
374/* Warning: Invalid access mode -1 in filename on line n */
375
376dbase_open("foo", null);
377/* Warning: The filename cannot be empty in filename on line n */
378As of 5.2.1 #See http://cvs.php.net/viewvc.cgi/php-src/ext/dbase/dbase.c?r1=1.74.2.2.2.5&r2=1.74.2.2.2.6&diff_format=u
379?>
380
381In the mcrypt extension
382=======================
383
384<?php
385
386$key = "this is a secret key";
387
388$td = mcrypt_module_open('tripledes', '', 'ecb', '');
389$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
390mcrypt_generic_init($td, $key, $iv);
391$encrypted_data = mcrypt_generic($td, "");
392/* Warning: mcrypt_generic(): An empty string was passed in filename on line n */
393
394?>
395
396In the oci8 extension
397=====================
398
399<?php
400
401oci_connect("user", "pass", "db", "bogus_charset");
402/* Warning: Invalid character set name: bogus_charset in filename on line n */
403
404$oci = oci_connect("user", "pass", "db");
405oci_password_change($oci, "", "old", "new");
406/* Warning: username cannot be empty in filename on line n */
407
408oci_password_change($oci, "user", "", "new");
409/* Warning: old password cannot be empty in filename on line n */
410
411oci_password_change($oci, "user", "old", "");
412/* Warning: new password cannot be empty in filename on line n */
413
414?>
415
416In the SPL extension
417====================
418
419<?php
420
421$obj = new SplFileObject(__FILE__);
422$obj->fgetcsv("foo");
423/* Warning:  SplFileObject::fgetcsv(): delimiter must be a character in filename on line n */
424
425$obj->fgetcsv(",", "foo");
426/* Warning:  SplFileObject::fgetcsv(): enclosure must be a character in filename on line n */
427
428?>
429
430In the sysvmsg extension
431========================
432<?php
433
434/* Warning:  maximum size of the message has to be greater then zero in filename on line n */
435
436?>
437
438In the Zip extension
439====================
440<?php
441$obj = new ZipArchive();
442$obj->open("archive.zip");
443$obj->setCommentName("", "comment");'
444/* Notice:  ZipArchive::setCommentName(): Empty string as entry name in filename on line n */
445
446$obj->getCommentName("");
447/* Notice:  ZipArchive::getCommentName(): Empty string as entry name in filename on line n */
448As of 5.2.1 #See http://cvs.php.net/viewvc.cgi/php-src/ext/zip/php_zip.c?r1=1.1.2.15&r2=1.1.2.16
449?>
450
451
452============
453NEW FEATURES
454============
455
456New extensions
457==============
458
459  Filter
460    Methods:
461      mixed filter_has_var(constant type, string variable_name)
462        - Returns true if the variable with the name 'name' exists in source
463      int filter_id(string filtername)
464        - Returns the filter ID belonging to a named filter
465      mixed filter_input(constant type, string variable_name [, long filter [, mixed options]])
466        - Returns the filtered variable 'name'* from source `type`
467      mixed filter_input_array(constant type, [, mixed options]])
468        - Returns an array with all arguments defined in 'definition'
469      array filter_list()
470        - Returns a list of all supported filters
471      mixed filter_var(mixed variable [, long filter [, mixed options]])
472        - Returns the filtered version of the variable.
473      mixed filter_var_array(array data, [, mixed options]])
474        - Returns an array with all arguments defined in 'definition'
475
476  JSON
477    Methods:
478      mixed json_decode(string json[, boolean assoc=0])
479        - Decodes a JSON string into a PHP object/associative array
480      string json_encode(mixed parameter)
481        - Takes a object or an array and returns a JSON encoded string
482
483  Zip
484    Class constants:
485      ZipArchive::CHECKCONS
486      ZipArchive::CM_DEFAULT
487      ZipArchive::CM_DEFLATE
488      ZipArchive::CM_DEFLATE64
489      ZipArchive::CM_IMPLODE
490      ZipArchive::CM_PKWARE_IMPLODE
491      ZipArchive::CM_REDUCE_1
492      ZipArchive::CM_REDUCE_2
493      ZipArchive::CM_REDUCE_3
494      ZipArchive::CM_REDUCE_4
495      ZipArchive::CM_SHRINK
496      ZipArchive::CM_STORE
497      ZipArchive::CREATE
498      ZipArchive::ER_CHANGED
499      ZipArchive::ER_CLOSE
500      ZipArchive::ER_COMPNOTSUPP
501      ZipArchive::ER_CRC
502      ZipArchive::ER_DELETED
503      ZipArchive::ER_EOF
504      ZipArchive::ER_EXISTS
505      ZipArchive::ER_INCONS
506      ZipArchive::ER_INTERNAL
507      ZipArchive::ER_INVAL
508      ZipArchive::ER_MEMORY
509      ZipArchive::ER_MULTIDISK
510      ZipArchive::ER_NOENT
511      ZipArchive::ER_NOZIP
512      ZipArchive::ER_OK
513      ZipArchive::ER_OPEN
514      ZipArchive::ER_READ
515      ZipArchive::ER_REMOVE
516      ZipArchive::ER_RENAME
517      ZipArchive::ER_SEEK
518      ZipArchive::ER_TMPOPEN
519      ZipArchive::ER_WRITE
520      ZipArchive::ER_ZIPCLOSED
521      ZipArchive::ER_ZLIB
522      ZipArchive::EXCL
523      ZipArchive::FL_COMPRESSED
524      ZipArchive::FL_NOCASE
525      ZipArchive::FL_NODIR
526      ZipArchive::FL_UNCHANGED
527      ZipArchive::OVERWRITE
528
529    Functions:
530      void zip_close(resource zip)
531        - Close a Zip archive
532      void zip_entry_close(resource zip_ent)
533        - Close a zip entry
534      int zip_entry_compressedsize(resource zip_entry)
535        - Return the compressed size of a Zip entry
536      string zip_entry_compressionmethod(resource zip_entry)
537        - Return a string containing the compression method used on a particular entry
538      int zip_entry_filesize(resource zip_entry)
539        - Return the actual filesize of a Zip entry
540      string zip_entry_name(resource zip_entry)
541        - Return the name given a Zip entry
542      bool zip_entry_open(resource zip_dp, resource zip_entry [, string mode])
543        - Open a Zip File, pointed by the resource entry
544      mixed zip_entry_read(resource zip_entry [, int len])
545        - Read from an open directory entry
546      resource zip_open(string filename)
547        - Create new zip using source URI for output
548      resource zip_read(resource zip)
549        - Returns the next file in the archive
550    Methods:
551      bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length]]])
552        - Add a file in a Zip archive using its path and the name to use
553      bool ZipArchive::addFromString(string name, string content)
554        - Add a file using content and the entry name
555      void ZipArchive::close()
556        - close the zip archive
557      bool ZipArchive::deleteIndex(int index)
558        - Delete a file using its index
559      bool ZipArchive::deleteName(string name)
560        - Delete a file using its index
561      bool ZipArchive::extractTo(string pathto[, mixed files])
562        - Extract one or more file from a zip archive to a specified destination
563      string ZipArchive::getArchiveComment()
564        - Returns the Zip archive comment
565      string ZipArchive::getCommentIndex(int index)
566        - Returns the comment of an entry using its index
567      string ZipArchive::getCommentName(string name)
568        - Returns the comment of an entry using its name
569      string ZipArchive::getFromName(string entryname[, int len [, int flags]])
570        - get the contents of an entry using its name
571      string ZipArchive::getFromIndex(string entryname[, int len [, int flags]])
572        - get the contents of an entry using its index
573      string ZipArchive::getNameIndex(int index [, int flags])
574        - Returns the name of the file at position index
575      resource ZipArchive::getStream(string entryname)
576        - Get a stream for an entry using its name
577      int ZipArchive::locateName(string filename[, int flags])
578        - Returns the index of the entry named filename in the archive
579      mixed ZipArchive::open(string source [, int flags])
580        - Create new zip using source URI for output, return TRUE on success or the error code
581      bool ZipArchive::renameIndex(int index, string new_name)
582        - Rename an entry selected by its index to new_name
583      bool ZipArchive::renameName(string name, string new_name)
584        - Rename an entry selected by its name to new_name
585      bool ZipArchive::setArchiveComment(string name, string comment)
586        - Set or remove (NULL/'') the comment of the archive
587      bool ZipArchive::setCommentIndex(int index, string comment)
588        - Set or remove (NULL/'') the comment of an entry using its index
589      bool ZipArchive::setCommentName(string name, string comment)
590        - Set or remove (NULL/'') the comment of an entry using its Name
591      array ZipArchive::statIndex(int index[, int flags])
592        - Returns the zip entry information using its index
593      array ZipArchive::statName(string filename[, int flags])
594        - Returns the information about a the zip entry filename
595      bool ZipArchive::unchangeAll()
596        - All changes made to the archive are reverted
597      bool ZipArchive::unchangeArchive()
598        - Revert all global changes to the archive.  For now, this only reverts archive comment changes
599      bool ZipArchive::unchangeIndex(int index)
600        - Changes to the file at position index are reverted
601      bool ZipArchive::unchangeName(string name)
602        - Changes to the file named 'name' are reverted
603
604
605New classes
606===========
607
608  DateTime:
609    Constants:
610      DateTime::ATOM
611      DateTime::COOKIE
612      DateTime::ISO8601
613      DateTime::RFC822
614      DateTime::RFC850
615      DateTime::RFC1036
616      DateTime::RFC1123
617      DateTime::RFC2822
618      DateTime::RFC3339
619      DateTime::RSS
620      DateTime::W3C
621    Methods:
622      DateTime::__construct([string time[, DateTimeZone object]])
623      - Returns new DateTime object
624      string DateTime::format(string format)
625      - Returns date formatted according to given format
626      long DateTime::getOffset()
627      - Returns the DST offset
628      DateTimeZone DateTime::getTimezone()
629      - Return new DateTimeZone object relative to give DateTime
630      void DateTime::modify(string modify)
631      - Alters the timestamp
632      array DateTime::parse(string date)
633      - Returns associative array with detailed info about given date
634      void DateTime::setDate(long year, long month, long day)
635      - Sets the date
636      void DateTime::setISODate(long year, long week[, long day])
637      - Sets the ISO date
638      void DateTime::setTime(long hour, long minute[, long second])
639      - Sets the time
640      void DateTime::setTimezone(DateTimeZone object)
641      - Sets the timezone for the DateTime object
642
643  DateTimeZone:
644    Methods:
645      DateTimeZone DateTimeZone::__construct(string timezone)
646      - Returns new DateTimeZone object
647      string DateTimeZone::getName()
648      - Returns the name of the timezone
649      long DateTimeZone::getOffset(DateTime object)
650      - Returns the timezone offset
651      array DateTimeZone::getTransitions()
652      - Returns numerically indexed array containing associative array for all transitions for the timezone
653
654  RecursiveRegexIterator:
655      extends RegexIterator
656      implements OuterIterator, Traversable, Iterator, RecursiveIterator
657    Methods:
658      RecursiveRegexIterator::__construct(RecursiveIterator it, string regex [, int mode [, int flags [, int preg_flags]]])
659        Create an RecursiveRegexIterator from another recursive iterator and a regular expression
660      RecursiveRegexIterator RecursiveRegexIterator::getChildren()
661        Return the inner iterator's children contained in a RecursiveRegexIterator
662      bool RecursiveRegexIterator::hasChildren()
663        Check whether the inner iterator's current element has children
664
665  RegexIterator:
666      extends FilterIterator
667      implements Iterator, Traversable, OuterIterator
668    Constants:
669      RecursiveRegexIterator::ALL_MATCHES
670      RecursiveRegexIterator::GET_MATCH
671      RecursiveRegexIterator::MATCH
672      RecursiveRegexIterator::REPLACE
673      RecursiveRegexIterator::SPLIT
674      RecursiveRegexIterator::USE_KEY
675    Properties:
676      public $replacement
677    Methods:
678      RegexIterator::__construct(Iterator it, string regex [, int mode [, int flags [, int preg_flags]]])
679        - Create an RegexIterator from another iterator and a regular expression
680      bool RegexIterator::accept()
681        - Match (string)current() against regular expression
682      bool RegexIterator::getFlags()
683        - Returns current operation flags
684      bool RegexIterator::getMode()
685        - Returns current operation mode
686      bool RegexIterator::getPregFlags()
687        - Returns current PREG flags (if in use or NULL)
688      bool RegexIterator::setFlags(int new_flags)
689        - Set operation flags
690      bool RegexIterator::setMode(int new_mode)
691        - Set new operation mode
692      bool RegexIterator::setPregFlags(int new_flags)
693        - Set PREG flags
694
695
696New methods
697===========
698
699In ext/dom
700==========
701    DOMDocument:
702      DOMDocument::registerNodeClass(string baseclass, string extendedclass)
703        - Register extended class used to create base node type
704
705    DOMElement:
706      DOMElement::setIDAttribute(string name, boolean isId)
707        - Declares the attribute specified by name to be of type ID
708      DOMElement::setIDAttributeNode(DOMAttr idAttr, boolean isId)
709        - Declares the attribute specified by node to be of type ID
710      DOMElement::setIDAttributeNS(string namespaceURI, string localName, boolean isId)
711        - Declares the attribute specified by local name and namespace URI to be of type ID
712
713    DOMNode:
714      DOMNode::C14N([bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
715        - Canonicalize nodes to a string
716      DOMNode::C14NFile(string uri [, bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
717        - Canonicalize nodes to a file
718      DOMNode::getNodePath()
719        - Gets an xpath for a node
720
721In ext/soap
722===========
723    SoapServer:
724      SoapServer::setObject(object obj)
725        - Sets object which will handle SOAP requests
726
727In ext/spl
728==========
729    ArrayObject:
730      int ArrayObject::asort(void)
731        - Sort the entries by values
732      int ArrayObject::ksort(void)
733        - Sort the entries by key
734      int ArrayObject::natcasesort(void)
735        - Sort the entries by key using case insensitive "natural order" algorithm.
736      int ArrayObject::natsort(void)
737        - Sort the entries by values using "natural order" algorithm.
738      int ArrayObject::uasort(callback cmp_function)
739        - Sort the entries by values user defined function
740      int ArrayObject::uksort(callback cmp_function)
741        - Sort the entries by key using user defined function.
742
743    AppendIterator:
744      ArrayIterator AppendIterator::getArrayIterator()
745        Get access to inner ArrayIterator
746      int AppendIterator::getIteratorIndex()
747        Get index of iterator
748
749    CachingIterator:
750      bool CachingIterator::getCache()
751        Return the cache
752      int CachingIterator::getFlags()
753        Return the internal flags
754      bool CachingIterator::offsetExists(mixed index)
755        Return whether the requested index exists
756      string CachingIterator::offsetGet(mixed index)
757        - Return the internal cache if used
758      void CachingIterator::offsetSet(mixed index, mixed newval)
759        - Set given index in cache
760      void CachingIterator::offsetUnset(mixed index)
761        - Unset given index in cache
762      void CachingIterator::setFlags()
763        Set the internal flags
764
765    SplFileObject:
766      array("delimiter" =>, "enclosure" =>) SplFileObject::getCsvControl(void)
767        - Get the delimiter and enclosure character used in fgetcsv
768      void SplFileObject::setCsvControl([string delimiter = ',' [, string enclosure = '"']])
769        - Set the delimiter and enclosure character used in fgetcsv
770
771    XMLReader:
772      boolean XMLReader::setSchema(string filename)
773        Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first Read()
774
775In ext/zip
776==========
777    ZipArchive:
778      bool addEmptyDir(string dirname)
779        Creates an empty directory in the archive
780As of 5.2.1 #See http://cvs.php.net/viewvc.cgi/php-src/ext/zip/php_zip.c?r1=1.1.2.15&r2=1.1.2.16
781
782New class constants
783===================
784
785In ext/pdo
786==========
787  PDO::ATTR_DEFAULT_FETCH_MODE
788  PDO::FETCH_PROPS_LATE
789
790In ext/spl
791==========
792  CachingIterator::FULL_CACHE
793  CachingIterator::TOSTRING_USE_INNER
794
795  SplFileObject::READ_AHEAD
796  SplFileObject::READ_CSV
797  SplFileObject::SKIP_EMPTY
798
799
800New functions
801=============
802
803In the PHP core
804===============
805    array array_fill_keys(array keys, mixed val)
806      - Create an array using the elements of the first parameter as keys, each initialized to val
807    array error_get_last()
808      - Get the last occurred error as associative array. Returns NULL if there hasn't been an error yet
809    string image_type_to_extension(int imagetype [, bool include_dot])
810      - Get file extension for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype
811    int memory_get_peak_usage([real_usage])
812      - Returns the peak allocated by PHP memory
813    array timezone_abbreviations_list()
814     - Returns associative array containing DST, offset and the timezone name
815    array timezone_identifiers_list()
816     - Returns numerically indexed array with all timezone identifiers
817    string timezone_name_from_abbr(string abbr[, long gmtOffset[, long isdst]])
818     - Returns the timezone name from abbreviation
819As of 5.2.1: #See http://cvs.php.net/viewvc.cgi/php-src/ext/standard/streamsfuncs.c?r1=1.58.2.6.2.9&r2=1.58.2.6.2.10&diff_format=u
820    int stream_socket_shutdown(resource stream, int how)
821     - Causes all or part of a full-duplex connection on the socket associated with stream to be shut down
822
823In ext/mbstring
824===============
825    array mb_list_encodings_alias_names([string encoding])
826      - Returns an array of all supported entity encodings
827    mixed mb_list_mime_names([string encoding])
828      - Returns an array or string of all supported mime names
829    int mb_stripos(string haystack, string needle [, int offset [, string encoding]])
830      - Finds position of first occurrence of a string within another, case insensitive
831    string mb_stristr(string haystack, string needle[, bool part[, string encoding]])
832      - Finds first occurrence of a string within another, case insensitive
833    string mb_strrchr(string haystack, string needle[, bool part[, string encoding]])
834      - Finds the last occurrence of a character in a string within another
835    string mb_strrichr(string haystack, string needle[, bool part[, string encoding]])
836      - Finds the last occurrence of a character in a string within another, case insensitive
837    int mb_strripos(string haystack, string needle [, int offset [, string encoding]])
838      - Finds position of last occurrence of a string within another, case insensitive
839    string mb_strstr(string haystack, string needle[, bool part[, string encoding]])
840      - Finds first occurrence of a string within another
841
842In ext/ming
843===========
844As of 5.2.1: See http://cvs.php.net/viewvc.cgi/php-src/ext/ming/ming.c?r1=1.79.2.4.2.4&r2=1.79.2.4.2.5&diff_format=u
845    void ming_setSWFCompression(int num)
846     - Sets output compression
847    void swfmovie::namedanchor(string name)
848     - Creates anchor
849    void swfmovie::protect([string pasword])
850     - Protects
851
852In ext/openssl
853==============
854    resource openssl_csr_get_public_key(mixed csr)
855      - Extracts public key from a CERT and prepares it for use
856    array openssl_csr_get_subject(mixed csr [, bool use_short_names])
857      - Returns the subject of a CERT
858    array openssl_pkey_get_details(resource key)
859      - returns an array with the key details (bits, pkey, type)
860
861In ext/spl
862==========
863    string spl_object_hash(object obj)
864      - Return hash id for given object
865    int iterator_apply(Traversable it, mixed function [, mixed params])
866      - Calls a function for every element in an iterator
867
868In ext/pcre
869===========
870    int preg_last_error(void)
871      - Returns the error code of the last regex execution
872
873In ext/pgsql
874============
875    mixed pg_field_table(resource result, int field_number[, bool oid_only])
876      - Returns the name of the table field belongs to, or table's oid if oid_only is true
877
878In ext/posix
879============
880    bool posix_initgroups(string name, int base_group_id)
881      - Calculate the group access list for the user specified in name
882
883In ext/gmp
884==========
885    resource gmp_nextprime(resource a)
886      - Finds next prime of a
887
888In ext/xmlwriter
889================
890    bool xmlwriter_full_end_element(resource xmlwriter)
891     - End current element - returns FALSE on error
892    bool xmlwriter_write_raw(resource xmlwriter, string content)
893     - Write text - returns FALSE on error
894As of 5.2.1 #See http://cvs.php.net/viewvc.cgi/php-src/ext/xmlwriter/php_xmlwriter.c?r1=1.20.2.12.2.8&r2=1.20.2.12.2.9
895    bool xmlwriter_start_dtd_entity(resource xmlwriter, string name, bool isparam)
896     - Create start DTD Entity - returns FALSE on error
897    bool xmlwriter_end_dtd_entity(resource xmlwriter)
898     - End current DTD Entity - returns FALSE on error
899    bool xmlwriter_write_dtd_entity(resource xmlwriter, string name, string content [, bool pe [, string pubid [, string sysid [, string ndataid]]]])
900     - Write full DTD Entity tag - returns FALSE on error
901
902
903New optional parameters
904=======================
905
906In the PHP core
907===============
908  - string base64_decode(string str[, bool strict=false]) (strict)
909  - bool setcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly=false]]]]]] (httponly)
910  - bool setrawcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly=false]]]]]] (httponly)
911  - void session_set_cookie_params(int lifetime [, string path [, string domain [, bool secure[, bool httponly]]]]) (httponly)
912  - int memory_get_usage([bool real_usage=false]) (real_usage)
913
914In ext/curl
915===========
916  - array curl_multi_info_read(resource mh [, long msgs_in_queue]) (msgs_in_queue)
917
918In ext/imap
919===========
920  - resource imap_open ( string mailbox, string username, string password [, int options[, int n_retries]]) (n_retries)
921  - bool imap_reopen(resource stream_id, string mailbox [, int options [, int n_retries]]) (n_retries)
922As of 5.2.1 #See http://cvs.php.net/viewvc.cgi/php-src/ext/imap/php_imap.c?r1=1.208.2.7.2.7&r2=1.208.2.7.2.8
923
924In ext/mbstring
925===============
926  - int mb_strrpos(string haystack, string needle [, int offset [, string encoding]]) (offset)
927
928In ext/ming
929===========
930  - int swfmovie::streamMP3(mixed file [, float skip]) (skip)
931As of 5.2.1 #See http://cvs.php.net/viewvc.cgi/php-src/ext/ming/ming.c?r1=1.79.2.4.2.3&r2=1.79.2.4.2.4
932
933In ext/openssl
934==============
935  - int openssl_verify(string data, string signature, mixed key [, int signature_algo]) (signature_algo)
936
937In ext/pgsql
938============
939  - string pg_escape_bytea([resource connection,] string data) (connection)
940  - string pg_escape_string([resource connection,] string data) (connection)
941
942In ext/simplexml
943================
944  - SimpleXMLElement::__construct(string data [, int options [, bool data_is_url [, string ns [, bool is_prefix]]]]) (ns, is_prefix)
945  - SimpleXMLElement SimpleXMLElement::attributes([string ns [, bool is_prefix]]) (is_prefix)
946  - SimpleXMLElement SimpleXMLElement::children([string ns [, bool is_prefix]]) (is_prefix)
947  - SimpleXMLElement simplexml_load_file(string filename [, string class_name [, int options [, string ns [, bool is_prefix]]]]) (ns, is_prefix)
948  - SimpleXMLElement simplexml_load_string(string data [, string class_name [, int options [, string ns [, bool is_prefix]]]]) (ns, is_prefix)
949
950In ext/spl
951==========
952  - array iterator_to_array(Traversable it [, bool use_keys = true]) (use_keys)
953As of 5.2.1 #See http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_iterators.c?r1=1.73.2.30.2.20&r2=1.73.2.30.2.21
954
955In ext/xmlreader
956================
957  - boolean XMLReader::open(string URI [, string encoding [, int options]]) (encoding, options)
958  - boolean XMLReader::XML(string source [, string encoding [, int options]]) (encoding, options)
959
960
961New INI settings
962================
963allow_url_include PHP_INI_SYSTEM, default: false
964pcre.backtrack_limit PHP_INI_ALL, default: 100000
965pcre.recursion_limit PHP_INI_ALL, default: 100000
966session.cookie_httponly PHP_INI_ALL, default: false
967
968
969New global constants
970====================
971
972In the PHP core
973===============
974    - M_EULER
975    - M_LNPI
976    - M_SQRT3
977    - M_SQRTPI
978    - PATHINFO_FILENAME
979    - PREG_BACKTRACK_LIMIT_ERROR
980    - PREG_BAD_UTF8_ERROR
981    - PREG_INTERNAL_ERROR
982    - PREG_NO_ERROR
983    - PREG_RECURSION_LIMIT_ERROR
984    - UPLOAD_ERR_EXTENSION
985As of 5.2.1: (See http://cvs.php.net/viewvc.cgi/php-src/ext/standard/file.c?r1=1.409.2.6.2.13&r2=1.409.2.6.2.14&diff_format=u)
986    - STREAM_SHUT_RD
987    - STREAM_SHUT_WR
988    - STREAM_SHUT_RDWR
989
990In ext/curl
991===========
992    - CURLE_FILESIZE_EXCEEDED
993    - CURLE_FTP_SSL_FAILED
994    - CURLE_LDAP_INVALID_URL
995    - CURLFTPAUTH_DEFAULT
996    - CURLFTPAUTH_SSL
997    - CURLFTPAUTH_TLS
998    - CURLFTPSSL_ALL
999    - CURLFTPSSL_CONTROL
1000    - CURLFTPSSL_NONE
1001    - CURLFTPSSL_TRY
1002    - CURLOPT_FTP_SSL
1003    - CURLOPT_FTPSSLAUTH
1004
1005In ext/ming
1006===========
1007As of 5.2.1: See http://cvs.php.net/viewvc.cgi/php-src/ext/ming/ming.c?r1=1.79.2.4.2.4&r2=1.79.2.4.2.5&diff_format=u
1008    - SWFTEXTFIELD_USEFONT
1009    - SWFTEXTFIELD_AUTOSIZE
1010    - SWF_SOUND_NOT_COMPRESSED
1011    - SWF_SOUND_ADPCM_COMPRESSED
1012    - SWF_SOUND_MP3_COMPRESSED
1013    - SWF_SOUND_NOT_COMPRESSED_LE
1014    - SWF_SOUND_NELLY_COMPRESSED
1015    - SWF_SOUND_5KHZ
1016    - SWF_SOUND_11KHZ
1017    - SWF_SOUND_22KHZ
1018    - SWF_SOUND_44KHZ
1019    - SWF_SOUND_8BITS
1020    - SWF_SOUND_16BITS
1021    - SWF_SOUND_MONO
1022    - SWF_SOUND_STEREO
1023
1024In ext/openssl
1025==============
1026    - OPENSSL_VERSION_NUMBER
1027    - OPENSSL_VERSION_TEXT
1028
1029In ext/snmp
1030===========
1031    - SNMP_OID_OUTPUT_FULL
1032    - SNMP_OID_OUTPUT_NUMERIC
1033
1034In ext/sysvmsg
1035==============
1036    - MSG_EAGAIN
1037    - MSG_ENOMSG
1038

README.WIN32-BUILD-SYSTEM

1The Win32 Build System.
2$Id$
3Wez Furlong <wez@thebrainroom.com>
4
5If you need help with the build system, send mail to
6internals@lists.php.net; please don't email me directly.
7
8===========================================================
9Contents:
101. How to build PHP under windows
11 a. Requirements
12 b. Opening a command prompt
13 c. Generating configure.js
14 d. Configuring
15 e. Building
16 f. Cleaning up
17 g. Running the test suite
18 h. snapshot building
19 
202. How to write config.w32 files
21 x. to be written.
22
23===========================================================
241. How to build PHP under windows
25a. Requirements
26
27 You need:
28  - Windows Scripting Host (cscript.exe)
29  - Microsoft Build Tools from:
30     Microsoft Visual Studio (VC6) or later
31 
32 You also need:
33  - bindlib_w32 [http://www.php.net/extra/bindlib_w32.zip]
34  - win32build  [http://www.php.net/extra/win32build.zip]
35
36 b. Opening the Build Environment Command Prompt:
37  - Using Visual Studio (VC6)
38    1. Install it
39    2. If you have a VC++ Command Prompt icon on your start menu,
40       click on it to get a Command Prompt with the env vars
41       set up correctly.
42
43       If not, create a new shortcut and set the Target to:
44
45       %comspec% /k "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"
46
47       You might also want to set the prompt to start in
48       a convenient location (such as the root of your
49       PHP source checkout).
50
51  - Using Visual Studio .Net
52    1. Install it.
53    2. Under the Visual Studio .Net Tools sub menu of your start
54       menu, you should have a Visual Studio .Net Command Prompt
55       icon.  If not, create a new shortcut and set the Target to:
56
57       %comspec% /k "C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat"
58
59       You might also want to set the prompt to start in
60       a convenient location (such as the root of your
61       PHP source checkout).
62
63  - Using the Platform SDK tools
64    1. Download the Platform SDK:
65       http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
66
67       - You need the Core SDK, which is approx 200MB to download
68         and requires approx 500MB of disk space.
69       - The other components of the SDK are not required by PHP
70       - You might be able to reduce the download size by downloading
71         the installer control component first and then selecting
72         only the Build Environment (around 30MB), but I haven't
73         tried this.
74
75         ** Note: it seems that MS don't include the 32 bit
76            build tools in the platform SDK any longer, so
77            you will probably have very limited luck if you
78            don't also have VC++ or VS.Net already installed.
79
80    2. Once installed, you will have an icon on your start menu
81       that will launch the build environment; the latest SDK's
82       install a number of different versions of this; you probably
83       want to choose the Windows 2000 Retail build environment.
84       Clicking on this will open a command prompt with its Path,
85       Include and Lib env vars set to point to the build tools
86       and win32 headers.
87
88c. Generating configure
89
90 Change directory to where you have your PHP 5 sources.
91 Run buildconf.bat.
92
93d. Configuring
94 
95 cscript /nologo configure.js --help
96 
97 Will give you a list of configuration options; these will
98 have the form:
99 
100 --enable-foo or --disable-foo or --with-foo or --without-foo.
101 
102 --enable-foo will turn something on, and is equivalent to
103 specifying --enable-foo=yes
104 
105 --disable-foo will turn something off, and is equivalent to
106 specifying --enable-foo=no
107
108 --enable-foo=shared will attempt to build that feature as
109 a shared, dynamically loadable module.
110
111 Sometimes a configure option needs additional information
112 about where to find headers and libraries; quite often
113 you can specify --enable-foo=option where option could be
114 the path to where to find those files.  If you want to
115 specify a parameter and build it as shared, you can use
116 this syntax instead:  --enable-foo=shared,option
117
118 The same rules all apply to --with-foo and --without-foo;
119 the only difference is the way the options are named;
120 the convention is that --enable-foo means that you are
121 switching on something that comes with PHP, whereas
122 --with-foo means that you want to build in something
123 external to PHP.
124
125e. Building
126
127 Once you have successfully configured your build (make
128 sure you read the output from the command to make sure
129 it worked correctly), you can build the code; simply type
130
131 "nmake" at the command prompt, and it will build everthing
132 you asked for.
133
134 Once the build has completed, you will find your binaries
135 in the build dir determined by configure; this is typically
136 Release_TS for release builds or Debug_TS for debug builds.
137 If you build a non-thread-safe build, it will use Release
138 or Debug to store the files.  Also in this build dir you
139 will find sub directories for each module that went into
140 your PHP build.  The files you'll want to keep are the
141 .exe and .dll files directly in your build dir.
142
143f. Cleaning Up
144 
145 You can automatically delete everything that was built
146 by running "nmake clean".  This will delete everything
147 that was put there when you ran nmake, including the
148 .exe and .dll files.
149
150g. Running the test suite
151
152 You can verify that your build is working well by running
153 the regression test suite.  You do this by typing
154 "nmake test".  You can specify the tests you want to run
155 by defing the TESTS variable - if you wanted to run the
156 sqlite test suite only, you would type
157 "nmake /D TESTS=ext/sqlite/tests test"
158
159h. Snapshot Building
160
161 If you want to set up an automated build that will tolerate
162 breakages in some of the modules, you can use the
163 --enable-snapshot-build configure option to generate a
164 makefile optimized for that purpose.  A snapshot build will
165 switch the argument parser so that the default option for
166 configure switches that your don't specify will be set
167 to "shared".  The effect of this is to turn on all options
168 unless you explicitly disable them.  When you have configured
169 your snapshot build, you can use "nmake build-snap" to build
170 everything, ignoring build errors in individual extensions
171 or SAPI.
172
173vim:tw=78:sw=1:ts=1:et
174
175

README.Zeus

1Using PHP 5 with the Zeus Web Server
2-----------------------------------
3
4Zeus fully supports running PHP in combination with our
5webserver. There are three different interfaces that can be used to
6enable PHP:
7
8* CGI
9* ISAPI
10* FastCGI
11
12Of the three, we recommend using FastCGI, which has been tested and
13benchmarked as providing the best performance and reliability.
14
15Full details of how to install PHP are available from our
16website, at:
17
18http://support.zeus.com/products/php.html
19
20If you have any problems, please check the support site for more
21up-to-date information and advice.
22
23
24Quick guide to installing CGI/FastCGI with Zeus
25-----------------------------------------------
26
27Step 1 - Compile PHP as FastCGI.
28
29Compile as follows:
30        ./configure --enable-fastcgi
31        make
32
33Note that PHP has many options to the configure script -
34e.g. --with-mysql. You will probably want to select your usual options
35before compiling; the above is just a bare minimum, for illustration.
36
37After compilation finishes, you will be left with an executable
38program called 'php'. Copy this into your document root, under a
39dedicated FastCGI directory (e.g. $DOCROOT/fcgi-bin/php)
40
41
42Step 2 - configure Zeus
43
44Four stages:
45        -  enable FastCGI
46        -  configure FastCGI
47        -  setup alias for FastCGI
48        -  setup alias for PHP
49
501) Using the admin server, go to the 'module configuration' page for
51your virtual server, and ensure that 'fastcgi' is enabled (select the
52tickbox to the left).
53
542) While we can run FastCGI's locally, there are known problems with
55some OS's (specifically, the communication between web server and
56FastCGI happens over a unix domain socket, and some OS's have trouble
57sustaining high connection rates over these sockets). So instead, we
58are going to set up the PHP FastCGI to run 'remotely' over localhost
59(this uses TCP sockets, which do not suffer this problem). Go to the
60'fastcgi configuration' page, and under 'add remote fastcgi':
61        Add Remote FastCGI
62                Docroot path            /fcgi-bin/php
63                Remote machine          localhost:8002
64The first entry is where you saved PHP, above.
65The second entry is localhost:<any unused port>
66We will start the FastCGI listening on this port shortly.
67Click 'update' to commit these changes.
68
693) Go to the path mapping module and add an alias for FastCGI:
70        Add Alias
71                Docroot path            /fcgi-bin
72                Filesystem directory    /path/to/docroot/fcgi-bin
73                Alias type              fastcgi
74Click 'update' to commit these changes
75
764) Also on the path mapping module, add a handler for PHP:
77        Add handler
78                File extension          php
79                Handler                 /fcgi-bin/php
80Click 'update' to commit these changes
81
82Finally restart your virtual server for these changes to take effect.
83
84
85Step 3 - start PHP as a FastCGI runner
86
87When you start PHP, it will pre-fork a given number of child processes
88to handle incoming PHP requests. Each process will handle a given
89number of requests before exiting (and being replaced by a newly
90forked process). You can control these two parameters by setting the
91following environment variables BEFORE starting the FastCGI runner:
92
93PHP_FCGI_CHILDREN - the number of child processes to pre-fork. This
94variable MUST be set, if not then the PHP will not run as a FastCGI.
95We recommend a value of 8 for a fairly busy site. If you have many,
96long-running PHP scripts, then you may need to increase this further.
97
98PHP_FCGI_MAX_REQUESTS - the number of requests each PHP child process
99handles before exiting. If not set, defaults to 500.
100
101To start the FastCGI runner, execute '$ZEUSHOME/web/bin/fcgirunner
1028002 $DOCROOT/fcgi-bin/php'.  Substitute the appropriate values for
103$ZEUSHOME and $DOCROOT; also substitute for 8002 the port you chose,
104above.
105
106To stop the runner (e.g. to experiment with the above environment
107variables) you will need to manually stop and running PHP
108processes. (Use 'ps' and 'kill'). As it is PHP which is forking lots
109of children and not the runner, Zeus unfortunately cannot keep track
110of what processes are running, sorry. A typical command line may look
111like 'ps -efl | grep $DOCROOT/fcgi-bin/php | grep -v grep | awk
112'{print $4}' | xargs kill'
113