diff --git a/features/cookies.xml b/features/cookies.xml
new file mode 100644
index 0000000000..ca1f422814
--- /dev/null
+++ b/features/cookies.xml
@@ -0,0 +1,37 @@
+
+ Cookies
+
+
+ PHP transparently supports HTTP cookies. Cookies are a mechanism
+ for storing data in the remote browser and thus tracking
+ or identifying return users. You can set cookies using the
+ setcookie function. Cookies are part of the
+ HTTP header, so setcookie must be called before
+ any output is sent to the browser. This is the same limitation that
+ header has.
+
+
+ Any cookies sent to you from the client will automatically be
+ turned into a PHP variable just like GET and POST method data. If
+ you wish to assign multiple values to a single cookie, just add
+ [] to the cookie name. For more details see
+ the setcookie function.
+
+
+
+
diff --git a/features/error-handling.xml b/features/error-handling.xml
new file mode 100644
index 0000000000..5cbfcf8808
--- /dev/null
+++ b/features/error-handling.xml
@@ -0,0 +1,305 @@
+
+ Error Handling
+
+
+ There are several types of errors and warnings in PHP. They are:
+
+
+
+
+
+ The above values (either numerical or symbolic) are used to build
+ up a bitmask that specifies which errors to report. You can use the
+ bitwise operators
+ to combine these values or mask out certain types of errors. Note
+ that only '|', '~', '!', and '&' will be understood within
+ php.ini, however, and that no bitwise
+ operators will be understood within php3.ini.
+
+
+ In PHP 4, the default error_reporting setting is
+ E_ALL & ~E_NOTICE, meaning to display all errors
+ and warnings which are not E_NOTICE-level. In PHP 3, the default
+ setting is (E_ERROR | E_WARNING | E_PARSE),
+ meaning the same thing. Note, however, that since constants are not
+ supported in PHP 3's php3.ini, the error_reporting setting there
+ must be numeric; hence, it is 7.
+
+
+
+ The initial setting can be changed in the ini file with the error_reporting directive, in
+ your Apache httpd.conf file with the
+ php_error_reporting (php3_error_reporting for PHP 3) directive, and
+ lastly it may be set at runtime within a script by using the
+ error_reporting function.
+
+
+
+
+ When upgrading code or servers from PHP 3 to PHP 4 you should
+ check these settings and calls to
+ error_reporting or you might disable
+ reporting the new error types, especially E_COMPILE_ERROR. This
+ may lead to empty documents without any feedback of what happened
+ or where to look for the problem.
+
+
+
+
+ All PHP expressions can
+ also be called with the "@" prefix, which turns off error reporting
+ for that particular expression. If an error occurred during such
+ an expression and the track_errors feature is enabled,
+ you can find the error message in the global variable
+ $php_errormsg.
+
+
+
+
+ Currently the @
+ error-control operator prefix will even disable error
+ reporting for critical errors that will terminate script
+ execution. Among other things, this means that if you use @ to suppress
+ errors from a certain function and either it isn't available or
+ has been mistyped, the script will die right there with no
+ indication as to why.
+
+
+
+
+ Below we can see an example of using the error handling capabilities in
+ PHP. We define a error handling function which logs the information into
+ a file (using an XML format), and e-mails the developer in case a critical
+ error in the logic happens.
+
+ Using error handling in a script
+
+<?php
+// we will do our own error handling
+error_reporting(0);
+
+// user defined error handling function
+function userErrorHandler ($errno, $errmsg, $filename, $linenum, $vars) {
+ // timestamp for the error entry
+ $dt = date("Y-m-d H:i:s (T)");
+
+ // define an assoc array of error string
+ // in reality the only entries we should
+ // consider are 2,8,256,512 and 1024
+ $errortype = array (
+ 1 => "Error",
+ 2 => "Warning",
+ 4 => "Parsing Error",
+ 8 => "Notice",
+ 16 => "Core Error",
+ 32 => "Core Warning",
+ 64 => "Compile Error",
+ 128 => "Compile Warning",
+ 256 => "User Error",
+ 512 => "User Warning",
+ 1024=> "User Notice"
+ );
+ // set of errors for which a var trace will be saved
+ $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
+
+ $err = "<errorentry>\n";
+ $err .= "\t<datetime>".$dt."</datetime>\n";
+ $err .= "\t<errornum>".$errno."</errnumber>\n";
+ $err .= "\t<errortype>".$errortype[$errno]."</errortype>\n";
+ $err .= "\t<errormsg>".$errmsg."</errormsg>\n";
+ $err .= "\t<scriptname>".$filename."</scriptname>\n";
+ $err .= "\t<scriptlinenum>".$linenum."</scriptlinenum>\n";
+
+ if (in_array($errno, $user_errors))
+ $err .= "\t<vartrace>".wddx_serialize_value($vars,"Variables")."</vartrace>\n";
+ $err .= "</errorentry>\n\n";
+
+ // for testing
+ // echo $err;
+
+ // save to the error log, and e-mail me if there is a critical user error
+ error_log($err, 3, "/usr/local/php4/error.log");
+ if ($errno == E_USER_ERROR)
+ mail("phpdev@mydomain.com","Critical User Error",$err);
+}
+
+
+function distance ($vect1, $vect2) {
+ if (!is_array($vect1) || !is_array($vect2)) {
+ trigger_error("Incorrect parameters, arrays expected", E_USER_ERROR);
+ return NULL;
+ }
+
+ if (count($vect1) != count($vect2)) {
+ trigger_error("Vectors need to be of the same size", E_USER_ERROR);
+ return NULL;
+ }
+
+ for ($i=0; $i<count($vect1); $i++) {
+ $c1 = $vect1[$i]; $c2 = $vect2[$i];
+ $d = 0.0;
+ if (!is_numeric($c1)) {
+ trigger_error("Coordinate $i in vector 1 is not a number, using zero",
+ E_USER_WARNING);
+ $c1 = 0.0;
+ }
+ if (!is_numeric($c2)) {
+ trigger_error("Coordinate $i in vector 2 is not a number, using zero",
+ E_USER_WARNING);
+ $c2 = 0.0;
+ }
+ $d += $c2*$c2 - $c1*$c1;
+ }
+ return sqrt($d);
+}
+
+$old_error_handler = set_error_handler("userErrorHandler");
+
+// undefined constant, generates a warning
+$t = I_AM_NOT_DEFINED;
+
+// define some "vectors"
+$a = array(2,3,"foo");
+$b = array(5.5, 4.3, -1.6);
+$c = array (1,-3);
+
+// generate a user error
+$t1 = distance($c,$b)."\n";
+
+// generate another user error
+$t2 = distance($b,"i am not an array")."\n";
+
+// generate a warning
+$t3 = distance($a,$b)."\n";
+
+?>
+
+
+ This is just a simple example showing how to use the
+ Error Handling and Logging
+ functions.
+
+
+
+ See also error_reporting,
+ error_log,
+ set_error_handler,
+ restore_error_handler,
+ trigger_error,
+ user_error
+
+
+
+
+
diff --git a/features/http-auth.xml b/features/http-auth.xml
new file mode 100644
index 0000000000..4a9414ba92
--- /dev/null
+++ b/features/http-auth.xml
@@ -0,0 +1,125 @@
+
+ HTTP authentication with PHP
+
+
+ The HTTP Authentication hooks in PHP are only available when it is
+ running as an Apache module and is hence not available in the CGI version.
+ In an Apache module PHP script, it is possible to use the
+ Header function to send an "Authentication Required"
+ message to the client browser causing it to pop up a Username/Password
+ input window. Once the user has filled in a username and a password,
+ the URL containing the PHP script will be called again with the variables,
+ $PHP_AUTH_USER, $PHP_AUTH_PW and $PHP_AUTH_TYPE set to the user
+ name, password and authentication type respectively. Only "Basic"
+ authentication is supported at this point. See the Header
+ function for more information.
+
+
+ An example script fragment which would force client authentication
+ on a page would be the following:
+
+
+ HTTP Authentication example
+
+<?php
+ if(!isset($PHP_AUTH_USER)) {
+ Header("WWW-Authenticate: Basic realm=\"My Realm\"");
+ Header("HTTP/1.0 401 Unauthorized");
+ echo "Text to send if user hits Cancel button\n";
+ exit;
+ } else {
+ echo "Hello $PHP_AUTH_USER.<P>";
+ echo "You entered $PHP_AUTH_PW as your password.<P>";
+ }
+?>
+
+
+
+
+ Instead of simply printing out the $PHP_AUTH_USER and
+ $PHP_AUTH_PW, you would probably want to check the username and
+ password for validity. Perhaps by sending a query to a database,
+ or by looking up the user in a dbm file.
+
+
+ Watch out for buggy Internet Explorer browsers out there. They
+ seem very picky about the order of the headers. Sending the
+ WWW-Authenticate header before the
+ HTTP/1.0 401 header seems to do the trick
+ for now.
+
+
+ In order to prevent someone from writing a script which reveals
+ the password for a page that was authenticated through a
+ traditional external mechanism, the PHP_AUTH variables will not be
+ set if external authentication is enabled for that particular
+ page. In this case, the $REMOTE_USER variable can be used to
+ identify the externally-authenticated user.
+
+
+ Note, however, that the above does not prevent someone who
+ controls a non-authenticated URL from stealing passwords from
+ authenticated URLs on the same server.
+
+ Both Netscape and Internet Explorer will clear the local browser
+ window's authentication cache for the realm upon receiving a
+ server response of 401. This can effectively "log out" a user,
+ forcing them to re-enter their username and password. Some people
+ use this to "time out" logins, or provide a "log-out" button.
+
+
+ HTTP Authentication example forcing a new name/password
+
+<?php
+ function authenticate() {
+ Header( "WWW-authenticate: basic realm=\"Test Authentication System\"");
+ Header( "HTTP/1.0 401 Unauthorized");
+ echo "You must enter a valid login ID and password to access this resource\n";
+ exit;
+ }
+
+ if(!isset($PHP_AUTH_USER) || ($SeenBefore == 1 && !strcmp($OldAuth, $PHP_AUTH_USER)) ) {
+ authenticate();
+ }
+ else {
+ echo "Welcome: $PHP_AUTH_USER<BR>";
+ echo "Old: $OldAuth";
+ echo "<FORM ACTION=\"$PHP_SELF\" METHOD=POST>\n";
+ echo "<INPUT TYPE=HIDDEN NAME=\"SeenBefore\" VALUE=\"1\">\n";
+ echo "<INPUT TYPE=HIDDEN NAME=\"OldAuth\" VALUE=\"$PHP_AUTH_USER\">\n";
+ echo "<INPUT TYPE=Submit VALUE=\"Re Authenticate\">\n";
+ echo "</FORM>\n";
+
+}
+?>
+
+
+
+ This behavior is not required by the HTTP Basic authentication
+ standard, so you should never depend on this. Testing with Lynx
+ has shown that Lynx does not clear the authentication credentials
+ with a 401 server response, so pressing back and then forward
+ again will open the resource (as long as the credential
+ requirements haven't changed).
+
+ Also note that this does not work using Microsoft's IIS server and
+ the CGI version of PHP due to a limitation of IIS.
+
+
+
+
diff --git a/features/images.xml b/features/images.xml
new file mode 100644
index 0000000000..a62ab266ea
--- /dev/null
+++ b/features/images.xml
@@ -0,0 +1,59 @@
+
+ Creating and manipulating images
+
+
+ PHP is not limited to creating just HTML output. It can also be
+ used to create and manipulate image files in a variety of different
+ image formats, including gif, png, jpg, wbmp, and xpm. Even more
+ convenient, php can output image streams directly to a browser. You
+ will need to compile PHP with the GD library of image functions for
+ this to work. GD and PHP may also require other libraries, depending
+ on which image formats you want to work with. GD stopped supporting
+ Gif images in version 1.6.
+
+
+
+
+ PNG creation with PHP
+
+<?php
+ Header("Content-type: image/png");
+ $string=implode($argv," ");
+ $im = imageCreateFromPng("images/button1.png");
+ $orange = ImageColorAllocate($im, 220, 210, 60);
+ $px = (imagesx($im)-7.5*strlen($string))/2;
+ ImageString($im,3,$px,9,$string,$orange);
+ ImagePng($im);
+ ImageDestroy($im);
+?>
+
+
+
+ This example would be called from a page with a tag like: <img
+ src="button.php?text"> The above button.php script
+ then takes this "text" string an overlays it on top of a
+ base image which in this case is "images/button1.png"
+ and outputs the resulting image. This is a very convenient way to
+ avoid having to draw new button images every time you want to
+ change the text of a button. With this method they are
+ dynamically generated.
+
+
+
+
+