Using PHP with the Sun Java System Web Server™ 6.1

April 13, 2006. v0.4
DRAFT
DzM - dzm@dzm.com

Contents

  1. Introduction
    1. What is PHP?
      1. Notes on modules
    2. What is the Sun Java System Web Server
      1. Notes on Sun Java System Web Server architecture
      2. Notes on configuration files
        1. magnus.conf
        2. obj.conf
        3. mime.types
    3. Why use PHP and the Sun Java System Web Server?
  2. Ways of running the PHP engine
    1. Common Gateway Interface (CGI)
    2. FastCGI
    3. Native API
  3. Installing the PHP engine as a CGI
    1. Why use CGI?
      1. Pros
      2. Cons
    2. Compiling the PHP engine as CGI
    3. Configuring the Sun Java System Web Server to use CGI
      1. magnus.conf
      2. obj.conf
      3. mime.types
      4. server.xml
    4. Notes
  4. Installing the PHP engine as a FastCGI
    1. Why use FastCGI?
      1. Pros
      2. Cons
    2. Compiling the PHP engine as FastCGI
    3. Configuring the Sun Java System Web Server to use FastCGI
      1. magnus.conf
      2. obj.conf
      3. mime.types
    4. Notes
  5. Installing the PHP engine using the NSAPI interface
    1. Why use NSAPI?
      1. Pros
      2. Cons
    2. Compiling the PHP engine as FastCGI
    3. Configuring the Sun Java System Web Server to use PHP as NSAPI
      1. magnus.conf
      2. obj.conf
      3. mime.types
    4. Notes

Introduction

This document describes in basic detail how to install and use the popular scripting language PHP with the Sun Java System Web Server.

What is PHP?

PHP is a widely used scripting language uniquely suited to creating dynamic Web based content. It is the most rapidly expanding scripting language in use on the Internet due to its simplicity, accessibility, wide number of available modules, and large number of easily available applications.

More information about the PHP engine and language can be had on the PHP web site [php.net].

Notes on modules

The PHP developer community creates modules for the PHP core that extend the capabilities of the PHP language. These modules provide an assortment of features, and are written by many contributors around the world. This distributed development method allows new technologies to be quickly implemented and made available, but can sometimes introduce unstable application code into the PHP engine. Third-party modules should be used with caution. Where possible code reviews should take place to check for security problems (back doors, buffer overflows, code insertion points, cross-site scripting vulnerabilities, thread safety, etc).

What is the Sun Java System Web Server?

The Sun Java System Web Server is a highly scalable and secure web server used heavily within the Fortune 1000 community. It has also been known as the Sun ONE Web Server, the iPlanet Web Server, and the Netscape Enterprise Server.

The Sun Java System Web Server utilizes a mature and highly scalable multi-process and multi-threaded application architecture to provide server redundancy, request scalability, and a wide range of application programming interfaces (APIs) to create dynamic content.

Notes on the Sun Java System Web Server architecture

By utilizing watchdog processes the server is able to watch for abnormal listener child death and, if detected, start new processes with little or no downtime.

By utilizing multiple listener processes the server achieves load redundancy that allows for graceful fail over in the event of listener death, as well as allowing the server to take better advantage of multiple CPU configuration (e.g. an administrator can choose to bind specific processes to a specific CPUs).

Finally, multiple thread pools are utilized within the server's listener processes to maximize number of simultaneous requests handled while minimizing resource overhead with unneeded "worker" threads.

This multi-process, multi-threaded architecture allows for a massively scalable and stable web server environment.

Modules that add capabilities to the server can be run via standard APIs such as CGI, SHTML, Java etc. They can also take advantage of the server's native API, Netscape Server API (NSAPI). Modules that utilize NSAPI must be thread safe, and should be multi-process aware as well.

Notes on configuration files

magnus.conf The magnus.conf file contains information that controls the server core. Information that is entered into this file controls which shared objects (plugins or modules) get loaded, number of processes the server will use, number of threads used in each process, etc. This file will be used to initialize the PHP engine or the FastCGI engine.

obj.conf The obj.conf controls the flow of request processing. It is executed from top to bottom, invoking the various request processing stages as described in the NSAPI Programmer's Guide. It is in the obj.conf that the server is instructed how to handle PHP documents, where they're located, etc.

