| By Joe McCabe, January 12, 2007 |
PHP (PHP: Hypertext Preprocessor) is a widely used scripting language suited to creating dynamic web-based content. It is popular due to its simplicity, accessibility, wide number of available modules, and large number of freely available applications.
Sun Java System Web Server is a mature, highly scalable, and secure web server that provides process redundancy, request scalability, and a wide range of application programming interfaces (APIs) to create and serve dynamic content.
This document describes how to install and use PHP with Sun Java System Web Server (hereafter Web Server). The document applies to all versions of Web Server through version 7.
This section contains useful background not covered elsewhere in this document.
The PHP developer community creates modules for the PHP core that extend the capabilities of the PHP language. These modules, which provide an assortment of features, 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 code into the PHP engine. Therefore, use third-party modules with caution. When possible, conduct code reviews to check for security problems, such as back doors, buffer overflows, code insertion points, cross-site scripting vulnerabilities, and thread safety.
For more information about the PHP engine and language, see the PHP web site.
Web Server's multiprocess, multithreaded architecture sustains a massively scalable and stable web hosting environment.
For more information about Web Server, visit the Sun Microsystems product page.
In this article, we refer to three Web Server configuration files. Here's a brief introduction to them.
magnus.conf: obj.conf: Controls the flow of request processing. The file is executed from top to bottom, invoking the various request processing stages as described in the NSAPI Programmer's Guide ( 6.1, 7.0). It is in the obj.conf file that the server is instructed how to process PHP documents, where they're located, and so forth.mime.types: Maps specific file extensions to certain MIME types. The server then takes action based on what that MIME type is, for example, sets the Content-type: header or executes certain Server Application Functions (SAFs).For more information about all three of these files (as well as the others used in the configuration of Web Server), see the NSAPI Programmer's Guide in the NSAPI documentation set ( 6.1, 7.0).
More information about Web Server can be found on the Sun Microsystems product page.
The PHP engine can run with Web Server as a Common Gateway Interface (CGI) program, as a FastCGI server, or as a plugin using Web Server's native API, NSAPI, all briefly described below. Each method has strengths and weaknesses, as tabulated in each method's Installation section.
The PHP engine supports the methods outlined in this section by means of various command-line switches used during compilation. These switches are discussed throughout the article. For more information on them, see the PHP documentation page.
If your PHP applications use database drivers (such as SQL or MySQL) or other common modules, then the database drivers must be compiled into the PHP binary following the instructions on the PHP web site, or the appropriate environment variables must be passed to the PHP binary via environment variables or the php.ini file. Discussion of the syntax and use of the php.ini file is outside the scope of this document.
Note: All of the methods discussed in this document require that the PHP engine be compiled with a C language compiler. This document discusses the process in the context of UNIX and Linux operating systems, but does not attempt to describe the process for Microsoft Windows operating systems. Precompiled binaries for Microsoft Windows systems using various common APIs are available from the PHP web site. The configuration information in this document applies to all operating systems, though path naming conventions for each operating system are not explicitly addressed.
The Common Gateway Interface, or CGI, is one of the oldest widely accepted forms of providing dynamic content through 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 to the user-agent.
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 and the CGI be intimately aware of each other, nor does it require that programmers write an application to a specific native API. Unfortunately, because CGI programs run out-of-process, they don't perform as well as their native API counterparts. For each request processed, the CGI program is launched, run, and terminated. In high-load environments, this behavior can significantly load the server OS and hardware and can negatively impact the overall performance of the web site.
While very widely used, this API is losing favor in high-load environments to APIs that perform better.
Note: When PHP is run out-of-process, some functions do not work correctly. Examine the PHP applications for the use of functions that require direct communication with the HTTP engine. For example, the PHP function virtual is known not to work correctly.
For more information on CGI, see the NCSA CGI site.
FastCGI is an extension to CGI (see above) that mitigates many of its performance limitations. The FastCGI server process runs externally to Web Server but reduces the overhead of CGI by not starting and terminating the FastCGI server process with each request.
Due to the improved performance of FastCGI over CGI and the protection of Web Server from potentially non-thread-safe modules that have been compiled into the PHP engine, FastCGI is typically the recommended method of running PHP applications with Web Server.
Note: When PHP is run out-of-process, some functions do not work correctly. Examine the PHP applications for use of functions that require direct communication with the HTTP engine. For example, the PHP function virtual is known not to work correctly.
For more information on FastCGI, see the FastCGI web site.
Web Server offers a native API named NSAPI to extend its capabilities. With NSAPI, developers can create plugins that run directly in Web Server instead of as an external application. Typically, NSAPI offers better performance than CGI or FastCGI, but poorly implemented NSAPI plugins pose a risk to the stability of Web Server itself. For example, a buffer overflow in an application running as an NSAPI plugin can crash Web Server by corrupting the process heap, whereas a crash of that application running as a CGI process or a FastCGI server has no impact on the stability of Web Server.
The CGI interface affords a great deal of versatility in how you install and manage the PHP engine. Unfortunately, CGI imposes performance and state penalties. Table 1 presents some pros and cons of the PHP engine as a CGI.
Pros | Cons | |
|---|---|---|
Unique PHP engines. You can compile the PHP engine with unique options for each directory or for each virtual server. | Large performance penalty. CGI is expensive because a new process must be executed for each request. This can require expensive CPU and memory resources to launch, process, and terminate a request. For languages that are parsed (for example, PHP, Perl, Shell), where a virtual machine has to be created and the script itself parsed and compiled before the final execution, this is a resource-expensive and time-expensive operation. | |
Concurrency safety. The PHP engine and modules need not be thread safe or thread aware because the execution environment is re-created for each request. | Caching not viable. Because the application is launched and destroyed for each request, maintenance of content caches, connection pools, and other resource pools that can be expensive to allocate is not possible. | |
Platform portability. The nature of CGI provides a great deal of portability from server to server, as well as from operating system to operating system. | Inability of PHP engine to directly communicate with HTTP engine. PHP functions (such as virtual) that require direct communication with the HTTP engine do not work. | |
Security. CGI scripts can be run in chroot and suid jails that limit their access to the rest of the Web Server environment. |
The default build configuration for the PHP 4.3. x and PHP 5. x engines 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, for example:
./configure ... gmake |
The administrator must then copy the binary produced (located at build-dir /sapi/cgi/php) to an area that Web Server can access. This is often the directory that is mapped to the URI /cgi-bin.
You can configure Web Server to use CGI through the Administrative interface as described in the Administrator's Guide ( 6.1, 7.0) or by directly modifying the configuration files as described below.
magnus.conf for CGI
The magnus.conf file is not modified when enabling CGI in Web Server 6.1 or Web Server 7.0.
obj.conf for CGI
The obj.conf file configures CGI programs to be executed for certain directories only, for certain file types only, or for both. The modifications for CGI functionality are the same in Web Server 6.1 and Web Server 7.0.
Add the lines shown in bold to the obj.conf file.
<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>
|
The lines assign the URI /cgi-bin to the directory /export/my/cgi, and instruct Web Server to execute anything in the directory. Additionally, any file that has a MIME type magnus-internal/cgi (set in the mime.types fileĀsee below) is executed.
mime.types for CGI
The mime.types file assigns certain file extensions to the type used by the server to determine if a file should be served as content 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 to be an executable type. This causes the server to execute the file rather than to serve the file when combined with the Service fn="send-cgi" line from the obj.conf file (see above).
server.xml for CGI (Optional)
Although the server.xml file need not be modified in order to enable CGI capabilities, it can be used to enhance the security of the CGIs.
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. By effectively using these variables, an administrator minimizes the security risk of CGIs and controls the overall impact large CGIs can have on the rest of the server environment.
If the CGI method is used to execute PHP content, use one of two methods to invoke the PHP engine:
#!/usr/bin/php
|
/cgi-bin/php/
path-to-my-file
|
Note: Microsoft Windows users need to make certain the that file extensions of their PHP applications (typically php, php4, php5, and so on) have an association with the PHP CGI binary.
For more information on compiling and using the PHP engine as a CGI process, see the PHP web site. Also be aware of security considerations for using PHP as a CGI.
The FastCGI interface provides much of the scalability of native APIs with much of the versatility of the CGI interface by keeping the executed binary running from request to request instead of terminating after a single request. Table 2 presents some pros and cons of the PHP engine as FastCGI.
Pros | Cons |
|---|---|
Unique PHP engines. You can compile the PHP engine with unique options for each directory or for each virtual server. | Some performance penalty. FastCGI achieves performance improvements by not terminating a process after servicing a request. Regardless, the process runs outside the server memory, and a performance penalty is inevitable due to the out-of-process communication required between Web Server and the PHP engine. |
Concurrency safety. The PHP engine and modules need not be thread safe or thread aware, because the PHP processes are not necessarily long running and stability issues within the PHP environment will not negatively impact Web Server's stability. | Inability to interact directly with a web server. If running out-of-process, the FastCGI application cannot be used for tasks that would need direct access to Web Server's internal data structures to influence other parts of request processing. Note: The auth-fastcgi Service Application Function could be used to have a FastCGI server process perform authentication, but that is separate from Web Server's built-in access control capabilities. |
Platform portability. The nature of FastCGI provides a great deal of portability from server to server and from operating system to operating system, requiring only that Web Server understand how to interact with the FastCGI server processes. | Inability of PHP engine to directly communicate with HTTP engine. PHP functions (such as virtual) that require direct communication with the HTTP engine do not work. |
Better performance. Because FastCGI servers launch once and then run for a predetermined period of time (or number of requests), the model performs considerably faster than the CGI model. The FastCGI model allows for results caching, connection pooling and reuse, and so on. In some CGI to FastCGI comparisons, a 4x to 8x improvement in speed has been observed. |
Beginning with PHP v4.3.0, FastCGI became a supported configuration for the PHP engine. To compile the PHP 4.3. x, 5. x or newer engine with support for FastCGI, simply include the configure switch --enable-fastcgi as part of the build process, for example:
./configure --enable-fastcgi ... gmake |
Production example with PHP 5.1.6:
./configure --enable-track-vars --enable-force-cgi-redirect \ --with-gettext --enable-fastcgi --with-zlib --with-gd --with-mysql |
A properly compiled FastCGI PHP engine can be easily tested by using the -version command-line switch to verify the version and interface:
$ pwd /tmp/php-5.1.6/sapi/cgi $ ./php -version PHP 5.1.6 (cgi-fcgi) (built: Oct 17 2006 17:41:24) Copyright (c) 1997-2006 The PHP Group Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies |
The administrator must then copy the binary (located at build-dir /sapi/cgi/php) to a directory that Web Server can access.
Configuring Web Server 6.1 to use FastCGI requires the free FastCGI add-on available from Sun (see the complete FastCGI add-on documentation). Web Server 7.0 includes the FastCGI add-on and does not require a separate download. The Web Server 6.1 FastCGI add-on is not compatible with Web Server 7.0. The php.ini file location can be specified within the obj.conf file (see example below). The syntax and use of the php.ini file is outside the scope of this document.
Note: You can configure the FastCGI plugin for use with languages such as Perl, Python, and so on, but that configuration is outside the scope of this document.
magnus.conf for FastCGI
Modify magnus.conf to initialize the FastCGI plugin.
Web Server 6.1: Add the following two lines to the section of magnus.conf that contains the various Init lines.
Init fn=load-modules
shlib="/path/to/libfastcgi.so"
|
Web Server 7.0: Add the following line to the magnus.conf file:
Init fn=load-modules shlib="libfastcgi.so" |
These lines instruct Web Server to load the shared object libfastcgi.so.
obj.conf for FastCGI
The obj.conf file configures FastCGI servers to be accessed (or executed) only for certain directories, certain file types, specified URI patterns, other elements of the HTTP request (such as User-Agent version and date), or any combination of these. The FastCGI syntax is the same for Web Server 6.1 and Web Server 7.0.
(Lines in bold are new or modified from a default obj.conf file.)
<Object name="Default">
# Make everything in URI "/php" come from"/path/to/php" and # 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 be 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 # LD_LIBRARY_PATH: /usr/local/php/lib # PHPRC: /path/to/php/config/dir # The LD_LIBRARY_PATH can be used to indicate the location # of the local system's MySQL libraries, etc. # Note that the PHPRC variable points to the directory # containing php.ini, not to php.ini itself. # 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" app-env="LD_LIBRARY_PATH=/usr/local/php/lib" app-env="PHPRC=/path/to/php/config/dir" ...
</Object>
# Object to handle assigned names from the Default object <Object name="fastcgi"> # Anything that ends 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 # LD_LIBRARY_PATH: /usr/local/php/lib # PHPRC: /path/to/php/config/dir # The LD_LIBRARY_PATH can be used to indicate the location # of the local system's MySQL libraries, etc. # Note that the PHPRC variable points to the directory # containing php.ini, not to the php.ini itself. # 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" app-env="LD_LIBRARY_PATH=/usr/local/php/lib" app-env="PHPRC=/path/to/php/config/dir" </Object>
|
This configuration considers anything that comes from the directory /path/to/php to be FastCGI. Additionally, files with a MIME type of magnus-internal/fastcgi are considered FastCGI. See the mime.types section below to determine how to assign extensions to this MIME type.
mime.types for FastCGI
mime.typesmagnus-internal/fastcgimime.types
type=magnus-internal/fastcgi exts=php,php3,php4,php5
|
The addition of this line instructs the server to consider the file extensions php, php3, php4 and php5 to be a type owned by the FastCGI plugin. This causes the server to run the request through the FastCGI plugin rather than to serve the matching file (see above).
Web Server should be able to start and terminate the FastCGI server specified by app-path. If the server is unable to do so, it creates an error log entry. For more information on compiling and using the PHP engine as a FastCGI process, see the PHP web site.
The NSAPI interface is the native API for Web Server and provides a highly scalable environment in which third-party applications can 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. Table 3 presents some pros and cons of the PHP engine as NSAPI.
Pros | Cons |
|---|---|
Highly scalable. Multithreaded, multiprocess environment is massively scalable (see Notes on Web Server Architecture). | Thread safety. NSAPI applications need to be thread safe. Application code that is not thread safe can crash Web Server. |
Memory sharing. Multiple threads can share memory, allowing for the use of content caches, connection pools, and so on. This internal communication and resource management can contribute to significant performance gains. | File descriptor limits. Per-process file descriptor limits can affect Web Server when a 32-bit NSAPI makes use of stdio() on modern versions of the Solaris Operating System. In this situation the process itself is limited to 256 total file descriptors. A low number of available file descriptors can negatively impact the perceived performance and stability of a web site. |
It's 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.
To compile PHP 4.3. x or newer with support for NSAPI, include the configure switch --with-nsapi as part of the build process, for example:
./configure --with-nsapi=/
path-to-install-dir
...
gmake
|
where path-to-install-dir is the path to your Web Server 6.1 or Web Server 7.0 installation directory (in this directory are subdirectories like https-admserv, plugins, alias, and so on).
Production example with PHP 5.1.6:
./configure --with-nsapi=/export/WS7/ --enable-track-vars --enable-force-cgi-redirect \ --with-gettext --with-zlib --with-gd --with-mysql |
The PHP 5.2 build process correctly finds the nsapi.h file for Web Server 7.0 and Web Server 6.1. Versions of PHP prior to 5.2 might not find Web Server 7.0's nsapi.h file, however, and might require the following workaround:
# pwd
/install/dir
# cd plugins/
# ln -s ../include include
# ls -ld include
lrwxrwxrwx 1 root root 10 Oct 18 15:22 include -> ../include
|
After the symlink is created PHP can be built normally.
Compiling PHP 4. x results in the shared object build-dir /sapi/nsapi/libphp4.so (or build-dir /sapi/nsapi/libphp4.dll on Microsoft Windows systems). Compiling PHP 5. x results in build-dir /libs/libphp5.so (or build-dir /libs/libphp5.dll on Microsoft Windows systems). An administrator should then copy this shared object into a location that Web Server can access.
To make the NSAPI plugin work correctly, modify the magnus.conf, obj.conf, and mime.types files. The php.ini file for an NSAPI installation is in the install-dir /https- name /config/ directory. Syntax and use of the php.ini file is outside the scope of this document.
magnus.conf for NSAPI
Modify the magnus.conf file to initialize the PHP plugin. Add the following lines to the section of the magnus.conf that contains the various Init lines. The NSAPI syntax is the same for Web Server 6.1 and Web Server 7.0.
# Initialize PHP 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 failed to initialize."
|
The shlib= and funcs= lines instruct Web Server to load the shared object libphp4.so from the directory path/to/install/dir/third-party/ (adjust the path to reflect the location at which the administrator has installed the library).
Note: For PHP 5. x change all the strings above from php4 to php5.
obj.conf for NSAPI
The obj.conf file configures Server Application Functions (SAFs) to be executed for certain directories only, for certain file types only, or for both (lines in bold are new or modified). Note that the syntax has not changed from Web Server 6.1 to Web Server 7.0. In switching from PHP 4. x to PHP 5. x, however, the SAF names have changed all php4 occurrences to php5.
<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"
... # Generically execute files with the correct PHP MIME type # This Service needs to come before the "send-file" service # "php4_execute" is "php5_execute" when using PHP 5. x. Service fn="php4_execute" type="magnus-internal/x-httpd-php"
Service method=(GET|HEAD) type="*~magnus-internal/*" fn="send-file"
...
</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 # "php4_execute" is "php5_execute" when using PHP 5. x. Service fn=php4_execute </Object>
|
This configuration considers anything that comes from the directory /path/to/php to be PHP. Additionally, files with a MIME type of magnus-internal/x-httpd-php are considered PHP. See the mime.types section below to determine how to assign extensions to this MIME type. Finally, this configuration recognizes documents named index.php as index documents for directories and treats them accordingly.
mime.types for NSAPI
The mime.types file assigns certain file extensions to the type magnus-internal/xhttpd-php, the type used by the server to determine if a file should be served or executed as PHP. The syntax of the mime.types file has not changed between Web Server 6.1 and Web Server 7.0.
type=magnus-internal/x-httpd-php exts=php,php3,php4,php5
|
This line instructs the server to consider the file extensions php, php3, php4 and php5 to be a type owned by the PHP plugin. This causes the server to run the request through the NSAPI plugin rather than to serve the file.
In some situations PHP can be non-thread-safe. You should thoroughly test any new PHP plugin before you compile it into your production environment. Thread-safety issues can lead to memory corruption and server outages.
The PHP core is known to use the select() function along with other stdio() functions that, in a 32-bit application running on the Solaris Operating System, have a file descriptor limit that cannot be increased (more information on this is available in this blog entry). Setting the MaxProcs directive to greater than 1 in the magnus.conf file can alleviate the risk posed by this configuration but can introduce other performance penalties.
For more information on compiling and using the PHP engine as an NSAPI plugin, see the PHP web site.
The scalability of Sun Java System Web Server combined with the versatility of the PHP engine affords a high-performance web deployment platform for dynamic content. The combination delivers the stability required by the most demanding web sites and the versatility that an increasing number of web developers demand.
