README.coolstack
1 If you want to add additional extensions to php, the best way to
2 do this is using 'phpize'. You do not need to rebuild PHP itself.
3
4 Building php is a complicated affair. It requires that several libraries
5 be built first and in a specific order in some cases.
6 It has taken us a lot of time and trial-and-error to figure out the right
7 build order and libraries. So please DO NOT change anything in the
8 'make_solaris.sh' or 'make_fastcgi.sh' script. The former is for using
9 PHP with apache (via mod_php) and the latter is for using PHP with any
10 other webserver via fastcgi.
11
12 If you are not rebuilding any libraries but only PHP itself, then go
13 ahead and install the CSKphplibs package and use that as is.
14 All you then have to do is to run the 'make_solaris.sh' script here.
15
16 If you do want to rebuild everything, here is the order in which
17 we build :
18 imap, libiconv, libxml2, mysql, curl, readline, gettext, ncurses,
19 freetype, gd, gdbm, tidy, unixODBC, freetds, cyrus-sasl, openldap,
20 httpd, php
21
22 If PHP is rebuilt, you also need to rebuid APC and suhosin extensions.
23 README.CVS-RULES
1 This is the first file you should be reading after you get your CVS account.
2 We'll assume you're basically familiar with CVS, but feel free to post
3 your questions on the mailing list. Please have a look at
4 http://cvsbook.red-bean.com/ for more detailed information on CVS.
5
6 PHP is developed through the efforts of a large number of people.
7 Collaboration is a Good Thing(tm), and CVS lets us do this. Thus, following
8 some basic rules with regards to CVS usage will:
9
10 a. Make everybody happier, especially those responsible for maintaining
11 the CVS itself.
12 b. Keep the changes consistently well documented and easily trackable.
13 c. Prevent some of those 'Oops' moments.
14 d. Increase the general level of good will on planet Earth.
15
16
17 Having said that, here are the organizational rules:
18
19 1. Respect other people working on the project.
20
21 2. Discuss any significant changes on the list before committing.
22
23 3. Look at EXTENSIONS file to see who is the primary maintainer of
24 the code you want to contribute to.
25
26 4. If you "strongly disagree" about something another person did, don't
27 start fighting publicly - take it up in private email.
28
29 5. If you don't know how to do something, ask first!
30
31 6. Test your changes before committing them. We mean it. Really.
32 To do so use "make test".
33
34 7. For development use the --enable-maintainer-zts switch to ensure your
35 code handles TSRM correctly and doesn't break for thos who need that.
36
37 Currently we have the following branches in use:
38 HEAD Will become PHP 6.0. This CVS branch is for active development.
39 PHP_5_2 Is used to release the PHP 5.2.x series. Only minor feature
40 enhancements may go in here, but please keep that as infrequent as
41 possible.
42 PHP_5_1 Is used to release the PHP 5.1.x series. Only bugfixes are permitted
43 on this branch (Consult the releasemaster prior to commit).
44 PHP_5_0 This branch is closed.
45 PHP_4_4 Is used to release the PHP 4.4.x series. Only bugfixes are permitted
46 on this branch (Consult the releasemaster prior to commit).
47 PHP_4_3 This branch is closed.
48
49 The next few rules are more of a technical nature.
50
51 1. DO NOT TOUCH ChangeLog! It is automagically updated from the commit
52 messages every day. Woe be to those who attempt to mess with it.
53
54 2. All news updates intended for public viewing, such as new features,
55 bug fixes, improvements, etc., should go into the NEWS file.
56
57 NB! Lines, starting with @ will go automagically into NEWS file, but
58 this is NOT recommended, though. Please, add news entries directly to
59 NEWS file and don't forget to keep them adjusted and sorted.
60
61 3. Do not commit multiple file and dump all messages in one commit. If you
62 modified several unrelated files, commit each group separately and
63 provide a nice commit message for each one. See example below.
64
65 4. Do write your commit message in such a way that it makes sense even
66 without the corresponding diff. One should be able to look at it, and
67 immediately know what was modified. Definitely include the function name
68 in the message as shown below.
69
70 5. In your commit messages, keep each line shorter than 80 characters. And
71 try to align your lines vertically, if they wrap. It looks bad otherwise.
72
73 6. If you modified a function that is callable from PHP, prepend PHP to
74 the function name as shown below.
75
76
77 The format of the commit messages is pretty simple.
78
79 Use a - to start a new item in your commit message.
80
81 If a line begins with #, it is taken to be a comment and will not appear
82 in the ChangeLog. Everything else goes into the ChangeLog.
83
84 It is important to note that if your comment or news logline spans multiple
85 lines, you have to put # at the beginning of _every_ such line.
86
87 Example. Say you modified two files, datetime.c and string.c. In datetime.c you
88 added a new format option for the date() function, and in string.c you fixed a
89 memory leak in php_trim(). Don't commit both of these at once. Commit them
90 separately and try to make sure your commit messages look something like the
91 following.
92
93 For datetime.c:
94 - Added new 'K' format modifier to date() for printing out number of days until
95 New Year's Eve.
96
97 For string.c:
98 - Fixed a memory leak in php_trim() resulting from improper use of zval_dtor().
99 #- Man, that thing was leaking all over the place!
100
101 The # lines will be omitted from the ChangeLog automagically.
102
103 If you fix some bugs, you should note the bug ID numbers in your
104 commit message. Bug ID should be prefixed by "#" for easier access to
105 bug report when developers are browsing CVS via. LXR or Bonsai.
106
107 Example:
108
109 Fixed bug #14016 (pgsql notice handler double free crash bug.)
110
111 If you don't see your messages in ChangeLog right away, don't worry!
112 These files are updated once a day, so your stuff will not show up until
113 somewhat later.
114
115 You can use LXR (http://lxr.php.net/) and Bonsai (http://bonsai.php.net/)
116 to look at PHP CVS repository in various ways.
117
118 To receive daily updates to ChangeLog and NEWS, send an empty message to
119 php-cvs-daily-subscribe (a] lists.php.net.
120
121 Happy hacking,
122
123 PHP Team
124 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
6 WHAT 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
12 HOW 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
43 FORMAT 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
83 OTHER 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
131 CURRENT 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
149 EXAMPLE
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 */
161 PHP_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
1 Between PHP 4.0.6 and 4.1.0, the Zend module struct changed in a way
2 that broke both source and binary compatibility. If you are
3 maintaining a third party extension, here's how to update it:
4
5 If this was your old module entry:
6
7 zend_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
18 Here's how it should look if you want your code to build with PHP
19 4.1.0 and up:
20
21 zend_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
38 If you don't care about source compatibility with earlier PHP releases
39 than 4.1.0, you can drop the #if/#endif lines.
40 README.input_filter
1 Input Filter Support in PHP 5
2 -----------------------------
3
4 XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
5 and can be quite difficult to prevent. Whenever you accept user data
6 and somehow display this data back to users, you are likely vulnerable
7 to XSS hacks.
8
9 The Input Filter support in PHP 5 is aimed at providing the framework
10 through which a company-wide or site-wide security policy can be
11 enforced. It is implemented as a SAPI hook and is called from the
12 treat_data and post handler functions. To implement your own security
13 policy you will need to write a standard PHP extension. There is also
14 a powerful standard implementation in ext/filter that should suit most
15 peoples' needs. However, if you want to implement your own security
16 policy, read on.
17
18 A simple implementation might look like the following. This stores the
19 original raw user data and adds a my_get_raw() function while the normal
20 $_POST, $_GET and $_COOKIE arrays are only populated with stripped
21 data. In this simple example all I am doing is calling strip_tags() on
22 the data. If register_globals is turned on, the default globals that
23 are created will be stripped ($foo) while a $RAW_foo is created with the
24 original user input.
25
26 ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
27 zval *post_array;
28 zval *get_array;
29 zval *cookie_array;
30 ZEND_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
38 ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
39
40 zend_function_entry my_input_filter_functions[] = {
41 PHP_FE(my_get_raw, NULL)
42 {NULL, NULL, NULL}
43 };
44
45 zend_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
58 PHP_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
70 PHP_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
87 PHP_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: 1.7.4.1.2.1 $");
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. */
99 SAPI_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
151 PHP_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
1 New parameter parsing functions
2 ===============================
3
4 It should be easier to parse input parameters to an extension function.
5 Hence, borrowing from Python's example, there are now a set of functions
6 that given the string of type specifiers, can parse the input parameters
7 and store the results in the user specified variables. This avoids most
8 of the IS_* checks and convert_to_* conversions. The functions also
9 check for the appropriate number of parameters, and try to output
10 meaningful error messages.
11
12
13 Prototypes
14 ----------
15 /* Implemented. */
16 int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);
17 int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...);
18
19 The zend_parse_parameters() function takes the number of parameters
20 passed to the extension function, the type specifier string, and the
21 list of pointers to variables to store the results in. The _ex() version
22 also takes 'flags' argument -- current only ZEND_PARSE_PARAMS_QUIET can
23 be used as 'flags' to specify that the function should operate quietly
24 and not output any error messages.
25
26 Both functions return SUCCESS or FAILURE depending on the result.
27
28 The auto-conversions are performed as necessary. Arrays, objects, and
29 resources cannot be auto-converted.
30
31
32 Type 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 'a', 'o', 'O', 'r', and 'z'). If NULL is passed, the results
55 pointer is set to NULL as well.
56
57 Examples
58 --------
59 /* Gets a long, a string and its length, and a zval */
60 long l;
61 char *s;
62 int s_len;
63 zval *param;
64 if (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. */
71 zval *obj;
72 double d = 0.5;
73 zend_class_entry my_ce;
74 if (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. */
82 zval *obj;
83 zval *arr;
84 if (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. */
91 zval *arr;
92 if (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). */
99 zval *z;
100 zend_bool b;
101 zval *r;
102 if (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. */
109 long l1, l2, l3;
110 char *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 */
118 int length;
119
120 if (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
1 1. 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
14 2. 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
24 3. 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
28 4. 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
36 5. 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
42 6. 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
49 7. $_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
56 8. 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
78 9. 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
111 10. 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
136 11. 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
1 QNX4 Installation Notes
2 -----------------------
3
4 NOTE: General installation instructions are in the INSTALL file
5
6
7 1. 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
13 2. 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
18 3. To run configure define -lunix in command line:
19 LDFLAGS=-lunix ./configure
20
21 4. 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
29 5. 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
47 6. 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
56 June 28, 1998
57 Igor Kovalenko -- owl (a] infomarket.ru
58 README.SELF-CONTAINED-EXTENSIONS
1 $Id: README.SELF-CONTAINED-EXTENSIONS,v 1.12 2002/10/23 21:35:17 jon Exp $
2 =============================================================================
3
4 HOW 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
16 PREPARING 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
30 CONVERTING 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
63 DEFINING 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
79 CREATING 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 ------------------------------------------------------------------------------
86 PHP_ARG_ENABLE(foobar,whether to enable foobar,
87 [ --enable-foobar Enable foobar])
88
89 if test "$PHP_FOOBAR" != "no"; then
90 PHP_NEW_EXTENSION(foobar, foo.c bar.c, $ext_shared)
91 fi
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
105 CREATING 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
116 CREATING 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
130 INSTALLING 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
138 ADDING 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
1 An Overview of the PHP Streams abstraction
2 ==========================================
3 $Id: README.STREAMS,v 1.11 2003/03/04 21:46:33 iliaa Exp $
4
5 WARNING: some prototypes in this file are out of date.
6 The information contained here is being integrated into
7 the PHP manual - stay tuned...
8
9 Please send comments to: Wez Furlong <wez (a] thebrainroom.com>
10
11 Why Streams?
12 ============
13 You may have noticed a shed-load of issock parameters flying around the PHP
14 code; we don't want them - they are ugly and cumbersome and force you to
15 special case sockets and files every time you need to work with a "user-level"
16 PHP file pointer.
17 Streams take care of that and present the PHP extension coder with an ANSI
18 stdio-alike API that looks much nicer and can be extended to support non file
19 based data sources.
20
21 Using Streams
22 =============
23 Streams use a php_stream* parameter just as ANSI stdio (fread etc.) use a
24 FILE* parameter.
25
26 The main functions are:
27
28 PHPAPI size_t php_stream_read(php_stream * stream, char * buf, size_t count);
29 PHPAPI size_t php_stream_write(php_stream * stream, const char * buf, size_t
30 count);
31 PHPAPI size_t php_stream_printf(php_stream * stream TSRMLS_DC,
32 const char * fmt, ...);
33 PHPAPI int php_stream_eof(php_stream * stream);
34 PHPAPI int php_stream_getc(php_stream * stream);
35 PHPAPI char *php_stream_gets(php_stream * stream, char *buf, size_t maxlen);
36 PHPAPI int php_stream_close(php_stream * stream);
37 PHPAPI int php_stream_flush(php_stream * stream);
38 PHPAPI int php_stream_seek(php_stream * stream, off_t offset, int whence);
39 PHPAPI off_t php_stream_tell(php_stream * stream);
40 PHPAPI int php_stream_lock(php_stream * stream, int mode);
41
42 These (should) behave in the same way as the ANSI stdio functions with similar
43 names: fread, fwrite, fprintf, feof, fgetc, fgets, fclose, fflush, fseek, ftell, flock.
44
45 Opening Streams
46 ===============
47 In most cases, you should use this API:
48
49 PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode,
50 int options, char **opened_path TSRMLS_DC);
51
52 Where:
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
72 If you need to open a specific stream, or convert standard resources into
73 streams there are a range of functions to do this defined in php_streams.h.
74 A brief list of the most commonly used functions:
75
76 PHPAPI php_stream *php_stream_fopen_from_file(FILE *file, const char *mode);
77 Convert a FILE * into a stream.
78
79 PHPAPI php_stream *php_stream_fopen_tmpfile(void);
80 Open a FILE * with tmpfile() and convert into a stream.
81
82 PHPAPI 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
86 There are some network enabled relatives in php_network.h:
87
88 PHPAPI php_stream *php_stream_sock_open_from_socket(int socket, int persistent);
89 Convert a socket into a stream.
90
91 PHPAPI 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
95 PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent,
96 struct timeval *timeout);
97 Open a UNIX domain socket.
98
99
100 Stream Utilities
101 ================
102
103 If you need to copy some data from one stream to another, you will be please
104 to know that the streams API provides a standard way to do this:
105
106 PHPAPI size_t php_stream_copy_to_stream(php_stream *src,
107 php_stream *dest, size_t maxlen);
108
109 If you want to copy all remaining data from the src stream, pass
110 PHP_STREAM_COPY_ALL as the maxlen parameter, otherwise maxlen indicates the
111 number of bytes to copy.
112 This function will try to use mmap where available to make the copying more
113 efficient.
114
115 If you want to read the contents of a stream into an allocated memory buffer,
116 you should use:
117
118 PHPAPI size_t php_stream_copy_to_mem(php_stream *src, char **buf,
119 size_t maxlen, int persistent);
120
121 This function will set buf to the address of the buffer that it allocated,
122 which will be maxlen bytes in length, or will be the entire length of the
123 data remaining on the stream if you set maxlen to PHP_STREAM_COPY_ALL.
124 The buffer is allocated using pemalloc(); you need to call pefree() to
125 release the memory when you are done.
126 As with copy_to_stream, this function will try use mmap where it can.
127
128 If you have an existing stream and need to be able to seek() it, you
129 can use this function to copy the contents into a new stream that can
130 be seek()ed:
131
132 PHPAPI int php_stream_make_seekable(php_stream *origstream, php_stream **newstream);
133
134 It 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
140 make_seekable will always set newstream to be the stream that is valid
141 if the function succeeds.
142 When you have finished, remember to close the stream.
143
144 NOTE: If you only need to seek forward, there is no need to call this
145 function, as the php_stream_seek can emulate forward seeking when the
146 whence parameter is SEEK_CUR.
147
148 NOTE: Writing to the stream may not affect the original source, so it
149 only makes sense to use this for read-only use.
150
151 NOTE: If the origstream is network based, this function will block
152 until the whole contents have been downloaded.
153
154 NOTE: Never call this function with an origstream that is referenced
155 as a resource! It will close the origstream on success, and this
156 can lead to a crash when the resource is later used/released.
157
158 NOTE: If you are opening a stream and need it to be seekable, use the
159 STREAM_MUST_SEEK option to php_stream_open_wrapper();
160
161 PHPAPI int php_stream_supports_lock(php_stream * stream);
162
163 This function will return either 1 (success) or 0 (failure) indicating whether or
164 not a lock can be set on this stream. Typically you can only set locks on stdio streams.
165
166 Casting Streams
167 ===============
168 What if your extension needs to access the FILE* of a user level file pointer?
169 You need to "cast" the stream into a FILE*, and this is how you do it:
170
171 FILE * fp;
172 php_stream * stream; /* already opened */
173
174 if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void*)&fp, REPORT_ERRORS) == FAILURE) {
175 RETURN_FALSE;
176 }
177
178 The prototype is:
179
180 PHPAPI int php_stream_cast(php_stream * stream, int castas, void ** ret, int
181 show_err);
182
183 The show_err parameter, if non-zero, will cause the function to display an
184 appropriate error message of type E_WARNING if the cast fails.
185
186 castas can be one of the following values:
187 PHP_STREAM_AS_STDIO - a stdio FILE*
188 PHP_STREAM_AS_FD - a generic file descriptor
189 PHP_STREAM_AS_SOCKETD - a socket descriptor
190
191 If you ask a socket stream for a FILE*, the abstraction will use fdopen to
192 create it for you. Be warned that doing so may cause buffered data to be lost
193 if you mix ANSI stdio calls on the FILE* with php stream calls on the stream.
194
195 If your system has the fopencookie function, php streams can synthesize a
196 FILE* on top of any stream, which is useful for SSL sockets, memory based
197 streams, data base streams etc. etc.
198
199 In situations where this is not desirable, you should query the stream
200 to see if it naturally supports FILE *. You can use this code snippet
201 for 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
207 You can use:
208
209 PHPAPI int php_stream_can_cast(php_stream * stream, int castas)
210
211 to find out if a stream can be cast, without actually performing the cast, so
212 to check if a stream is a socket you might use:
213
214 if (php_stream_can_cast(stream, PHP_STREAM_AS_SOCKETD) == SUCCESS) {
215 /* it can be a socket */
216 }
217
218 Please note the difference between php_stream_is and php_stream_can_cast;
219 stream_is tells you if the stream is a particular type of stream, whereas
220 can_cast tells you if the stream can be forced into the form you request.
221 The former doesn't change anything, while the later *might* change some
222 state in the stream.
223
224 Stream Internals
225 ================
226
227 There are two main structures associated with a stream - the php_stream
228 itself, which holds some state information (and possibly a buffer) and a
229 php_stream_ops structure, which holds the "virtual method table" for the
230 underlying implementation.
231
232 The php_streams ops struct consists of pointers to methods that implement
233 read, write, close, flush, seek, gets and cast operations. Of these, an
234 implementation need only implement write, read, close and flush. The gets
235 method is intended to be used for streams if there is an underlying method
236 that can efficiently behave as fgets. The ops struct also contains a label
237 for the implementation that will be used when printing error messages - the
238 stdio implementation has a label of "STDIO" for example.
239
240 The idea is that a stream implementation defines a php_stream_ops struct, and
241 associates it with a php_stream using php_stream_alloc.
242
243 As an example, the php_stream_fopen() function looks like this:
244
245 PHPAPI 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
260 php_stream_stdio_ops is a php_stream_ops structure that can be used to handle
261 FILE* based streams.
262
263 A socket based stream would use code similar to that above to create a stream
264 to be passed back to fopen_wrapper (or it's yet to be implemented successor).
265
266 The prototype for php_stream_alloc is this:
267
268 PHPAPI php_stream * php_stream_alloc(php_stream_ops * ops, void * abstract,
269 size_t bufsize, int persistent, const char * mode)
270
271 ops is a pointer to the implementation,
272 abstract holds implementation specific data that is relevant to this instance
273 of the stream,
274 bufsize is the size of the buffer to use - if 0, then buffering at the stream
275 level will be disabled (recommended for underlying sources that implement
276 their own buffering - such a FILE*),
277 persistent controls how the memory is to be allocated - persistently so that
278 it lasts across requests, or non-persistently so that it is freed at the end
279 of a request (it uses pemalloc),
280 mode is the stdio-like mode of operation - php streams places no real meaning
281 in the mode parameter, except that it checks for a 'w' in the string when
282 attempting to write (this may change).
283
284 The mode parameter is passed on to fdopen/fopencookie when the stream is cast
285 into a FILE*, so it should be compatible with the mode parameter of fopen().
286
287 Writing your own stream implementation
288 ======================================
289
290 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
291 RULE #1: when writing your own streams: make sure you have configured PHP with
292 --enable-debug.
293 I've taken some great pains to hook into the Zend memory manager to help track
294 down allocation problems. It will also help you spot incorrect use of the
295 STREAMS_DC, STREAMS_CC and the semi-private STREAMS_REL_CC macros for function
296 definitions.
297 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
298
299 RULE #2: Please use the stdio stream as a reference; it will help you
300 understand the semantics of the stream operations, and it will always
301 be more up to date than these docs :-)
302
303 First, you need to figure out what data you need to associate with the
304 php_stream. For example, you might need a pointer to some memory for memory
305 based streams, or if you were making a stream to read data from an RDBMS like
306 MySQL, you might want to store the connection and rowset handles.
307
308 The stream has a field called abstract that you can use to hold this data.
309 If you need to store more than a single field of data, define a structure to
310 hold it, allocate it (use pemalloc with the persistent flag set
311 appropriately), and use the abstract pointer to refer to it.
312
313 For structured state you might have this:
314
315 struct my_state {
316 MYSQL conn;
317 MYSQL_RES * result;
318 };
319
320 struct 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
325 state->result = mysql_use_result(&state->conn);
326
327 /* now allocate the stream itself */
328 stream = php_stream_alloc(&my_ops, state, 0, persistent, "r");
329
330 /* now stream->abstract == state */
331
332 Once you have that part figured out, you can write your implementation and
333 define the your own php_stream_ops struct (we called it my_ops in the above
334 example).
335
336 For example, for reading from this weird MySQL stream:
337
338 static 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
359 Implement the other operations - remember that write, read, close and flush
360 are all mandatory. The rest are optional. Declare your stream ops struct:
361
362 php_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
368 Thats it!
369
370 Take a look at the STDIO implementation in streams.c for more information
371 about how these operations work.
372 The main thing to remember is that in your close operation you need to release
373 and free the resources you allocated for the abstract field. In the case of
374 the example above, you need to use mysql_free_result on the rowset, close the
375 connection and then use pefree to dispose of the struct you allocated.
376 You may read the stream->persistent field to determine if your struct was
377 allocated in persistent mode or not.
378
379 vim:tw=78:et
380 README.SUBMITTING_PATCH
1 Submitting Patch for PHP
2 ========================
3
4 This document describes how to submit a patch for PHP. Since you are
5 reading this document, you are willing to submit a patch for PHP.
6 Please keep reading! Submitting a patch for PHP is easy. The hard
7 part is making it acceptable for inclusion into our repository. :-)
8
9 How to create patch?
10 --------------------
11 We are working with CVS. You need to get CVS source to create a patch
12 that we accept. Visit http://www.php.net/anoncvs.php to get CVS
13 source. You can check out older versions, but make sure you get
14 the default branch (i.e. Do not use -r option when you check out the
15 CVS source)
16
17 Read CODING_STANDARDS file before you start working.
18
19 Now you are ready to create a patch. Modify source to fix a bug in PHP or
20 add a new feature to PHP. After you finished editing, please test your
21 patch. Read README.TESTING for testing.
22
23 After you finish testing your patch, take diff file using
24 "cvs diff > your.patch" command.
25
26 Read README.TESTING for submitting a test script for your patch. This is
27 not strictly required, but it is preferred to submit a test script along
28 with your patch. Making new test script is very easy. It also helps us
29 to understand what you have been fixed or added to PHP.
30
31
32 Tips for creating patch
33 -----------------------
34 If you would like to fix multiple bugs. It is easier for us if you
35 could create 1 patch for 1 bug, but this is not strictly required.
36 Note though that you might get little response, if your patch is
37 too hard to review.
38
39 If you would like change/add many lines, it is better to ask module
40 maintainer and/or internals (a] lists.php.net, or pear-dev (a] lists.php.net if
41 you are patching PEAR. Official module maintainers can be found in
42 EXTENSIONS file in PHP source.
43
44 If you are new to CVS (Concurrent Versions System), visit
45 http://cvshome.org/ for details.
46
47
48 Recommended CVS client settings for creating patch file
49 ------------------------------------------------------
50 Recommended ~/.cvsrc file setting is:
51 ------
52 cvs -z3
53 update -d -P
54 checkout -P
55 diff -u
56
57 ------
58 diff -u means:
59 -u Use the unified output format.
60
61 With this CVS setting, you don't have to worry about adding/deleting
62 newlines and spaces.
63
64
65 Check list for submitting patch
66 -------------------------------
67 - Did you run "make test" to check if your patch didn't break
68 other features?
69 - Did you compile PHP with --enable-debug and check the PHP and
70 web server error logs when you test your patch?
71 - Did you build PHP for multi-threaded web servers. (Optional)
72 - Did you create test script for "make test"? (Recommended)
73 - Did you check your patch is unified format and it does not
74 contain white space changes? (If you are not using recommended
75 cvs setting)
76 - Did you update CVS source before you take final patch?
77 - Did you read the patch again?
78
79
80 Where to send your patch?
81 -------------------------
82 If you are patching C source, send the patch to internals (a] lists.php.net.
83 If you are patching a module, you should also send the patch to the
84 maintainer. Official module maintainers are listed in EXTENSION file
85 in source.
86
87 If you are patching PEAR, send the patch to pear-dev (a] lists.php.net.
88
89 Please add the prefix "[PATCH]" to your email subject and make sure
90 to include the patch as a MIME attachment even if it is short.
91
92 NOTE: only MIME attachments of type 'text/*' are accepted. The
93 easiest way to accomplish this, is to make the extension
94 '.txt'.
95
96 Test scripts should be included in the same email.
97 Explain what has been fixed/added/changed by your patch.
98
99 Finally, add the bug Id(s) which can be closed by your patch, if any.
100
101
102 What happens after you submit your patch
103 ----------------------------------------
104 If your patch is easy to review and has obviously no side-effects,
105 it might take up to a few hours until someone commits it.
106
107 Because this is a volunteer-driven effort, more complex patches will
108 require more patience on your side.
109
110 If you did not receive any feedback in a few days, please consider
111 resubmitting the description of your patch, along-side with
112 these questions:
113
114 - Is my patch too hard to review? Because of which factors?
115 - Should I split it up in multiple parts?
116 - Are there any unwanted whitespace changes?
117
118
119 What happens when your patch is applied?
120 ----------------------------------------
121 Your name will be included together with your email address in the CVS
122 commit log. If your patch affects end-users, a brief description
123 and your name might be added to the NEWS file.
124
125
126 Thank you for submitting patch for PHP!
127 README.TESTING
1 [IMPORTANT NOTICE]
2 ------------------
3 Failed tests usualy indicate a problem with your local system setup
4 and not within PHP itself (at least for official PHP release versions).
5 You may decide to automaticaly submit a test summary to our QA workflow
6 at the end of a test run.
7 Please do *not* submit a failed test as a bug or ask for help on why
8 it failed on your system without providing substantial backup information
9 on *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
15 command line after successfully compiling. This will run the complete
16 tests for all enabled functionalities and extensions using the PHP
17 CLI binary.
18 To execute test scripts, you must build PHP with some SAPI, then you
19 type "make test" to execute all or some test scripts saved under
20 "tests" directory under source root directory.
21
22 Usage:
23 make test
24
25 "make test" basically executes "run-tests.php" script
26 under the source root (parallel builds will not work). Therefore you
27 can execute the script as follows:
28
29 TEST_PHP_EXECUTABLE=sapi/cli/php \
30 sapi/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 ---------------------------------------------
35 You must use TEST_PHP_EXECUTABLE environment variable to explicitly
36 select the php executable to be used to run the tests. That can either
37 be the CLI or CGI executable.
38
39 "make test" executes "run-tests.php" script with "php" binary. Some
40 test scripts such as session must be executed by CGI SAPI. Therefore,
41 you must build PHP with CGI SAPI to perform all tests.
42
43 NOTE: PHP binary executing "run-tests.php" and php binary used for
44 executing test scripts may differ. If you use different PHP binary for
45 executing "run-tests.php" script, you may get errors.
46
47
48 [Which php.ini is used]
49 -----------------------
50 "make test" uses the same php.ini file as it would once installed.
51 The tests have been written to be independent of that php.ini file,
52 so if you find a test that is affected by a setting, please report
53 this, so we can address the issue.
54
55
56 [Which test scripts are executed]
57 ---------------------------------
58 "run-tests.php" ("make test"), without any arguments executes all
59 test scripts by extracting all directories named "tests"
60 from the source root and any subdirectories below. If there are files,
61 which have a "phpt" extension, "run-tests.php" looks at the sections
62 in these files, determines whether it should run it, by evaluating
63 the 'SKIP' section. If the test is eligible for execution, the 'FILE'
64 section is extracted into a ".php" file (with the same name besides
65 the extension) and gets executed.
66 When an argument is given or TESTS environment variable is set, the
67 GLOB is expanded by the shell and any file with extension "*.phpt" is
68 regarded as a test file.
69
70 Tester can easily execute tests selectively with as follows.
71
72 Examples:
73 ./sapi/cli/php run-tests.php ext/mbstring/*
74 ./sapi/cli/php run-tests.php ext/mbstring/020.phpt
75
76
77 [Test results]
78 --------------
79 Test results are printed to standard output. If there is a failed test,
80 the "run-tests.php" script saves the result, the expected result and the
81 code executed to the test script directory. For example, if
82 ext/myext/tests/myext.phpt fails to pass, the following files are created:
83
84 ext/myext/tests/myext.php - actual test file executed
85 ext/myext/tests/myext.log - log of test execution (L)
86 ext/myext/tests/myext.exp - expected output (E)
87 ext/myext/tests/myext.out - output from test script (O)
88 ext/myext/tests/myext.diff - diff of .out and .exp (D)
89
90 Failed tests are always bugs. Either the test is bugged or not considering
91 factors applying to the tester's environment, or there is a bug in PHP.
92 If this is a known bug, we strive to provide bug numbers, in either the
93 test name or the file name. You can check the status of such a bug, by
94 going to: http://bugs.php.net/12345 where 12345 is the bug number.
95 For clarity and automated processing, bug numbers are prefixed by a hash
96 sign '#' in test names and/or test cases are named bug12345.phpt.
97
98 NOTE: The files generated by tests can be selected by setting the
99 environment variable TEST_PHP_LOG_FORMAT. For each file you want to be
100 generated use the character in brackets as shown above (default is LEOD).
101 The php file will be generated always.
102
103 NOTE: You can set environment variable TEST_PHP_DETAILED to enable
104 detailed test information.
105
106 [Automated testing]
107 If you like to keep up to speed, with latest developments and quality
108 assurance, setting the environment variable NO_INTERACTION to 1, will not
109 prompt the tester for any user input.
110
111 Normally, the exit status of "make test" is zero, regardless of the results
112 of independent tests. Set the environment variable REPORT_EXIT_STATUS to 1,
113 and "make test" will set the exit status ("$?") to non-zero, when an
114 individual test has failed.
115
116 Example script to be run by cron(1):
117 ========== qa-test.sh =============
118 #!/bin/sh
119
120 CO_DIR=$HOME/cvs/php5
121 MYMAIL=qa-test (a] domain.com
122 TMPDIR=/var/tmp
123 TODAY=`date +"%Y%m%d"`
124
125 # Make sure compilation enviroment is correct
126 CONFIGURE_OPTS='--disable-all --enable-cli --with-pcre'
127 export MAKE=gmake
128 export CC=gcc
129
130 # Set test environment
131 export NO_INTERACTION=1
132 export REPORT_EXIT_STATUS=1
133
134 cd $CO_DIR
135 cvs update . >>$TMPDIR/phpqatest.$TODAY
136 ./cvsclean ; ./buildconf ; ./configure $CONFIGURE_OPTS ; $MAKE
137 $MAKE test >>$TMPDIR/phpqatest.$TODAY 2>&1
138 if test $? -gt 0
139 then
140 cat $TMPDIR/phpqatest.$TODAY | mail -s"PHP-QA Test Failed for $TODAY" $MYMAIL
141 fi
142 ========== end of qa-test.sh =============
143
144 NOTE: the exit status of run-tests.php will be 1 when
145 REPORT_EXIT_STATUS is set. The result of "make test" may be higher
146 than that. At present, gmake 3.79.1 returns 2, so it is
147 advised to test for non-zero, rather then a specific value.
148
149
150 [Creating new test files]
151 -------------------------
152 Writing test file is very easy if you are used to PHP.
153 See the HOWTO at http://qa.php.net/write-test.php
154
155
156 [How to help us]
157 ----------------
158 If you find bug in PHP, you can submit bug report AND test script
159 for us. You don't have to write complete script, just give us test
160 script with following format. Please test the script and make sure
161 you write the correct ACTUAL OUTPUT and EXPECTED OUTPUT before you
162 submit.
163
164 <?php
165 /*
166 Bug #12345
167 substr() bug. Do not return expected string.
168
169 ACTUAL OUTPUT
170 XYXA
171
172 EXPECTED OUTPUT
173 ABCD
174 */
175
176 $str = "XYZABCD";
177 echo substr($str,3,7);
178
179 ?>
180 README.TESTING2
1 [IMPORTANT NOTICE]
2 ------------------
3 This is an addendum to README.TESTING with additional information
4 specific to run-tests2.php.
5
6 run-tests2.php is backward compatible with tests developed for
7 the original run-tests.php script. run-tests2 is *not* used by
8 'make test'. run-tests2 was developed to provide support for
9 testing PHP under it's primary environment, HTTP, and can run the
10 PHP tests under any of the SAPI modules that are direct executables,
11 or are accessable via HTTP.
12
13 [New features]
14 ----------------
15 * Command line interface:
16 You can run 'php run-tests2.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 run-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
32 When running tests over http, tests that require ini settings different that what
33 the web server runs under will be skipped. Since the test harness defines a number
34 of ini settings by default, the web server may require special configuration to
35 make testing work.
36
37 [Example Usage]
38 ----------------
39 Some (but not all!) examples of usage:
40
41 1. run tests from the php source directory
42 php run-tests2.php -p /path/to/php-cli
43
44 2. run tests using cgi emulation
45 php run-tests2.php -p /path/to/php-cgi
46
47 3. run tests over http, copying test files into document root
48 php run-tests2.php -w -u http://localhost/test -m /path/to/htdocs/test
49
50 4. run tests over http, php sources have been aliased in web server
51 php run-tests2.php -w -u http://localhost/test
52
53 5. run tests using configuration file
54 php run-tests2.php -c /path/to/run-tests-config.php
55
56 6. run tests using configuration file, but overriding some settings:
57 (config file must be first)
58 php run-tests2.php -c /path/to/run-tests-config.php -w -t 3 -d /path/to/testdir
59
60 NOTE: configuration as described in README.TESTING still works.
61
62 [New Test Sections]
63 ----------------
64 In addition to the traditional test sections
65 (see http://qa.php.net/write-test.php), several new sections are available
66 under run-tests2.
67
68 --POST--
69 This is not a new section, but not multipart posts are supported for testing
70 file uploads, or other types of POST data.
71
72 --CGI--
73 This section takes no value. It merely provides a simple marker for tests
74 that MUST be run as CGI, even if there is no --POST-- or --GET-- sections
75 in the test file.
76
77 --DESCRIPTION--
78 Not used for anything, just a section for documenting the test
79
80 --ENV--
81 This section get's eval()'d to help build an environment for the
82 execution of the test. This can be used to change environment
83 vars that are used for CGI emulation, or simply to set env vars
84 for 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
93 Some variables are made easily available for use in this section, they
94 include:
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 run-tests2 configuration vars
101 $this->env all environment variables that will get passed to the test
102
103
104 --REQUEST--
105 This section is also eval'd, and is similar in nature to --ENV--. However,
106 this section is used to build the url used in an HTTP request. Valid values
107 to 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--
119 This section is also eval'd. It is used to provide additional headers sent
120 in 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--
129 This section can be used to define what headers are required to be
130 received back from a request, and is checked in addition to the
131 regular expect sections. For example:
132
133 --EXPECTHEADERS--
134 Status: 404
135
136
137
138 README.UNIX-BUILD-SYSTEM
1 PHP 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
24 The Reason For a New System
25
26 It became more and more apparent that there is a severe need
27 for addressing the portability concerns and improving the chance
28 that 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
32 If You Build PHP on a Unix System
33
34
35 You, as a user of PHP, will notice no changes. Of course, the build
36 system will be faster, look better and work smarter.
37
38
39
40 If You Are Developing PHP
41
42
43
44
45 Extension developers:
46
47 Makefile.ins are abandoned. The files which are to be compiled
48 are specified in the config.m4 now using the following macro:
49
50 PHP_NEW_EXTENSION(foo, foo.c bar.c baz.cpp, $ext_shared)
51
52 E.g. this enables the extension foo which consists of three source-code
53 modules, two in C and one in C++. And, depending on the user's wishes,
54 the extension will even be built as a dynamic module.
55
56 The full syntax:
57
58 PHP_NEW_EXTENSION(extname, sources [, shared [,sapi_class[, extra-cflags]]])
59
60 Please have a look at acinclude.m4 for the gory details and meanings
61 of the other parameters.
62
63 And that's basically it for the extension side.
64
65 If you previously built sub-libraries for this module, add
66 the source-code files here as well. If you need to specify
67 separate include directories, do it this way:
68
69 PHP_NEW_EXTENSION(foo, foo.c mylib/bar.c mylib/gregor.c,,,-I@ext_srcdir@/lib)
70
71 E.g. this builds the three files which are located relative to the
72 extension source directory and compiles all three files with the
73 special include directive (@ext_srcdir@ is automatically replaced).
74
75 Now, you need to tell the build system that you want to build files
76 in a directory called $ext_builddir/lib:
77
78 PHP_ADD_BUILD_DIR($ext_builddir/lib)
79
80 Make sure to call this after PHP_NEW_EXTENSION, because $ext_builddir
81 is only set by the latter.
82
83 If you have a complex extension, you might to need add special
84 Make rules. You can do this by calling PHP_ADD_MAKEFILE_FRAGMENT
85 in your config.m4 after PHP_NEW_EXTENSION.
86
87 This will read a file in the source-dir of your extension called
88 Makefile.frag. In this file, $(builddir) and $(srcdir) will be
89 replaced by the values which are correct for your extension
90 and which are again determined by the PHP_NEW_EXTENSION macro.
91
92 Make sure to prefix *all* relative paths correctly with either
93 $(builddir) or $(srcdir). Because the build system does not
94 change the working directory anymore, we must use either
95 absolute paths or relative ones to the top build-directory.
96 Correct prefixing ensures that.
97
98
99 SAPI developers:
100
101 Instead of using PHP_SAPI=foo/PHP_BUILD_XYZ, you will need to type
102
103 PHP_SELECT_SAPI(name, type, sources.c)
104
105 I.e. specify the source-code files as above and also pass the
106 information regarding how PHP is supposed to be built (shared
107 module, program, etc).
108
109 For example for APXS:
110
111 PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php5.c php_apache.c)
112
113
114
115 General info
116
117 The foundation for the new system is the flexible handling of
118 sources and their contexts. With the help of macros you
119 can define special flags for each source-file, where it is
120 located, in which target context it can work, etc.
121
122 Have a look at the well documented macros
123 PHP_ADD_SOURCES(_X) in acinclude.m4.
124 README.UPDATE_5_2
1 PHP 5.2 UPDATE INFO
2
3 ===============================
4 Changes in PHP datetime support
5 ===============================
6
7 Since PHP 5.1, there has been an extension named 'date' in the PHP core. This
8 is the new implementation of PHP's datetime support. Although it will attempt
9 to guess your system's timezone setting, you should set the timezone manually.
10 You can do this in any of three ways:
11
12 1) in your php.ini using the date.timezone INI directive
13 2) on your system using the TZ environmental variable
14 3) from your script using the convenience function date_default_timezone_set()
15
16 All supported timezones are listed in the PHP Manual at
17 http://www.php.net/manual/timezones.php.
18
19 With the advent of PHP 5.2, there are object representations of the date and
20 timezone, named DateTime and DateTimeZone respectively. You can see the methods
21 and constants available to the new classes by running
22
23 php --rc DateTime
24 php --rc DateTimeZone
25
26 under PHP CLI - or see the PHP Manual under Date/Time functions, or the 'NEW
27 FEATURES' section below. All methods map to existing procedural date functions.
28
29 ==================================
30 Items 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
176 ==================
177 NEW ERROR MESSAGES
178 ==================
179
180 In the PHP core
181 ===============
182
183 <?php
184
185 print 10%0;
186 /* Warning: Division by zero in filename on line n */
187
188 echo " ";
189 session_regenerate_id();
190 /* Warning: session_regenerate_id(): Cannot regenerate session id - headers already sent in filename on line n */
191
192 str_word_count("string", 4);
193 /* Warning: str_word_count(): Invalid format value 4 in filename on line n */
194
195 strripos("foo", "f", 4);
196 /* Notice: strripos(): Offset is greater than the length of haystack string in filename on line n */
197
198 strrpos("foo", "f", 4);
199 /* Notice: strrpos(): Offset is greater than the length of haystack string in filename on line n */
200
201 ?>
202
203 OO related in the PHP core
204 ==========================
205
206 <?php
207
208 interface foo {
209 }
210 class bar implements foo, foo {
211 }
212 /* Fatal error: Class bar cannot implement previously implemented interface foo in filename on line n */
213
214
215 class foo {
216 public $bar;
217 function __get($var)
218 {
219 return $this->bar;
220 }
221 }
222
223 $foo = new foo;
224 $bar =& $foo->prop;
225 /* Notice: Indirect modification of overloaded property foo::$prop has no effect in filename on line n */
226
227
228 class foo implements iterator {
229 public function current() {
230
231 }
232 public function next() {
233
234 }
235 public function key() {
236
237 }
238 public function valid() {
239
240 }
241 public function rewind() {
242
243 }
244 }
245
246 $foo = new foo();
247 foreach($foo as &$ref) {}
248 /* Fatal error: An iterator cannot be used with foreach by reference in filename on line n */
249
250
251 class foo {
252 private function __construct() {
253 }
254 }
255 class bar extends foo {
256 public function __construct() {
257 parent::__construct();
258 /* Fatal error: Cannot call private foo::__construct() in filename on line n */
259 }
260 }
261 new bar;
262
263
264 abstract class foo {
265 abstract static function bar();
266 /* Strict Standards: Static function foo::bar() should not be abstract in filename on line n */
267 }
268
269
270 stream_filter_register("", "class");
271 /* Warning: stream_filter_register(): Filter name cannot be empty in filename on line n */
272
273 stream_filter_register("filter", "");
274 /* Warning: stream_filter_register(): Class name cannot be empty in filename on line n */
275
276
277 class foo {
278 public function __toString() {
279 throw new Exception;
280 }
281 }
282 try {
283 print new foo;
284 /* Fatal error: Method foo::__toString() must not throw an exception in filename on line n */
285 } catch(Exception $e) {}
286
287
288 class foo {}
289 $foo = new foo;
290 print $foo;
291 /* Catchable fatal error: Object of class foo could not be converted to string in filename on line n */
292
293 ?>
294
295 In the bzip2 extension
296 ======================
297
298 <?php
299
300 bzopen("", "w");
301 /* Warning: bzopen(): filename cannot be empty in filename on line n */
302
303 bzopen("foo", "a");
304 /* Warning: bzopen(): 'a' is not a valid mode for bzopen(). Only 'w' and 'r' are supported in filename on line n */
305
306 $fp = fopen("foo", "w");
307 bzopen($fp, "r");
308 /* Warning: bzopen(): cannot read from a stream opened in write only mode in filename on line n */
309
310 ?>
311
312 In the dBase extension
313 ======================
314
315 <?php
316
317 dbase_open("foo", -1);
318 /* Warning: Invalid access mode -1 in filename on line n */
319
320 ?>
321
322 In the mcrypt extension
323 =======================
324
325 <?php
326
327 $key = "this is a secret key";
328
329 $td = mcrypt_module_open('tripledes', '', 'ecb', '');
330 $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
331 mcrypt_generic_init($td, $key, $iv);
332 $encrypted_data = mcrypt_generic($td, "");
333 /* Warning: mcrypt_generic(): An empty string was passed in filename on line n */
334
335 ?>
336
337 In the oci8 extension
338 =====================
339
340 <?php
341
342 oci_connect("user", "pass", "db", "bogus_charset");
343 /* Warning: Invalid character set name: bogus_charset in filename on line n */
344
345 $oci = oci_connect("user", "pass", "db");
346 oci_password_change($oci, "", "old", "new");
347 /* Warning: username cannot be empty in filename on line n */
348
349 oci_password_change($oci, "user", "", "new");
350 /* Warning: old password cannot be empty in filename on line n */
351
352 oci_password_change($oci, "user", "old", "");
353 /* Warning: new password cannot be empty in filename on line n */
354
355 ?>
356
357 In the SPL extension
358 ====================
359
360 <?php
361
362 $obj = new SplFileObject(__FILE__);
363 $obj->fgetcsv("foo");
364 /* Warning: SplFileObject::fgetcsv(): delimiter must be a character in filename on line n */
365
366 $obj->fgetcsv(",", "foo");
367 /* Warning: SplFileObject::fgetcsv(): enclosure must be a character in filename on line n */
368
369 ?>
370
371
372 ============
373 NEW FEATURES
374 ============
375
376 New extensions
377 ==============
378
379 Filter
380 Methods:
381 mixed filter_has_var(constant type, string variable_name)
382 - Returns true if the variable with the name 'name' exists in source
383 int filter_id(string filtername)
384 - Returns the filter ID belonging to a named filter
385 mixed filter_input(constant type, string variable_name [, long filter [, mixed options]])
386 - Returns the filtered variable 'name'* from source `type`
387 mixed filter_input_array(constant type, [, mixed options]])
388 - Returns an array with all arguments defined in 'definition'
389 array filter_list()
390 - Returns a list of all supported filters
391 mixed filter_var(mixed variable [, long filter [, mixed options]])
392 - Returns the filtered version of the variable.
393 mixed filter_var_array(array data, [, mixed options]])
394 - Returns an array with all arguments defined in 'definition'
395
396 JSON
397 Methods:
398 mixed json_decode(string json[, boolean assoc=0])
399 - Decodes a JSON string into a PHP object/associative array
400 string json_encode(mixed parameter)
401 - Takes a object or an array and returns a JSON encoded string
402
403 Zip
404 Class constants:
405 ZipArchive::CHECKCONS
406 ZipArchive::CM_DEFAULT
407 ZipArchive::CM_DEFLATE
408 ZipArchive::CM_DEFLATE64
409 ZipArchive::CM_IMPLODE
410 ZipArchive::CM_PKWARE_IMPLODE
411 ZipArchive::CM_REDUCE_1
412 ZipArchive::CM_REDUCE_2
413 ZipArchive::CM_REDUCE_3
414 ZipArchive::CM_REDUCE_4
415 ZipArchive::CM_SHRINK
416 ZipArchive::CM_STORE
417 ZipArchive::CREATE
418 ZipArchive::ER_CHANGED
419 ZipArchive::ER_CLOSE
420 ZipArchive::ER_COMPNOTSUPP
421 ZipArchive::ER_CRC
422 ZipArchive::ER_DELETED
423 ZipArchive::ER_EOF
424 ZipArchive::ER_EXISTS
425 ZipArchive::ER_INCONS
426 ZipArchive::ER_INTERNAL
427 ZipArchive::ER_INVAL
428 ZipArchive::ER_MEMORY
429 ZipArchive::ER_MULTIDISK
430 ZipArchive::ER_NOENT
431 ZipArchive::ER_NOZIP
432 ZipArchive::ER_OK
433 ZipArchive::ER_OPEN
434 ZipArchive::ER_READ
435 ZipArchive::ER_REMOVE
436 ZipArchive::ER_RENAME
437 ZipArchive::ER_SEEK
438 ZipArchive::ER_TMPOPEN
439 ZipArchive::ER_WRITE
440 ZipArchive::ER_ZIPCLOSED
441 ZipArchive::ER_ZLIB
442 ZipArchive::EXCL
443 ZipArchive::FL_COMPRESSED
444 ZipArchive::FL_NOCASE
445 ZipArchive::FL_NODIR
446 ZipArchive::FL_UNCHANGED
447 ZipArchive::OVERWRITE
448
449 Functions:
450 void zip_close(resource zip)
451 - Close a Zip archive
452 void zip_entry_close(resource zip_ent)
453 - Close a zip entry
454 int zip_entry_compressedsize(resource zip_entry)
455 - Return the compressed size of a Zip entry
456 string zip_entry_compressionmethod(resource zip_entry)
457 - Return a string containing the compression method used on a particular entry
458 int zip_entry_filesize(resource zip_entry)
459 - Return the actual filesize of a Zip entry
460 string zip_entry_name(resource zip_entry)
461 - Return the name given a Zip entry
462 bool zip_entry_open(resource zip_dp, resource zip_entry [, string mode])
463 - Open a Zip File, pointed by the resource entry
464 mixed zip_entry_read(resource zip_entry [, int len])
465 - Read from an open directory entry
466 resource zip_open(string filename)
467 - Create new zip using source URI for output
468 resource zip_read(resource zip)
469 - Returns the next file in the archive
470 Methods:
471 bool ZipArchive::addFile(string filepath[, string entryname[, int start [, int length]]])
472 - Add a file in a Zip archive using its path and the name to use
473 bool ZipArchive::addFromString(string name, string content)
474 - Add a file using content and the entry name
475 void ZipArchive::close()
476 - close the zip archive
477 bool ZipArchive::deleteIndex(int index)
478 - Delete a file using its index
479 bool ZipArchive::deleteName(string name)
480 - Delete a file using its index
481 bool ZipArchive::extractTo(string pathto[, mixed files])
482 - Extract one or more file from a zip archive to a specified destination
483 string ZipArchive::getArchiveComment()
484 - Returns the Zip archive comment
485 string ZipArchive::getCommentIndex(int index)
486 - Returns the comment of an entry using its index
487 string ZipArchive::getCommentName(string name)
488 - Returns the comment of an entry using its name
489 string ZipArchive::getFromName(string entryname[, int len [, int flags]])
490 - get the contents of an entry using its name
491 string ZipArchive::getFromIndex(string entryname[, int len [, int flags]])
492 - get the contents of an entry using its index
493 string ZipArchive::getNameIndex(int index [, int flags])
494 - Returns the name of the file at position index
495 resource ZipArchive::getStream(string entryname)
496 - Get a stream for an entry using its name
497 int ZipArchive::locateName(string filename[, int flags])
498 - Returns the index of the entry named filename in the archive
499 mixed ZipArchive::open(string source [, int flags])
500 - Create new zip using source URI for output, return TRUE on success or the error code
501 bool ZipArchive::renameIndex(int index, string new_name)
502 - Rename an entry selected by its index to new_name
503 bool ZipArchive::renameName(string name, string new_name)
504 - Rename an entry selected by its name to new_name
505 bool ZipArchive::setArchiveComment(string name, string comment)
506 - Set or remove (NULL/'') the comment of the archive
507 bool ZipArchive::setCommentIndex(int index, string comment)
508 - Set or remove (NULL/'') the comment of an entry using its index
509 bool ZipArchive::setCommentName(string name, string comment)
510 - Set or remove (NULL/'') the comment of an entry using its Name
511 array ZipArchive::statIndex(int index[, int flags])
512 - Returns the zip entry information using its index
513 array ZipArchive::statName(string filename[, int flags])
514 - Returns the information about a the zip entry filename
515 bool ZipArchive::unchangeAll()
516 - All changes made to the archive are reverted
517 bool ZipArchive::unchangeArchive()
518 - Revert all global changes to the archive. For now, this only reverts archive comment changes
519 bool ZipArchive::unchangeIndex(int index)
520 - Changes to the file at position index are reverted
521 bool ZipArchive::unchangeName(string name)
522 - Changes to the file named 'name' are reverted
523
524
525 New classes
526 ===========
527
528 DateTime:
529 Constants:
530 DateTime::ATOM
531 DateTime::COOKIE
532 DateTime::ISO8601
533 DateTime::RFC822
534 DateTime::RFC850
535 DateTime::RFC1036
536 DateTime::RFC1123
537 DateTime::RFC2822
538 DateTime::RFC3339
539 DateTime::RSS
540 DateTime::W3C
541 Methods:
542 DateTime::__construct([string time[, DateTimeZone object]])
543 - Returns new DateTime object
544 string DateTime::format(DateTime object, string format)
545 - Returns date formatted according to given format
546 long DateTime::getOffset(DateTime object)
547 - Returns the DST offset
548 DateTimeZone DateTime::getTimezone(DateTime object)
549 - Return new DateTimeZone object relative to give DateTime
550 void DateTime::modify(DateTime object, string modify)
551 - Alters the timestamp
552 array DateTime::parse(string date)
553 - Returns associative array with detailed info about given date
554 void DateTime::setDate(DateTime object, long year, long month, long day)
555 - Sets the date
556 void DateTime::setISODate(DateTime object, long year, long week[, long day])
557 - Sets the ISO date
558 void DateTime::setTime(DateTime object, long hour, long minute[, long second])
559 - Sets the time
560 void DateTime::setTimezone(DateTime object, DateTimeZone object)
561 - Sets the timezone for the DateTime object
562
563 DateTimeZone:
564 Methods:
565 DateTimeZone DateTimeZone::__construct(string timezone)
566 - Returns new DateTimeZone object
567 string DateTimeZone::getName(DateTimeZone object)
568 - Returns the name of the timezone
569 long DateTimeZone::getOffset(DateTimeZone object, DateTime object)
570 - Returns the timezone offset
571 array DateTimeZone::getTransitions(DateTimeZone object)
572 - Returns numerically indexed array containing associative array for all transitions for the timezone
573
574 RecursiveRegexIterator:
575 extends RegexIterator
576 implements OuterIterator, Traversable, Iterator, RecursiveIterator
577 Methods:
578 RecursiveRegexIterator::__construct(RecursiveIterator it, string regex [, int mode [, int flags [, int preg_flags]]])
579 Create an RecursiveRegexIterator from another recursive iterator and a regular expression
580 RecursiveRegexIterator RecursiveRegexIterator::getChildren()
581 Return the inner iterator's children contained in a RecursiveRegexIterator
582 bool RecursiveRegexIterator::hasChildren()
583 Check whether the inner iterator's current element has children
584
585 RegexIterator:
586 extends FilterIterator
587 implements Iterator, Traversable, OuterIterator
588 Constants:
589 RecursiveRegexIterator::ALL_MATCHES
590 RecursiveRegexIterator::GET_MATCH
591 RecursiveRegexIterator::MATCH
592 RecursiveRegexIterator::REPLACE
593 RecursiveRegexIterator::SPLIT
594 RecursiveRegexIterator::USE_KEY
595 Properties:
596 public $replacement
597 Methods:
598 RegexIterator::__construct(Iterator it, string regex [, int mode [, int flags [, int preg_flags]]])
599 - Create an RegexIterator from another iterator and a regular expression
600 bool RegexIterator::accept()
601 - Match (string)current() against regular expression
602 bool RegexIterator::getFlags()
603 - Returns current operation flags
604 bool RegexIterator::getMode()
605 - Returns current operation mode
606 bool RegexIterator::getPregFlags()
607 - Returns current PREG flags (if in use or NULL)
608 bool RegexIterator::setFlags(int new_flags)
609 - Set operation flags
610 bool RegexIterator::setMode(int new_mode)
611 - Set new operation mode
612 bool RegexIterator::setPregFlags(int new_flags)
613 - Set PREG flags
614
615
616 New methods
617 ===========
618
619 In ext/dom
620 ==========
621 DOMDocument:
622 DOMDocument::registerNodeClass(string baseclass, string extendedclass)
623 - Register extended class used to create base node type
624
625 DOMElement:
626 DOMElement::setIDAttribute(string name, boolean isId)
627 - Declares the attribute specified by name to be of type ID
628 DOMElement::setIDAttributeNode(DOMAttr idAttr, boolean isId)
629 - Declares the attribute specified by node to be of type ID
630 DOMElement::setIDAttributeNS(string namespaceURI, string localName, boolean isId)
631 - Declares the attribute specified by local name and namespace URI to be of type ID
632
633 DOMNode:
634 DOMNode::C14N([bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
635 - Canonicalize nodes to a string
636 DOMNode::C14NFile(string uri [, bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
637 - Canonicalize nodes to a file
638 DOMNode::getNodePath()
639 - Gets an xpath for a node
640
641 In ext/soap
642 ===========
643 SoapServer:
644 SoapServer::setObject(object obj)
645 - Sets object which will handle SOAP requests
646
647 In ext/spl
648 ==========
649 ArrayObject:
650 int ArrayObject::asort(void)
651 - Sort the entries by values
652 int ArrayObject::ksort(void)
653 - Sort the entries by key
654 int ArrayObject::natcasesort(void)
655 - Sort the entries by key using case insensitive "natural order" algorithm.
656 int ArrayObject::natsort(void)
657 - Sort the entries by values using "natural order" algorithm.
658 int ArrayObject::uasort(callback cmp_function)
659 - Sort the entries by values user defined function
660 int ArrayObject::uksort(callback cmp_function)
661 - Sort the entries by key using user defined function.
662
663 AppendIterator:
664 ArrayIterator AppendIterator::getArrayIterator()
665 Get access to inner ArrayIterator
666 int AppendIterator::getIteratorIndex()
667 Get index of iterator
668
669 CachingIterator:
670 bool CachingIterator::getCache()
671 Return the cache
672 int CachingIterator::getFlags()
673 Return the internal flags
674 bool CachingIterator::offsetExists(mixed index)
675 Return whether the requested index exists
676 string CachingIterator::offsetGet(mixed index)
677 - Return the internal cache if used
678 void CachingIterator::offsetSet(mixed index, mixed newval)
679 - Set given index in cache
680 void CachingIterator::offsetUnset(mixed index)
681 - Unset given index in cache
682 void CachingIterator::setFlags()
683 Set the internal flags
684
685 SplFileObject:
686 array("delimiter" =>, "enclosure" =>) SplFileObject::getCsvControl(void)
687 - Get the delimiter and enclosure character used in fgetcsv
688 void SplFileObject::setCsvControl([string delimiter = ',' [, string enclosure = '"']])
689 - Set the delimiter and enclosure character used in fgetcsv
690
691 XMLReader:
692 boolean XMLReader::setSchema(string filename)
693 Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first Read()
694
695
696 New class constants
697 ===================
698
699 In ext/pdo
700 ==========
701 PDO::ATTR_DEFAULT_FETCH_MODE
702 PDO::FETCH_PROPS_LATE
703
704 In ext/spl
705 ==========
706 CachingIterator::FULL_CACHE
707 CachingIterator::TOSTRING_USE_INNER
708
709 SplFileObject::READ_AHEAD
710 SplFileObject::READ_CSV
711 SplFileObject::SKIP_EMPTY
712
713
714 New functions
715 =============
716
717 In the PHP core
718 ===============
719 array array_fill_keys(array keys, mixed val)
720 - Create an array using the elements of the first parameter as keys, each initialized to val
721 array error_get_last()
722 - Get the last occurred error as associative array. Returns NULL if there hasn't been an error yet
723 string image_type_to_extension(int imagetype [, bool include_dot])
724 - Get file extension for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype
725 int memory_get_peak_usage([real_usage])
726 - Returns the peak allocated by PHP memory
727 array timezone_abbreviations_list()
728 - Returns associative array containing DST, offset and the timezone name
729 array timezone_identifiers_list()
730 - Returns numerically indexed array with all timezone identifiers
731 string timezone_name_from_abbr(string abbr[, long gmtOffset[, long isdst]])
732 - Returns the timezone name from abbreviation
733
734 In ext/mbstring
735 ===============
736 array mb_list_encodings_alias_names([string encoding])
737 - Returns an array of all supported entity encodings
738 mixed mb_list_mime_names([string encoding])
739 - Returns an array or string of all supported mime names
740 int mb_stripos(string haystack, string needle [, int offset [, string encoding]])
741 - Finds position of first occurrence of a string within another, case insensitive
742 string mb_stristr(string haystack, string needle[, bool part[, string encoding]])
743 - Finds first occurrence of a string within another, case insensitive
744 string mb_strrchr(string haystack, string needle[, bool part[, string encoding]])
745 - Finds the last occurrence of a character in a string within another
746 string mb_strrichr(string haystack, string needle[, bool part[, string encoding]])
747 - Finds the last occurrence of a character in a string within another, case insensitive
748 int mb_strripos(string haystack, string needle [, int offset [, string encoding]])
749 - Finds position of last occurrence of a string within another, case insensitive
750 string mb_strstr(string haystack, string needle[, bool part[, string encoding]])
751 - Finds first occurrence of a string within another
752
753 In ext/openssl
754 ==============
755 resource openssl_csr_get_public_key(mixed csr)
756 - Extracts public key from a CERT and prepares it for use
757 array openssl_csr_get_subject(mixed csr [, bool use_short_names])
758 - Returns the subject of a CERT
759 array openssl_pkey_get_details(resource key)
760 - returns an array with the key details (bits, pkey, type)
761
762 In ext/spl
763 ==========
764 string spl_object_hash(object obj)
765 - Return hash id for given object
766 int iterator_apply(Traversable it, mixed function [, mixed params])
767 - Calls a function for every element in an iterator
768
769 In ext/pcre
770 ===========
771 int preg_last_error(void)
772 - Returns the error code of the last regex execution
773
774 In ext/pgsql
775 ============
776 mixed pg_field_table(resource result, int field_number[, bool oid_only])
777 - Returns the name of the table field belongs to, or table's oid if oid_only is true
778
779 In ext/posix
780 ============
781 bool posix_initgroups(string name, int base_group_id)
782 - Calculate the group access list for the user specified in name
783
784 In ext/gmp
785 ==========
786 resource gmp_nextprime(resource a)
787 - Finds next prime of a
788
789 In ext/xmlwriter
790 ================
791 bool xmlwriter_full_end_element(resource xmlwriter)
792 - End current element - returns FALSE on error
793 bool xmlwriter_write_raw(resource xmlwriter, string content)
794 - Write text - returns FALSE on error
795
796
797 New optional parameters
798 =======================
799
800 In the PHP core
801 ===============
802 - string base64_decode(string str[, bool strict=false]) (strict)
803 - bool setcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly=false]]]]]] (httponly)
804 - bool setrawcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly=false]]]]]] (httponly)
805 - void session_set_cookie_params(int lifetime [, string path [, string domain [, bool secure[, bool httponly]]]]) (httponly)
806 - int memory_get_usage([bool real_usage=false]) (real_usage)
807
808 In ext/curl
809 ===========
810 - array curl_multi_info_read(resource mh [, long msgs_in_queue]) (msgs_in_queue)
811
812 In ext/mbstring
813 ===============
814 - int mb_strrpos(string haystack, string needle [, int offset [, string encoding]]) (offset)
815
816 In ext/openssl
817 ==============
818 - int openssl_verify(string data, string signature, mixed key [, int signature_algo]) (signature_algo)
819
820 In ext/pgsql
821 ============
822 - string pg_escape_bytea([resource connection,] string data) (connection)
823 - string pg_escape_string([resource connection,] string data) (connection)
824
825 In ext/simplexml
826 ================
827 - SimpleXMLElement::__construct(string data [, int options [, bool data_is_url [, string ns [, bool is_prefix]]]]) (ns, is_prefix)
828 - SimpleXMLElement SimpleXMLElement::attributes([string ns [, bool is_prefix]]) (is_prefix)
829 - SimpleXMLElement SimpleXMLElement::children([string ns [, bool is_prefix]]) (is_prefix)
830 - SimpleXMLElement simplexml_load_file(string filename [, string class_name [, int options [, string ns [, bool is_prefix]]]]) (ns, is_prefix)
831 - SimpleXMLElement simplexml_load_string(string data [, string class_name [, int options [, string ns [, bool is_prefix]]]]) (ns, is_prefix)
832
833 In ext/xmlreader
834 ================
835 - boolean XMLReader::open(string URI [, string encoding [, int options]]) (encoding, options)
836 - boolean XMLReader::XML(string source [, string encoding [, int options]]) (encoding, options)
837
838
839 New INI settings
840 ================
841 allow_url_include PHP_INI_SYSTEM, default: false
842 pcre.backtrack_limit PHP_INI_ALL, default: 100000
843 pcre.recursion_limit PHP_INI_ALL, default: 100000
844 session.cookie_httponly PHP_INI_ALL, default: false
845
846
847 New global constants
848 ====================
849
850 In the PHP core
851 ===============
852 - M_EULER
853 - M_LNPI
854 - M_SQRT3
855 - M_SQRTPI
856 - PATHINFO_FILENAME
857 - PREG_BACKTRACK_LIMIT_ERROR
858 - PREG_BAD_UTF8_ERROR
859 - PREG_INTERNAL_ERROR
860 - PREG_NO_ERROR
861 - PREG_RECURSION_LIMIT_ERROR
862 - UPLOAD_ERR_EXTENSION
863
864 In ext/curl
865 ===========
866 - CURLE_FILESIZE_EXCEEDED
867 - CURLE_FTP_SSL_FAILED
868 - CURLE_LDAP_INVALID_URL
869 - CURLFTPAUTH_DEFAULT
870 - CURLFTPAUTH_SSL
871 - CURLFTPAUTH_TLS
872 - CURLFTPSSL_ALL
873 - CURLFTPSSL_CONTROL
874 - CURLFTPSSL_NONE
875 - CURLFTPSSL_TRY
876 - CURLOPT_FTP_SSL
877 - CURLOPT_FTPSSLAUTH
878
879 In ext/openssl
880 ==============
881 - OPENSSL_VERSION_NUMBER
882 - OPENSSL_VERSION_TEXT
883
884 In ext/snmp
885 ===========
886 - SNMP_OID_OUTPUT_FULL
887 - SNMP_OID_OUTPUT_NUMERIC
888
889 In ext/sysvmsg
890 ==============
891 - MSG_EAGAIN
892 - MSG_ENOMSG
893 README.WIN32-BUILD-SYSTEM
1 The Win32 Build System.
2 $Id: README.WIN32-BUILD-SYSTEM,v 1.4 2003/12/23 02:51:18 wez Exp $
3 Wez Furlong <wez (a] thebrainroom.com>
4
5 If you need help with the build system, send mail to
6 internals (a] lists.php.net; please don't email me directly.
7
8 ===========================================================
9 Contents:
10 1. 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
20 2. How to write config.w32 files
21 x. to be written.
22
23 ===========================================================
24 1. How to build PHP under windows
25 a. 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
88 c. Generating configure
89
90 Change directory to where you have your PHP 5 sources.
91 Run buildconf.bat.
92
93 d. 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
125 e. 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
143 f. 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
150 g. 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
159 h. 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
173 vim:tw=78:sw=1:ts=1:et
174
175 README.Zeus
1 Using PHP 5 with the Zeus Web Server
2 -----------------------------------
3
4 Zeus fully supports running PHP in combination with our
5 webserver. There are three different interfaces that can be used to
6 enable PHP:
7
8 * CGI
9 * ISAPI
10 * FastCGI
11
12 Of the three, we recommend using FastCGI, which has been tested and
13 benchmarked as providing the best performance and reliability.
14
15 Full details of how to install PHP are available from our
16 website, at:
17
18 http://support.zeus.com/products/php.html
19
20 If you have any problems, please check the support site for more
21 up-to-date information and advice.
22
23
24 Quick guide to installing CGI/FastCGI with Zeus
25 -----------------------------------------------
26
27 Step 1 - Compile PHP as FastCGI.
28
29 Compile as follows:
30 ./configure --enable-fastcgi
31 make
32
33 Note that PHP has many options to the configure script -
34 e.g. --with-mysql. You will probably want to select your usual options
35 before compiling; the above is just a bare minimum, for illustration.
36
37 After compilation finishes, you will be left with an executable
38 program called 'php'. Copy this into your document root, under a
39 dedicated FastCGI directory (e.g. $DOCROOT/fcgi-bin/php)
40
41
42 Step 2 - configure Zeus
43
44 Four stages:
45 - enable FastCGI
46 - configure FastCGI
47 - setup alias for FastCGI
48 - setup alias for PHP
49
50 1) Using the admin server, go to the 'module configuration' page for
51 your virtual server, and ensure that 'fastcgi' is enabled (select the
52 tickbox to the left).
53
54 2) While we can run FastCGI's locally, there are known problems with
55 some OS's (specifically, the communication between web server and
56 FastCGI happens over a unix domain socket, and some OS's have trouble
57 sustaining high connection rates over these sockets). So instead, we
58 are 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
64 The first entry is where you saved PHP, above.
65 The second entry is localhost:<any unused port>
66 We will start the FastCGI listening on this port shortly.
67 Click 'update' to commit these changes.
68
69 3) 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
74 Click 'update' to commit these changes
75
76 4) Also on the path mapping module, add a handler for PHP:
77 Add handler
78 File extension php
79 Handler /fcgi-bin/php
80 Click 'update' to commit these changes
81
82 Finally restart your virtual server for these changes to take effect.
83
84
85 Step 3 - start PHP as a FastCGI runner
86
87 When you start PHP, it will pre-fork a given number of child processes
88 to handle incoming PHP requests. Each process will handle a given
89 number of requests before exiting (and being replaced by a newly
90 forked process). You can control these two parameters by setting the
91 following environment variables BEFORE starting the FastCGI runner:
92
93 PHP_FCGI_CHILDREN - the number of child processes to pre-fork. This
94 variable MUST be set, if not then the PHP will not run as a FastCGI.
95 We recommend a value of 8 for a fairly busy site. If you have many,
96 long-running PHP scripts, then you may need to increase this further.
97
98 PHP_FCGI_MAX_REQUESTS - the number of requests each PHP child process
99 handles before exiting. If not set, defaults to 500.
100
101 To start the FastCGI runner, execute '$ZEUSHOME/web/bin/fcgirunner
102 8002 $DOCROOT/fcgi-bin/php'. Substitute the appropriate values for
103 $ZEUSHOME and $DOCROOT; also substitute for 8002 the port you chose,
104 above.
105
106 To stop the runner (e.g. to experiment with the above environment
107 variables) you will need to manually stop and running PHP
108 processes. (Use 'ps' and 'kill'). As it is PHP which is forking lots
109 of children and not the runner, Zeus unfortunately cannot keep track
110 of what processes are running, sorry. A typical command line may look
111 like 'ps -efl | grep $DOCROOT/fcgi-bin/php | grep -v grep | awk
112 '{print $4}' | xargs kill'
113