mime.types The mime.types file is used to map specific file extensions to certain MIME types. The server then takes action based upon what those MIME types are (e.g. sets the Content-type: header, or executes certain functions upon them).

More information about all three of these files (as well as the others used in the configuration of the server) can be found in the NSAPI Programmer's Guide (the entire documentation set is here [sun.com]).

More information about the Sun Java System Web Server can be found on the Sun Microsystems product page [sun.com].

Why use PHP with Sun Java System Web Server?

The scalability of the Sun Java System Web Server combined with the versatility of the PHP engine provides a highly performant and versatile web deployment platform for dynamic content. This combination provides the stability required by the most demanding web sites and the versatility that an increasing number of web developers demand.

PHP can be used with the Sun Java System Web Server via NSAPI, CGI, or FastCGI. See below for more information.

Ways of running the PHP engine

The PHP engine is designed to be run in a variety of ways. Each has strengths and weaknesses.

Common Gateway Interface (CGI)

The Common Gateway Interface, or CGI, is one of the oldest widely accepted forms of providing dynamic content via a web server. This interface allows the server to accept data, pass it to an external program for interpretation and response, and then forward the result back to the client.

Because the program is executed externally, this API is considered one of the most versatile APIs in common use. The model does not require that the server nor the CGI be intimately aware of each other, and does not require the programmer to write an application to a specific native API. Unfortunately by running out of process CGIs are not as performant as their native API counterparts. For each request processed the CGI program is launched, run, and terminated. In high-load environments this can produce a significant load on the server OS and hardware, and can negatively impact the overall performance of the web site.

While very widely used, this venerable API is losing favor in high load environments to APIs that are more performant.

More information on CGI can be found on the NSCA CGI site [uiuc.edu].

NOTE: When running PHP out-of-process some functions will not work correctly. Watch the PHP pages for use of functions that require direct communication with the HTTP engine. The PHP function virtual is known to not work correctly.

FastCGI

FastCGI is an extension to CGI that mitigates many of its technology limitations. The application process continues to run externally to the web server, but reduces the overhead involved in CGI by not starting/terminating the application with each request.

Applications must be written to take into account the FastCGI environment before they can be used within the framework.

More information on FastCGI can be found on the FastCGI web site [fastcgi.com].

NOTE: When running PHP out-of-process some functions will not work correctly. Watch the PHP pages for use of functions that require direct communication with the HTTP engine. The PHP function virtual is known to not work correctly.

Native API

All commonly used web servers have a native API to allow extending their capabilities. These APIs allow developers to create modules that run directly in the web server instead of as an external application. Typically these environments offer better performance than CGI or FastCGI, but pose a greater risk to the stability of the web server itself (an application running as a module that crashes can take down the web server; if that application runs as a CGI and crashes it will have no impact on the web server).

The PHP engine supports the use of all three methods listed above via various command-line switches used during compilation. These are discussed later in this document. More information on these switches can be found on the PHP documentation page [php.net].

Installing the PHP engine as a CGI

Why use CGI?

The CGI interface affords a great deal of versatility in how one installs and manages the PHP engine. Unfortunately CGI imposes performance and state penalties.

Pros

  • Unique PHP engines
    The PHP engine can be compiled with unique options for each directory, or for each virtual server
  • Concurrency safety
    The PHP engine and modules need not be thread safe or aware, as the process is run fresh for each request
  • Platform portability
    The nature of CGI provides a great deal of portability from server to server (as well as operating system to operating system)
  • Security
    CGI scripts can be run in chroot and suid jails that limit their access to the rest of the web server environment

Cons

  • Large performance penalty
    CGI is considered an expensive mechanism due to its need to launch a new process for each request. This approach requires a great deal of system resources to launch, process, and terminate a request. For languages that are parsed (e.g. PHP, Perl, Shell, etc) this is an extremely resource expensive operation
  • Caching is not viable
    Because the application is launched and destroyed for each request, it is not possible to maintain content caches, connection pools, and other resource pools that can be expensive to allocate
  • PHP engine unable to directly communicate with HTTP engine
    PHP functions (such as virtual) that require direct communication with the HTTP engine will not work.

Compiling the PHP engine as a CGI

The default build configuration for the PHP 4.3.x engine is to be built as a CGI. To build the PHP engine as a CGI an administrator need only run the normal configure options without modification.

