/manual/phpfi2.php
PHP | 7638 lines | 6754 code | 854 blank | 30 comment | 300 complexity | d678613bf0df6aa12b2164d01c894d48 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- <?php
- // $Id$
- $_SERVER['BASE_PAGE'] = 'manual/phpfi2.php';
- include_once $_SERVER['DOCUMENT_ROOT'] . '/include/prepend.inc';
- site_header('PHP/FI Version 2.0 Documentation');
- ?>
- <!--
- Documentation is like sex: when it is good, it is very, very good; and
- when it is bad, it is better than nothing.
- ++ Dick Brandon
- -->
- <h1 style="text-align: center;">PHP/FI Version 2.0</h1>
- <h1>Table of Contents</h1>
- <ol>
- <li><a href="#history">Brief History</a></li>
- <li><a href="#install">Installation Instructions</a></li>
- <li><a href="#starting">So, what can I do with PHP/FI?</a></li>
- <li><a href="#redirect">CGI Redirection</a></li>
- <li><a href="#security">Security Issues</a></li>
- <li><a href="#safemode">Safe Mode</a></li>
- <li><a href="#commandline">Running PHP/FI from the Command
- Line</a></li>
- <li><a href="#http_auth">HTTP Authentication</a></li>
- <li><a href="#requestvars">Apache Request Variables</a></li>
- <li><a href="#module">Apache Module Notes</a></li>
- <li><a href="#directives">Apache Module Configuration
- Directives</a></li>
- <li><a href="#fastcgi">FastCGI Support</a></li>
- <li><a href="#access">Access Control</a></li>
- <li><a href="#logging">Access Logging</a></li>
- <li><a href="#relative">Relative vs. Absolute URL's - or, Why
- do my Images Break?</a></li>
- <li>
- <a href="#getpost">How PHP/FI handles GET and POST method
- data</a>
- <ul>
- <li><a href="#selmul"><tt>SELECT MULTIPLE</tt> and
- PHP</a></li>
- <li><a href="#imagecoord"><tt>IMAGE SUBMIT</tt> and
- PHP</a></li>
- </ul>
- </li>
- <li><a href="#gd_support">GD (a graphics library for GIF
- creation) Support in PHP</a></li>
- <li><a href="#virtual_hosts">PHP/FI and Virtual Hosts</a></li>
- <li><a href="#upload">File Upload Support</a></li>
- <li><a href="#cookies">Cookie Support</a></li>
- <li><a href="#msql_support">mSQL Support</a></li>
- <li><a href="#pg95_support">Postgres95/PostgreSQL
- Support</a></li>
- <li><a href="#mysql_support">mysql Support</a></li>
- <li><a href="#solid_support">Solid Support</a></li>
- <li><a href="#sybase_support">Sybase Support</a></li>
- <li><a href="#oracle_support">Oracle Support</a></li>
- <li><a href="#illustra_support">Illustra Support</a></li>
- <li><a href="#adabas_support">Adabas Support</a></li>
- <li><a href="#regexp">Regular Expressions</a></li>
- <li><a href="#escapes">Escape Characters</a></li>
- <li><a href="#octal">Octal notation of Unix file
- permissions</a></li>
- <li>
- <a href="#script">PHP/FI Script Language</a>
- <ul>
- <li><a href="#syntax">Syntax</a></li>
- <li><a href="#vars">Variables</a></li>
- <li><a href="#assoc">Associative Arrays</a></li>
- <li><a href="#varvars">Variable Variables</a></li>
- <li><a href="#lang">Language Constructs</a></li>
- <li><a href="#user_funcs">User-Defined Functions</a></li>
- <li><a href="#scope">Scope of Variables</a></li>
- <li><a href="#math">Mathematical Expressions</a></li>
- <li><a href="#while">While Loops</a></li>
- <li><a href="#switch">Switch Construct</a></li>
- <li><a href="#secure">Secure Variables - Defeating GET
- method hacks</a></li>
- <li><a href="#overload">Overloaded Operators and dealing
- with variable types</a></li>
- <li><a href="#quiet">Suppressing Errors from function
- calls</a></li>
- <li><a href="#funcs">Internal Functions</a></li>
- </ul>
- </li>
- <li><a href="#addfunc">Adding your own functions to
- PHP/FI</a></li>
- <li><a href="#hacknotes">Notes for Code Hacks</a></li>
- </ol>
- <hr />
- <h2><a name="history" id="history">Brief History</a></h2>
- <p>PHP began life as a simple little cgi wrapper written in Perl.
- I wrote it in an afternoon during a period between contracts when
- I needed a quick tool to get an idea of who was reading my online
- resume. It was never intended to go beyond my own private use.
- The web server where I had my resume was extremely overloaded and
- had constant problems forking processes. I rewrote the Perl
- wrapper in C to get rid of the considerable overhead of having to
- fork Perl each time my resume was accessed.</p>
- <p>Eventually other people on the same web server came across my
- wrapper and asked if they could use it. Then, as inevitably
- happens, they started asking for more features. I added more
- features and finally put together a semi-complete distribution
- along with documentation, a mailing-list and a FAQ. The name of
- this first package was Personal Home Page Tools, which later
- became Personal Home Page Construction Kit.</p>
- <p>At the same time I started playing with databases and wrote a
- tool to easily embed SQL queries into web pages. It was basically
- another CGI wrapper that parsed SQL queries and made it easy to
- create forms and tables based on these queries. This tool was
- named FI (Form Interpreter).</p>
- <p>PHP/FI version 2.0 is a complete rewrite of these two packages
- combined into a single program. It has now evolved to the point
- where it is a simple programming language embedded inside HTML
- files. The original acronym, PHP, has stuck. It isn't really
- appropriate any longer. PHP/FI is used more for entire web sites
- today than for small Personal Home Page setups. By whatever name,
- it eliminates the need for numerous small Perl cgi programs by
- allowing you to place simple scripts directly in your HTML files.
- This speeds up the overall performance of your web pages since
- the overhead of forking Perl several times has been eliminated.
- It also makes it easier to manage large web sites by placing all
- components of a web page in a single html file. By including
- support for various databases, it also makes it trivial to
- develop database enabled web pages. Many people find the embedded
- nature much easier to deal with than trying to create separate
- HTML and CGI files.</p>
- <p>PHP Version 3.0 is yet another rewrite. If you are just
- starting out with PHP, I suggest that you start with Version 3.0
- instead of continuing with 2.0 at this point. PHP3 is quickly
- going to replace PHP/FI 2.0 and all development efforts are now
- focused on PHP3. Any remaining bugs in PHP/FI 2.0 are unlikely to
- be fixed unless they are straightforward. More information on
- PHP3 can be found at <a href=
- "http://www.lerdorf.on.ca/php3/">http://www.lerdorf.on.ca/php3</a>.</p>
- <p>Throughout this documentation any references to PHP, FI or
- PHP/FI all refer to the same thing. The difference between PHP
- and FI is only a conceptual one. Both are built from the same
- source distribution. When I build the package without any access
- logging or access restriction support, I call my binary FI. When
- I build with these options, I call it PHP.</p>
- <hr />
- <h2><a name="install" id="install">Installation
- Instructions</a></h2>
- <dl>
- <dt><big>Before You Begin</big></dt>
- <dd>
- <p>If you have absolutely no Unix experience, you may want to
- ask around for someone with a little bit of Unix knowledge to
- help you through this installation. Every attempt has been
- made to make it as simple as possible, but since the software
- is quite involved and relies on a number of different
- components, it is not realistic to assume it will go smoothly
- on all systems. You will probably need someone around who
- knows the particulars of the destination system well.</p>
- </dd>
- <dt><big>Things You Need To Know Before
- Installing</big></dt>
- <dd>
- <p>- Can you run both get and post method cgi programs on
- your server?<br />
- <em>This is not relevant if you installing the Apache module
- version.</em> If not, you can not use this package. On many
- public ISP's CGI programs are either disallowed or severely
- restricted. If this is the case on your system, talk to your
- system administrator and ask him/her to have a look at this
- package and see if they will install it for you.</p>
- </dd>
- <dd>
- <p>- If you have mSQL installed on your system, you need to
- know the base directory of this installation.</p>
- </dd>
- <dd>
- <p>- If you have Postgres95 or PostgreSQL installed on your
- system, you need to know the base directory of this
- installation.</p>
- </dd>
- <dd>
- <p>- If you are going to be storing log and access
- configuration files in an NFS-mounted directory and your
- system does not provide NFS file locking then you will need
- to define the NFS_HACK variable manually in the src/Makefile
- and you may want to use a slightly modified version of the
- gdbm library. See the <strong>nfs_hack.txt</strong> file in
- the doc directory for more information on this.</p>
- </dd>
- <dd>
- <p>- Note that if you are not interested in using PHP to
- track accesses to your pages, do not compile this option into
- the binary. You should also leave out the access restriction
- code. There is considerable overhead in including these
- options.</p>
- </dd>
- <dd>
- <p>- If you are installing the Apache module version, you
- will need to know the Apache src code directory location.</p>
- </dd>
- <dt><big>Installation Steps</big></dt>
- <dd>
- <p><em><strong>Step 1.</strong></em></p>
- <p>Run the install program: <tt>./install</tt></p>
- <p>You will be asked a number of questions. If you do not
- understand what is being asked, simply hit return. The
- default choice should be safe on most systems. This doesn't
- apply for the questions asking you to specify a directory for
- your configuration and log files however. Choose any
- directory to which the httpd (usually "nobody") has write
- privileges. You may create this directory manually somewhere
- and simply <strong><tt>chown nobody
- directory</tt></strong>.</p>
- <p><em><strong>Step 2.</strong></em></p>
- <p>Go into the src directory: <tt>cd src</tt></p>
- <p>Have a look at the php.h file. There are a number of
- compile-time options that can be set here.</p>
- <p><em><strong>Step 3.</strong></em></p>
- <p>type: <tt>make</tt></p>
- <p>This will create the actual executable program file named
- <em>php.cgi</em> by default, or if you are installing the
- Apache module, it will create a <em>libphp.a</em> file.</p>
- <p><em><strong>Step 4. (if you are not installing the Apache
- module version)</strong></em></p>
- <p>Copy the <strong>php.cgi</strong> binary to your system's
- cgi-bin directory. If you do not have access to do this and
- wish to install it in your own personal directory, you may do
- so, but you should set the setuid bit on the executable with:
- <tt>chmod u+s /path/php.cgi</tt></p>
- <p>If you do not make set the setuid bit on the binary then
- any files created by the binary will be owned by the user id
- under which the web server runs. If this is acceptable, then
- you can safely leave the setuid bit off.</p>
- <p><em><strong>Step 4. (if you are installing the Apache
- module version)</strong></em><br />
- Change to your Apache src directory where the
- <em>mod_php.c</em> and <em>mod_php.h</em> files should have
- been copied to. If they weren't which usually happens because
- of permission problems, copy these two files there manually.
- Edit your Apache Configuration file and add the EXTRA_LIBS
- line which was produced at the end of <strong>Step
- 3</strong>. And add:</p>
- <p><tt><strong>Module php_module mod_php.o</strong></tt></p>
- <p>to the very end of the file. Then type:
- <strong>./Configure</strong> and then <strong>make</strong>
- to rebuild your Apache httpd binary. Install this binary.</p>
- <p>Next you need to edit your Apache conf/srm.conf file and
- add a line like:</p>
- <p><tt><strong>AddType application/x-httpd-php
- .phtml</strong></tt></p>
- <p>This defines a new MIME, application/x-httpd-php, which
- will trigger the PHP module to parse any file ending with the
- <em>.phtml</em> extension. You can pick any extension you
- like for this.</p>
- <p>You may not want to enable everyone to run PHP parsed
- files. You can place the above AddType line within
- <Location /path>....</Location> directives in the
- <em>access.conf</em> file to only allow PHP-parsed documents
- in certain directories on your server.</p>
- <p>Now you are ready to restart your httpd server. See the
- <a href="#module">Apache Module Notes</a> for more details on
- configuring the PHP Module.</p>
- </dd>
- <dt><big>Testing the software</big></dt>
- <dd>
- <p>Once installed you can test to see if your executable
- works by entering a URL similar to the following in your
- browser:</p>
- <p><tt>http://your.site.domain/cgi-bin/php.cgi</tt></p>
- <p>This should show you a page which contains the version
- number along with various other useful information.</p>
- <p>To test the Apache module version, create any file with a
- .phtml extension and put a tag like: <?phpinfo()> in
- the file and see if it gets parsed.</p>
- </dd>
- <dt><big>Using the software</big></dt>
- <dd>
- <p>To actually use the software on an existing HTML file, you
- can simply append the path to your file to the above URL.
- ie.</p>
- <p>
- <tt>http://your.site.domain/cgi-bin/php.cgi/path/file.html</tt></p>
- <p>You should have a look at the <a href="#redirect">CGI
- Redirection</a> section of this documentation. Running PHP/FI
- through a redirect means you can automatically have a URL
- like <em>http://your.site.domain/file.phtml</em> be parsed by
- PHP/FI.</p>
- <p>This does not apply to Apace module users.</p>
- </dd>
- </dl>
- <hr />
- <h2><a name="starting" id="starting">So, what can I do with
- PHP/FI?</a></h2>
- <p>The first thing you will notice if you run a page through
- PHP/FI is that it adds a footer with information about the number
- of times your page has been accessed (if you have compiled access
- logging into the binary). This is just a very small part of what
- PHP/FI can do for you. It serves another very important role as a
- form interpreter cgi, hence the FI part of the name. For example,
- if you create a form on one of your web pages, you need something
- to process the information on that form. Even if you just want to
- pass the information to another web page, you will have to have a
- cgi program do this for you. PHP/FI makes it extremely easy to
- take form data and do things with it.</p>
- <p><em><strong>A simple example</strong></em></p>
- <p>Suppose you have a form:</p>
- <p><tt><FORM ACTION="/cgi-bin/php.cgi/~userid/display.html"
- METHOD=POST><br />
- <INPUT TYPE="text" name="name"><br />
- <INPUT TYPE="text" name="age"><br />
- <INPUT TYPE="submit"><br />
- </FORM></tt></p>
- <p>Your display.html file could then contain something like:</p>
- <p><tt><?echo "Hi $name, you are $age years
- old!<p>"></tt></p>
- <p>It's that simple! PHP/FI automatically creates a variable for
- each form input field in your form. You can then use these
- variables in the ACTION URL file.</p>
- <p>The next step once you have figured out how to use variables
- is to start playing with some logical flow tags in your pages.
- For example, if you wanted to display different messages based on
- something the user inputs, you would use if/else logic. In our
- above example, we can display different things based on the age
- the user entered by changing our display.html to:</p>
- <pre>
- <?
- if($age>50);
- echo "Hi $name, you are ancient!<p>";
- elseif($age>30);
- echo "Hi $name, you are very old!<p>";
- else;
- echo "Hi $name.";
- endif;
- >
- </pre>
- <p>PHP/FI provides a very powerful scripting language which will
- do much more than what the above simple example demonstrates. See
- the section on the <a href="#script">PHP/FI Script Language</a>
- for more information.</p>
- <p>You can also use PHP/FI to configure who is allowed to access
- your pages. This is done using a built-in configuration screen.
- With this you could for example specify that only people from
- certain domains would be allowed to see your pages, or you could
- create a rule which would password protect certain pages. See the
- <a href="#access">Access Control</a> section for more
- details.</p>
- <p>PHP/FI is also capable of receiving file uploads from any
- RFC-1867 compliant web browser. This feature lets people upload
- both text and binary files. With PHP/FI's access control and
- logical functions, you have full control over who is allowed to
- upload and what is to be done with the file once it has been
- uploaded. See the <a href="#upload">File Upload</a> section for
- more details.</p>
- <p>PHP/FI has support for a database package called mSQL. This
- allows you to put information into a database and access this
- information through simple embedded SQL queries right in your
- .HTML files. Adding a database back-end to a web page has never
- been easier. See the section on <a href="#msql_support">mSQL
- Support</a> for more information.</p>
- <p>PHP/FI has support for the Postgres95/PostgreSQL database
- package. It supports embedded SQL queries in your .HTML files.
- See the section on <a href="#pg95_support">Postgres95/PostgreSQL
- Support</a> for more information.</p>
- <p>PHP/FI also has support for the mysql database package. It
- supports embedded SQL queries in your .HTML files. See the
- section on <a href="#mysql_support">mysql Support</a> for more
- information.</p>
- <hr />
- <h2><a name="redirect" id="redirect">CGI Redirection</a></h2>
- <dl>
- <dt><strong>Apache 1.0.x Notes</strong></dt>
- <dd>
- <p>A good way to run PHP/FI is by using a cgi redirection
- module with the Apache server. Please note that you do not
- need to worry about redirection modules if you are using the
- Apache module version of PHP/FI. There are two of these
- redirection modules available. One is developed by Dave
- Andersen <angio@aros.net> and it is available at
- <a href=
- "ftp://ftp.aros.net/pub/util/apache/mod_cgi_redirect.c">ftp://ftp.aros.net/pub/util/apache/mod_cgi_redirect.c</a>
- and the other comes bundled with Apache and is called
- mod_actions.c. The modules are extremely similar. They differ
- slightly in their usage. Both have been tested and both work
- with PHP/FI.</p>
- <p>One large caveat at the time of this writing (Apr.20/96)
- is that the current official Apache release (1.0.5) has a
- severe limitation which prevents cgi redirected requests from
- having any post-method data associated with them. I have
- tracked this down and fixed it in my version of Apache, and
- there is an official patch available in the <a href=
- "http://php.iquest.net/files/">File Archives</a> on the
- <a href="http://php.iquest.net/">PHP Home Page</a>.</p>
- <p>A second rather large caveat with Apache 1.0.x is that it
- does not align double types correctly on most architectures.
- You may find yourself getting strange bus errors from your
- httpd when using mod_php, either upgrade to Apache 1.1 or
- edit the <i>alloc.c</i> Apache source file. In this file you
- will find the following piece of code:</p>
- <pre>
- union align
- {
- /* Types which are likely to have the longest RELEVANT alignment
- * restrictions... we don't do much with doubles.
- */
- char *cp;
- void (*f)();
- long l;
- FILE *fp;
- };
- </pre>
- <p>You will need to add a double to this line and recompile
- your Apache server. The correct block of code is:</p>
- <pre>
- union align
- {
- /* Types which are likely to have the longest RELEVANT alignment
- * restrictions... we don't do much with doubles.
- */
- char *cp;
- void (*f)();
- long l;
- FILE *fp;
- double d;
- };
- </pre>
- <p>These problems have all been fixed in later versions of
- Apache.</p>
- <p>Check the Apache documentation on how to add a module.
- Generally you add the module name to a file called
- <em>Configuration</em>. The line to be added if you want to
- use the mod_actions module is:</p>
- <p><tt>Module action_module mod_actions.o</tt></p>
- <p>If you are using the mod_cgi_redirect.c module add this
- line:</p>
- <p><tt>Module cgi_redirect_module mod_cgi_redirect.o</tt></p>
- <p>Then compile your httpd and install it. To configure the
- cgi redirection you need to either create a new mime type in
- your <em>mime.types</em> file or you can use the
- <strong>AddType</strong> command in your <em>srm.conf</em>
- file to add the mime type. The mime type to be added should
- be something like this:</p>
- <p><tt>application/x-httpd-php phtml</tt></p>
- <p>If you are using the mod_actions.c module you need to add
- the following line to your <em>srm.conf</em> file:</p>
- <p><tt>Action application/x-httpd-php
- /cgi-bin/php.cgi</tt></p>
- <p>If you are using mod_cgi_redirect.c you should add this
- line to <em>srm.conf</em>:</p>
- <p><tt>CgiRedirect application/x-httpd-php
- /cgi-bin/php.cgi</tt></p>
- <p>Don't try to use both mod_actions.c and mod_cgi_redirect.c
- at the same time.</p>
- <p>Once you have one of these cgi redirection modules
- installed and configured correctly, you will be able to
- specify that you want a file parsed by php/fi simply by
- making the file's extension <strong>.phtml</strong>.
- Furthermore, if you add <strong>index.phtml</strong> to your
- <strong>DirectoryIndex</strong> configuration line in your
- <em>srm.conf</em> file then the top-level page in a directory
- will be automatically parsed by php if your index file is
- called index.phtml.</p>
- </dd>
- <dt><strong>Netscape HTTPD</strong></dt>
- <dd>
- <p>You can automatically redirect requests for files with a
- given extension to be handled by PHP/FI by using the Netscape
- Server CGI Redirection module. This module is available in
- the <a href="http://php.iquest.net/files/">File Archives</a>
- on the <a href="http://php.iquest.net/">PHP/FI Home Page</a>.
- The README in the package explicitly explains how to
- configure it for use with PHP/FI.</p>
- </dd>
- <dt><strong>NCSA HTTPD</strong></dt>
- <dd>
- <p>NCSA does not currently support modules, so in order to do
- cgi redirection with this server you need to modify your
- server source code. A patch to do this with NCSA 1.5 is
- available in the <a href=
- "http://php.iquest.net/files/">PHP/FI file archives</a>.</p>
- </dd>
- </dl>
- <hr />
- <h2><a name="security" id="security">Security Issues</a></h2>
- <p>The CGI version of PHP/FI does <strong>not</strong> read any
- <em>.htaccess</em> files which may be present in a directory.
- This means that if you have files that are protected using the
- standard .htaccess server-based access control feature, people
- could potentially circumvent this security by loading the page
- through PHP/FI. Note that this is not an issue for the Apache
- module version of PHP/FI.</p>
- <p>A second problem with the CGI version is that if it is placed
- in the system's cgi-bin directory it can be used to view any file
- on your system as long as the user id it runs as has access to
- it.</p>
- <p>There are a couple of different solutions to this problem. The
- easiest is probably to use the <strong>PATTERN_RESTRICT</strong>
- feature found in <em>php.h</em>. This lets you define an
- extension (or a pattern of extensions) which are allowed to be
- parsed by PHP/FI. If a file does not have this extension and
- someone tries to load it with PHP/FI, an <em>access denied</em>
- message will appear.</p>
- <p>Another solution is to use the PHP/FI access control mechanism
- to mimic the access control setup you have in your .htaccess
- file. Keeping this information in two places can be tedious
- though, and the two systems don't share all of the same
- features.</p>
- <p>The problem can also be solved using file permissions. PHP/FI
- can be set up to run setuid as any user you wish. Then files that
- are to be read by PHP/FI can be given appropriate permissions and
- files not to be read by PHP/FI should be owned by another user id
- and have their permissions changed accordingly.</p>
- <p>For additional security options related to sites which provide
- shared access to PHP, see the <a href="#safemode">Safe Mode</a>
- section.</p>
- <hr />
- <h2><a name="safemode" id="safemode">Safe Mode</a></h2>
- <p>PHP's Safe Mode tries to solve the common problem faced by
- many ISP's regarding letting all their users run CGI programs.
- The common mechanism for making shared CGI access more secure is
- to use a cgi wrapper like the su_exec utility that comes with
- Apache. This will not work for PHP when it is running as a module
- because it is not a separate process that can be setuid'ed.</p>
- <p>It is based on a file permission scheme. Simply put, if a file
- is either owned by the same user id as the script that is trying
- to access it, or if the file is in a directory that is owned by
- the same user as the script that is trying to access it, then the
- access is allowed. One caveat here is that you must make sure
- that your OS does not allow non-root user to chown away the
- ownership on one of their files. Many older SysV systems allow
- this. The most common one is Irix. It is possible to change this
- behaviour at the OS level on Irix.</p>
- <p>Safe Mode applies to each function which could possibly be a
- security risk. Below is the current list of checks applied to
- each relevant function. In the following list, PHP UID refers to
- the user id of the owner of the current file being parsed by PHP,
- and HTTP UID refers to the user id the httpd process is running
- as (usually nobody).</p>
- <dl>
- <dt>Include, ReadFile, Fopen, File, Link, Unlink, Symlink,
- Rename, RmDir, ChMod, ChOwn, ChGrp</dt>
- <dd>Owner of file to be included must either be the PHP UID or
- the directory in which the file resides must be owned by the
- PHP UID.</dd>
- <dt>Exec, System, PassThru and Popen</dt>
- <dd>Executables to be forked and executed must reside in the
- directory defined by the PHP_SAFE_MODE_EXEC_DIR #define in
- php.h when PHP is compiled.</dd>
- <dt>Mysql_Connect</dt>
- <dd>This function takes an optional username to use to connect
- to an MySQL database. When in safe mode, this username must
- either be the username of the owner of the current file being
- parsed, or the name of the httpd user (usually nobody).</dd>
- <dt>HTTP Authentication</dt>
- <dd>The numerical user id of the owner of the script containing
- the HTTP Authentication code will be prepended to the
- authentication realm. This is to prevent someone from writing a
- password grabbing script which spoofs another authenticated
- page on the same server.</dd>
- </dl>
- <hr />
- <h2><a name="commandline" id="commandline">Running PHP/FI from
- the command line</a></h2>
- <p>If you build the CGI version of PHP/FI, you can use it from
- the command line simply typing: <tt>php.cgi filename</tt> where
- filename is the file you want to parse. You can also create
- standalone PHP/FI scripts by making the first line of your script
- look something like:</p>
- <pre>
- #!/usr/local/bin/php.cgi -q
- </pre>The "-q" suppresses the printing of the HTTP headers. You can
- leave off this option if you like.
- <hr />
- <h2><a name="http_auth" id="http_auth">HTTP
- Authentication</a></h2>
- <p>The HTTP Authentication hooks in PHP/FI are only available
- when it is running as an Apache module. In an Apache module
- PHP/FI script, it is possible to use the Header() command 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/FI 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.</p>
- <p>An example script fragment which would force client
- authentication on a page would be the following:</p>
- <pre>
- <?
- if(!$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>";
- }
- >
- </pre>
- <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.</p>
- <p>Watch out for buggy Internet Explorer browsers out there. They
- seem very picky about the order of the headers. Sending the
- <b>WWW-authenticate</b> header before the <b>HTTP/1.0 401</b>
- header seems to do the trick for now.</p>
- <p>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.</p>
- <p>Note however that the above does not prevent someone who
- controls a non-authenticated URL from stealing passwords from
- authenticated URL's on the same server. The PHP_AUTH_VARS define
- in <em>php.h</em> can be undefined to make sure that these
- variables will never be set and thus disable anybody from using
- mod_php to try to steal passwords.</p>
- <hr />
- <h2><a name="requestvars" id="requestvars">Apache Request
- Variables</a></h2>
- <p>When running PHP as an Apache module, you may access the
- request header variables sent by the remote browser by prepending
- <b>$req_</b> to the beginning of the header value you would like
- to use. If the request name contains a <b>-</b> character such as
- User-Agent, then you need to map the - to _ (an underscore). ie.
- reference it as $req_User_Agent. The <a href=
- "#phpinfo">phpinfo()</a> function can be used to display all the
- request headers.</p>
- <p>eg.</p>
- <pre>
- <
- echo "$req_connection<br>";
- echo "$req_host<br>";
- >
- </pre>The above simple script might output:
- <pre>
- Keep-Alive
- www.host.com
- </pre>
- <hr />
- <h2><a name="module" id="module">Apache Module Notes</a></h2>
- <p>Running PHP/FI as an Apache module is the most efficient way
- of using the package. Running it as a module means that the
- PHP/FI functionality is combined with the Apache server's
- functionality in a single program. There are a number of
- advantages to running it as a module:</p>
- <dl>
- <dt><strong>Performance</strong></dt>
- <dd>
- <p>Performance-wise it is a lot faster than traditional CGI
- programs. In fact, when running PHP/FI as a module, there is
- no CGI involved. The script code in the HTML files is
- executed directly by the Apache web server process.</p>
- </dd>
- <dt><strong>Security</strong></dt>
- <dd>
- <p>When running as a module, the normal httpd-based access
- restriction rules defined either in the Apache conf files or
- in private .htaccess files are first applied before the
- module is allowed to parse the file. Alternatively, you can
- also create PHP/FI scripts that control the normal
- httpd-based authentication. See <a href="#http_auth">HTTP
- Authentication</a>.</p>
- </dd>
- <dt><strong>Configurability</strong></dt>
- <dd>
- <p>Since the parser is always active inside the httpd
- process, it can be configured on startup using the same
- configuration files used to configure the httpd process. The
- module can even be configured on a per-directory basis by
- placing the <a href="#directives">PHP configuration
- directives</a> in the <em>.htaccess</em> files.</p>
- </dd>
- <dt><strong>Basis for custom server-based
- function</strong></dt>
- <dd>
- <p>For C programmers interested in accessing their functions
- from within Apache, the PHP/FI framework provides a very
- simple interface to Apache and to PHP itself. It is much
- easier to add a function to PHP and call that from a parsed
- page than it is to write an entire Apache module from
- scratch. See the <a href="#addfunc">Adding your own internal
- functions to PHP/FI</a> sections at the end of this document
- for further details.</p>
- </dd>
- </dl>
- <h2><a name="directives" id="directives">Apache Module
- Configuration Directives</a></h2>
- <p>The following directives can be placed either in the
- <em>srm.conf</em> file, or within
- <Directory>...</Directory> tags in
- <em>access.conf</em> or in <Location
- /path>...</Location> tags in <em>access.conf</em> or in
- individual <em>.htaccess</em> files. In order for the directives
- to work in .htaccess files, the Options override must be set on
- the AllowOverride Apache directive, with the exception of the
- phpEngine directive which is only available in the *.conf
- files.</p>
- <dl>
- <dt><strong>phpShowInfo <em>on</em>|<em>off</em></strong></dt>
- <dd>Turn the PHP info footers on or off. Default is on.</dd>
- <dt><strong>phpLogging <em>on</em>|<em>off</em></strong></dt>
- <dd>Turn logging on or off. Default is on.</dd>
- <dt><strong>phpDebug <em>on</em>|<em>off</em></strong></dt>
- <dd>Turn automatic ?info debug screen on or off. Default is
- off.</dd>
- <dt><strong>phpUploadTmpDir <em>directory</em></strong></dt>
- <dd>Set the directory where form-uploaded files will be
- placed.</dd>
- <dt><strong>phpDbmLogDir <em>directory</em></strong></dt>
- <dd>Set the directory where dbm-based logging files will be
- written.</dd>
- <dt><strong>phpSQLLogDB <em>database</em></strong></dt>
- <dd>Set name of SQL database to use for logging. Default is
- "phpfi"</dd>
- <dt><strong>phpSQLLogHost <em>hostname</em></strong></dt>
- <dd>Set hostname where SQL database to use for logging is
- found. Default is localhost.</dd>
- <dt><strong>phpAccessDir <em>directory</em></strong></dt>
- <dd>Set the directory where PHP-internal access control files
- are stored.</dd>
- <dt><strong>phpMaxDataSpace <em>KiloBytes</em></strong></dt>
- <dd>Max size a sub-pool can grow to within the PHP module.
- Setting this value to a low number will minimize the impact
- that mod_php will have on your system, but it may also limit
- people from writing complex scripts. The default is 8K.</dd>
- <dt><strong>phpIncludePath <em>colon-separated
- path</em></strong></dt>
- <dd>A colon-separated list of directories where php will look
- for files in when running <a href="#include">include()</a>. The
- default is to look only in the current directory.</dd>
- <dt><strong>phpAutoPrependFile <em>file name</em></strong></dt>
- <dd>Before the actual PHP/FI file is parsed, you may give a
- file name here that is parsed before the "main file", using
- PHP's Include() function (which means phpIncludePath applies
- for the file name). Keep in mind that you can make it difficult
- for yourself to use the Header() function in the main file if
- you write HTML from an auto-prepended file.</dd>
- <dt><strong>phpAutoAppendFile <em>file name</em></strong></dt>
- <dd>The name of a file parsed (using PHP's Include()
- function)after the actual PHP/FI file has been parsed, similar
- to phpAutoPrependFile.</dd>
- <dt><strong>phpAdaDefDB <em>database</em></strong></dt>
- <dd>Default Adabas database to use. No default value</dd>
- <dt><strong>phpAdaUser <em>username</em></strong></dt>
- <dd>Default Adabas database user. No default value</dd>
- <dt><strong>phpAdaPW <em>password</em></strong></dt>
- <dd>Default Adabas database password. No default value</dd>
- <dt><strong>phpEngine <em>on</em>|<em>off</em></strong></dt>
- <dd>Turn the PHP parsing engine on or off. The default is
- <em>on</em> and this directive is only useful for sites that
- wish to allow directives from the AllowOverride Options list of
- directives to function in .htaccess files while at the same
- time restricting mod_php access. The common way to handle
- per-virtual host php installs is to enable the PHP mime type
- with an AddType directive on a per virtual host basis and then
- put "phpEngine off" in the non-PHP virtual host blocks. If a
- non PHP customer tries to circumvent things by placing the PHP
- mime type in their .htaccess, the phpEngine off setting
- restricts the PHP parser from functioning.</dd>
- <dt><strong>phpLastModified
- <em>on</em>|<em>off</em></strong></dt>
- <dd>Since php pages are dynamic, they are processed and sent to
- the browser each time you access them. But sometimes, when you
- use php for basic includes, the parsed page does not change as
- long as the source doesn't. It that case, you may want to avoid
- page regeneration/reloading. If phpLastModified is turned on
- Apache will send the Last-Modified tag to the browser, so that
- the page will only be reloaded when it changes. (not that if
- you are using page logging, multiple accesses will not be
- logged!)</dd>
- </dl>
- <p>All of these directives are optional. If a directive is not
- specified anywhere, the compile-time default will be used.</p>
- <hr />
- <h2><a name="fastcgi" id="fastcgi">FastCGI Support</a></h2>
- <p>PHP/FI can be compiled with FastCGI support. You will need
- fetch and compile <a href="http://www.fastcgi.com">FCGI
- Development Kit</a> for your platform before compiling PHP/FI.
- You will also need to get <a href="#redirect">CGI Redirection</a>
- working. Then follow the instructions in the FastCGI
- documentation for configuring FastCGI for your platform. If you
- are using the mod_fastcgi module with the Apache server, here are
- the step-by-step instructions:</p>
- <ul>
- <li>Edit your Apache Configuration file and add the mod_fastcgi
- module, then recompile Apache.</li>
- <li>Edit your <em>srm.conf</em> file and add lines similar
- to:<br />
- <tt>AddType application/x-httpd-fcgi .fcgi<br />
- AppClass /usr/local/etc/httpd/fcgi-bin/php.fcgi -processes
- 4<br />
- AddType application/x-httpd-fphp .fhtml<br />
- Action application/x-httpd-fphp
- /fcgi-bin/php.fcgi<br /></tt></li>
- <li>Copy your <em>php.cgi</em> binary to
- <em>/usr/local/etc/httpd/fcgi-bin/php.fcgi</em></li>
- </ul>
- <p>Now, any pages with the .fhtml extension will be handed off to
- the FastCGI php.fcgi process which is already running. The
- php.fcgi binary will still work as a normal CGI binary, so you
- could just create a symbolic link from php.cgi to php.fcgi.</p>
- <p>If you are not using Apache, the above steps will be similar,
- but not identical. CGI Redirection mechanisms are available for
- NCSA and Netscape servers at the <a href=
- "http://php.iquest.net/files/">PHP/FI File Archive</a>.</p>
- <hr />
- <h2><a name="access" id="access">Access Control</a></h2>
- <p>Note that the built-in PHP/FI based access control is likely
- to be discontinued in future versions. You should seriously
- consider using the security mechanism that comes with your web
- server instead.</p>
- <p>If you chose to include access control when you compiled the
- package, you may append <em>?config</em> to any URL to edit the
- access control file. ie.</p>
- <p>
- <tt>http://your.machine.domain/cgi-bin/php.cgi/path/file.html?config</tt></p>
- <p>Your configuration password will initially be set to your user
- id. If your user id does not work as your password, it probably
- means that PHP could not read the /etc/passwd file to locate your
- user id. If this is the case, the initial password will be set to
- "<strong>php</strong>". It is a good idea to change this
- password. Note that multiple users may maintain their own
- personal configuration files through a single PHP/FI binary.</p>
- <p>Access Control can be quite confusing initially. The ?config
- screen is divided up into a number of sections. The top section
- is for changing the password used to make sure that only people
- who know this password can change access control characteristics.
- In a system-wide installation, each user has his or her own
- configuration screen with his or her own password.</p>
- <p>The second section of the ?config screen consists of a number
- of tables. Each table defines a rule-set. The first rule-set is
- always the default rule-set. This default rule-set is used if a
- page does not have a rule-set defined specifically for it. After
- the default rule-set, any number of specific rule-set tables will
- follow.</p>
- <p>To add a rule-set for a specific file, enter the URL of the
- file in your browser and add <em><strong>?config</strong></em> to
- the end of the URL. On the ?config screen that comes up you will
- see that a rule-set has been added for this page, if it wasn't
- already there. When a new rule-set is added, it is initially set
- to be the same as the default rule-set. The following picture
- shows two simple rule-sets. First a default rule-set which just
- indicates that hits from all domains should be logged, and
- second, for the file /~rasmus/test.html and only that file, any
- users coming from a "<em>.edu</em>" domain will not be granted
- access.</p>
- <p><img src="gifs/config.gif" alt=
- "[Image of ?config screen]" /></p>
- <p>To edit a rule-set modify the fields until the desired
- configuration is reached within a rule-set and then hit the
- "<em>Submit Changes</em>" button. If more rules are needed, hit
- the "<em>Add Rule</em>" button and then edit the added rule.</p>
- <p>To delete a rule, select the checkbox to the right of the rule
- and hit the "<em>Submit Changes</em>" button. The screen will
- redraw and the rule should disappear.</p>
- <p>Note that you need to enter a regular expression in the
- pattern field. See the section on regular expressions in this
- documentation for more details.</p>
- <hr />
- <h2><a name="logging" id="logging">Access Logging</a></h2>
- <p>Access Logging is another optional feature which can be
- enabled at compile-time by answering <em>Yes</em> to the question
- in the install script. You may either store your access log data
- in dbm files, in an mSQL database, or in an mysql database. The
- latter two are more powerful, but is also a bit more difficult to
- set up.</p>
- <p>To use dbm files for storing your access logs, you will need
- to specify a directory in which log files can be written. PHP
- will try to create this directory if it doesn't exist, but to
- make sure it has the proper permissions, you may want to create
- this directory yourself before running PHP for the first time.
- The permissions on the directory should be such that the user id
- under which the PHP cgi program will run can write to the
- directory.</p>
- <p>To use an mSQL or mysql database for storing your access log
- data, you need to first make sure you have mSQL or mysql
- installed and running on your system. Then you need to create a
- database. The default name is "phpfi" although this can be
- changed in <em>src/php.h</em>. To create this database for mSQL,
- type:</p>
- <pre>
- msqladmin create phpfi
- </pre>
- <p>or for mysql type:</p>
- <pre>
- mysqladmin create phpfi
- </pre>
- <p>Then for mSQL, edit your <em>msql.acl</em> file and make sure
- the permissions on the database are correct. Something like the
- following should suffice:</p>
- <pre>
- database=phpfi
- read=*
- write=nobody,<your user id>
- access=local
- </pre>
- <p>For mysql, you need to make sure the httpd user (usually
- "nobody") has access to the database. Unlike mSQL, mysql stores
- access control data in a database. Assuming default permissions,
- you should be able to simply execute the following command:</p>
- <pre>
- echo "INSERT INTO user VALUES ('localhost','nobody','','Y','Y','Y','Y','Y','Y','Y','Y','Y');" | mysql mysql
- </pre>
- <p>Don't forget to load this new configuration with:</p>
- <pre>
- mysqladmin reload
- </pre>
- <p>For each user id for whom you want to store log data, you need
- to create two tables. The <em>msqllog</em> shell script in the
- scripts directory will do this for you. Simply type:</p>
- <pre>
- msqllog <user id>
- </pre>
- <p>or for mysql, type:</p>
- <pre>
- mysqllog <user id>
- </pre>
- <p>and the script will create the appropriate tables. You may
- need to edit the script to make it reflect where things are
- stored on your system.</p>
- <p>You may want to have a look at this script. It defines the
- field sizes of your log tables. If, for example, you know that
- your file paths exceed 64 characters, you need to bump up the
- filename size in both the <em>logN</em> and the <em>lastN</em>
- tables in this <em>msqllog</em> or <em>mysqllog</em> file.</p>
- <p>Access logging stores information about each "hit" on a page.
- This information can then be summarized by examining these log
- files. An example log file summarizing script is included in the
- package. It is the <tt>log.html</tt> file in the
- <tt>examples</tt> directory. This is the dbm log file analyzer.
- The mSQL log file analyzer is called <tt>mlog.html</tt>. And the
- mysql log file analyzer is called <tt>mylog.html</tt>. To run it,
- copy it and the other mlog.* files to a directory accessible from
- your web server and type:</p>
- <pre>
- http://your.machine.domain/cgi-bin/php.cgi/path/mlog.html
- </pre>
- <p>Or, if you are using the Apache module version, you can give
- the script a ".phtml" extension and call it with:</p>
- <pre>
- http://your.machine.domain/path/mlog.phtml
- </pre>
- <p>By default, if you have compiled PHP with access logging
- enabled, then your pages will appear with a footer containing
- some access information. You may not want to see this footer, but
- still log hits. You can turn off this footer with a "phpShowInfo
- off" line in your Apache httpd.conf or .htaccess files if you are
- running Apache. If you are not running Apache, you may turn these
- log footers off either by creating a rule in the <a href=
- "#access">?config</a> section for the page, or by adding a tag
- like this to your page:</p>
- <p><tt><?setshowinfo(0)></tt></p>
- <hr />
- <h2><a name="relative" id="relative">Relative vs. Absolute URL's
- - or, Why do my Images Break?</a></h2>
- <p>A problem common to all CGI wrappers is that the HTTPD program
- changes the current directory to the directory where whatever it
- is loading is stored. In the case of a CGI program, the current
- directory is set to the directory where the CGI program resides.
- This is normally not a problem, except when it comes to relative
- URL's.</p>
- <p>A relative URL is a URL which relies upon the current
- directory being the same as the directory where the current HTML
- file is located. So, for example, if I had the URL:</p>
- <pre>
- http://my.machine/~rasmus/file.html
- </pre>
- <p>the actual HTML file might be:</p>
- <pre>
- ~rasmus/public_html/file.html
- </pre>
- <p>If within the <tt>file.html</tt> file I had the tag:</p>
- <pre>
- <IMG SRC="pic.gif">
- </pre>
- <p>when loaded normally this file gif file is expected to be in
- <tt>~rasmus/public_html/pic.gif</tt>. However, when loaded
- through a CGI wrapper with a URL like:</p>
- <pre>
- http://my.machine/cgi-bin/php.cgi/~rasmus/file.html
- </pre>
- <p>then HTTPD sets the current directory to <tt>/cgi-bin</tt> (or
- wherever the ScriptAlias might point) and subsequently when the
- page is loaded the <tt>pic.gif</tt> file is expected to be in:
- <tt>/cgi-bin/pic.gif</tt> which is usually not the desired
- effect.</p>
- <p>The quick way around this problem is to use absolute URL's. In
- the above example if the image tag had been:</p>
- <pre>
- <IMG SRC="/~rasmus/pic.gif">
- </pre>
- <p>then there would have been no problem. Using absolute URL's is
- not always desirable as it makes pages less portable. An obvious
- question you may have at this point is, "Why doesn't PHP just
- change the current directory to the right place?". The answer is
- that PHP actually does change the current directory to the
- location of the HTML file it is displaying. Any file paths used
- inside PHP Script tags, can be relative. The problem is that tags
- outside of PHP's control such as <img > and <a href >
- will not be passed through PHP. When they are parsed, PHP is no
- longer active and the current working directory has been set back
- to the directory specified by the HTTP Daemon.</p>
- <p><strong>The Solution</strong> is a compromise. PHP provides a
- variable called <strong>PATH_DIR</strong>. It contains the
- directory portion of the current HTML file at all times. If this
- PATH_DIR variable is used in the <img > and <a href >
- tags then th…
Large files files are truncated, but you can click here to view the full file