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, ¶m) == 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