Example:
./configure

The administrator will then need to copy the binary produced ("php") to an area that the web server will have access to. This is often the directory that is mapped to the URI "/cgi-bin".

Configuring the Sun Java System Web Server to use CGI

The Sun Java System Web Server can be configured to use CGI via the Administrative Interface as described in the Administrator's Guide [sun.com], or by directly modifying the configuration files as described below.

magnus.conf

The magnus.conf file is not modified to enable CGI in Sun Java System Web Server v6.1.

obj.conf

The obj.conf can be used to configure CGI programs to be be executed only for certain directories, or for certain file types, or for both.

These lines will be added to the obj.conf (bold lines are added):

<Object name="default">
# Consider anything in the directory "/export/my/cgi/" to be a CGI
NameTrans fn="pfx2dir" from="/cgi-bin" dir="/export/my/cgi" name="cgi"

...
# Consider anything with a MIME type of "magnus-internal/cgi" to be a CGI
# Set in mime.types
# Run CGI processes with a "Nice" level of 10
Service fn="send-cgi" type="magnus-internal/cgi" nice="10"
...
</Object>

# Process CGI types assigned in NameTrans statements
<Object name="cgi">

ObjectType fn="force-type" type="magnus-internal/cgi"
# Run CGI processes with a "Nice" level of 10
Service fn="send-cgi" nice="10"
</Object>


These bold bold lines will assign the URI "/cgi-bin" to "/export/my/cgi", execute anything in the directory. Additionally any file that has a MIME type "magnus-internal/cgi" (set in the mime.types file - see below) will be executed.

mime.types

The mime.types file will be used to assign certain file extensions to the type "magnus-internal/cgi," the type used by the server to determine if a file should be served or executed as a CGI.

type=magnus-internal/parsed-html    exts=shtml
type=magnus-internal/cgi            exts=cgi,exe,bat,php

type=application/x-x509-ca-cert     exts=cacert


The addition of ",php" to the "magnus-internal/cgi" line instructs the server to consider the file extension "php" an executable type. This causes the server to execute the file rather than server the file when combined with the "Service fn="send-cgi"" line from the obj.conf (see above).

server.xml (Optional)

The server.xml file is not required to be modified to enable CGI capabilities, but it can be used to further enhance the security of the CGIs that are used by a particular server.

As described in the Administrator's Guide and the NSAPI Programmer's Guide, an administrator can set the following values for CGI: user, group, chroot, dir, and nice. When used effectively these variables allow an administrator to minimize the security risk of CGIs, and to control the overall impact large CGI can have on the rest of the server environment.

Note: If a CGI method is used to execute PHP content, one of two methods will need to be used to invoke the parser:
  1. Each file must begin with a "SplatBang" line that indicates the location of the PHP engine:
    #!/usr/bin/php
    or;
  2. Access the file via the URI (see the security considerations mentioned below):
    /cgi-bin/php/path/to/my/file
More information on compiling and using the PHP engine as a CGI process can be found on the PHP web site [php.net]. Security considerations of using PHP as a CGI are discussed here [php.net].

Installing the PHP engine as FastCGI

Why use FastCGI?

The FastCGI interface provides much of the scalability of Native APIs with much of the versatility of the CGI interface.

Pros

  • Unique PHP engines
    The PHP engine can be compiled with unique options for each directory, or for each virtual server
  • Concurrency safety
    The PHP engine and modules need not be thread safe or aware, as the processes are not necessarily long running
  • Better performance
    Since FastCGI servers launch once, then run for a predetermined period of time, the model is considerably more performant than the CGI model. The FastCGI model allows for results caching, connection pooling/reuse, etc. In some CGI to FastCGI comparisons a 4x to 8x improvement in speed has been observed.
  • Platform portability
    The nature of FastCGI provides a great deal of portability from server to server (as well as operating system to operating system), requiring only that the server running the FastCGI application understand how to interact with the FastCGI processes

Cons

  • Some performance penalty
    FastCGI achieves performance improvements by allowing a process to not terminate after servicing a request. Regardless, the process still runs outside of the server memory, and a performance penalty is often inevitable.
  • Unable to interact directly with web server
    An advantage to using a server's native API is the ability to influence (or expand) the capabilities of many areas of the server. By running out of process the FastCGI application is unable to be used for tasks that would influence other parts of request processing (i.e. to extend the authentication capabilities of a server)
  • PHP engine unable to directly communicate with HTTP engine
    PHP functions (such as virtual) that require direct communication with the HTTP engine will not work.

Compiling the PHP engine as a FastCGI

Beginning with PHP v4.3.0 FastCGI became a supported configuration. The configure switch --enable-fastcgi is used to compile the PHP 4.3.x engine with support for FastCGI. To use it, simply use the switch as part of the build process.

Example:
./configure --enable-fastcgi

The administrator will then need to copy the binary ("php") to a directory that the web server will have access to.

Configuring the Sun Java System Web Server to use FastCGI

The Sun Java System Web Server can be configured to use FastCGI, but requires the freely available FastCGI add-on available from Sun here [sun.com] (the compleat FastCGI add-on documentation is available here [sun.com]).

The FastCGI module can be configured to allow use with languages such as Perl, Python, etc but that is outside the scope of this document.

magnus.conf

The magnus.conf file needs to be modified to initialize the FastCGI module:
Init fn=load-modules
shlib="/path/to/libfastcgi.so"
These lines instruct the Sun Java System Web Server to load the shared object "libfastcgi.so" from the directory "/path/to/" (this path should be adjusted to reflect the location the administrator has installed the library to).

These two lines should be added to the section of the magnus.conf that contains the various "Init" lines.

obj.conf

The obj.conf can be used to configure FastCGI programs to be be executed only for certain directories, or for certain file types, or for both (lines in bold are new or modified).

<Object name="Default">
# Make everything in "/path/to/php" be executed as PHP using # the directives in the Object named "fastcgi" (defined below) NameTrans fn="pfx2dir" from="/php" dir="/path/to/php" name="fastcgi" ...
# Execute all things with a MIME type of # "magnus-internal/fastcgi" with options (this requires that mime.types # by updated to assign this type for specified extensions - see below): # bind-path: localhost:8082 # app-path: /export/my/cgi/php # min-procs: 1 # PHP_FCGI_CHILDREN: 1 # PHP_FCGI_MAX_REQUEST: 200 # This can be a single line, or a line continued using # the syntax below Service type="magnus-internal/fastcgi" fn="responder-fastcgi" bind-path="localhost:8082" app-path="/export/my/cgi/php" min-procs="1" app-env="PHP_FCGI_CHILDREN=1" app-env="PHP_FCGI_MAX_REQUEST=200" ... </Object> # Object to handle assigned names from the Default object <Object name="fastcgi"> # Anything that end up here has its type forced to # "magnus-internal/fastcgi" ObjectType fn="force-type" type="magnus-internal/fastcgi" # Run the request through the FastCGI handler with # the following options: # bind-path: localhost:8082 # app-path: /export/my/cgi/php # min-procs: 1 # PHP_FCGI_CHILDREN: 1 # PHP_FCGI_MAX_REQUEST: 200 # This can be a single line, or a line continued using # the syntax below Service type="magnus-internal/fastcgi" fn="responder-fastcgi" bind-path="localhost:8082" app-path="/export/my/cgi/php" min-procs="1" app-env="PHP_FCGI_CHILDREN=1" app-env="PHP_FCGI_MAX_REQUEST=200" </Object>

This configuration will consider anything to be FastCGI that comes from the directory "/path/to/php." Additionally, files with a MIME type of magnus-internal/fastcgi will be considered FastCGI. See the mime.types below to determine how to assign extensions this MIME type.

mime.types

The mime.types file is used to assign certain file extensions to the type "magnus-internal/fastcgi," the type used by the server to determine if a file should be served or executed as a CGI.

type=magnus-internal/fastcgi exts=php,php3,php4

The addition of this line instructs the server to consider the file extension "php" a type owned by the FastCGI module. This causes the server to run the request through the FastCGI module rather than server the file (see above).

Note: The server should be able to start and terminate the FastCGI application specified by AppPath. If the server is unable to do so, it will create an error log entry.

More information on compiling and using the PHP engine as a FastCGI process can be found on the PHP web site [php.net].

Installing the PHP engine as NSAPI

Why use NSAPI?

The NSAPI interface is the native API for the Sun Java System Web Server and provides a highly scalable environment for third party applications to run. The PHP engine is run as part of the server process, has direct access to the memory where requests are stored, and can manipulate them as is appropriate.

Pros

  • Very scalable
    Multi-threaded, multi-process environment is very scalable (see Section 1 above)
  • Memory sharing
    Multiple threads can share memory, allowing for the use of content caches, connection pools, etc

Cons

  • Stability
    NSAPI applications need to be thread safe. Application code that is not thread safe can crash the server due to memory corruption, etc.
  • File Descriptor limits
    Per process file descriptor limits can affect the server when modules require a large number of file descriptors. Additionally, some functions are known to have an arbitrarily low file descriptor limit on some operating systems. Low file descriptor limits can negatively impact the perceived performance and stability of a web site.

Compiling the PHP engine as a NSAPI

It is recommended that you use PHP v4.3.2 or newer for NSAPI environments. You should use gcc v2.95 or newer to compile the NSAPI shared object.

The configure switch --with-nsapi is used to compile the PHP 4.3.x engine with support for NSAPI. To use it, simply use the switch as part of the build process.

Example:
./configure --with-nsapi=/path/to/install/dir/

"/path/to/install/dir/" is the path to your Sun Java System Web Server installation directory (in this directory you will see subdirectories like https-admserv, plugins, alias, etc)

Compiling the PHP engine with this option will result in a shared object ("libphp4.so" or "libphp4.dll"). This shared object should then be copied into a location that the web server will have access to.

Configuring the Sun Java System Web Server to use PHP NSAPI

The magnus.conf, obj.conf, and mime.types files need to be modified to make the NSAPI work correctly.

magnus.conf

The magnus.conf file needs to be modified to initialize the PHP module:
# Initialize PHP v4.3.2
Init fn="load-modules"
shlib="/path/to/install/dir/third-party/libphp4.so"
funcs="php4_init,php4_close,php4_execute,php4_auth_trans"
Init fn="php4_init"
errorString="PHP Totally Blowed Up!"
These two lines instruct the Sun Java System Web Server to load the shared object "libphp4.so" from the directory "/path/to/install/dir/third-party/" (this path should be adjusted to reflect the location the administrator has installed the library to).

These two lines should be added to the section of the magnus.conf that contains the various "Init" lines.

obj.conf

The obj.conf can be used to configure CGI programs to be be executed only for certain directories, or for certain file types, or for both (lines in bold are new or modified).

<Object name="Default">
# Create a PHP directory
NameTrans fn="pfx2dir" from="/php" dir="/path/to/php" name="php"
...
PathCheck fn="find-index" index-names="index.html,index.php"
...
Service method=(GET|HEAD) type="*~magnus-internal/*" fn="send-file"
# Generically execute files with the correct PHP MIME type
# This Service needs to come after the "send-file" service
Service fn="php4_execute" type="magnus-internal/x-httpd-php" bucket="php-bucket"
...
</Object>

# Anything that ends up in here will be treated as PHP
# See pfx2dir NameTrans above
<Object name="php">
# Set the MIME type
ObjectType fn="force-type" type="magnus-internal/x-httpd-php"
# Run the function
Service fn=php4_execute
</Object>

This configuration will consider anything to be PHP that comes from the directory "/path/to/php." Additionally, files with a MIME type of magnus-internal/x-httpd-php will be considered PHP. See the mime.types below to determine how to assign extensions this MIME type. Finally, it will recognize documents named "index.php" as index documents for directories and treat them accordingly.

mime.types

The mime.types file is used to assign certain file extensions to the type "magnus-internal/x-httpd-php" the type used by the server to determine if a file should be served or executed as PHP.

type=magnus-internal/x-httpd-php        exts=php,php3,php4

The addition of this line instructs the server to consider the file extensions "php," "php3," and "php4" a type owned by the PHP module. This causes the server to run the request through the NSAPI module rather than server the file (see above).

Note: In some situations PHP can not be thread safe. You should thoroughly test any new PHP module before you compile it into your production environment. Thread safety issues can lead to memory corruption and server outages. Additionally, the PHP core is known to use the select() function which, on Solaris, has a 256 File Descriptor limit (this limit is low for high volume sites). Setting the MaxProcs directive to greater than 1 in the magnus.conf can alleviate the risk posed by this configuration.

More information on compiling and using the PHP engine as a NSAPI module can be found on the PHP web site [php.net].