15.2. Writing Portable Code for Windows and UnixOne of the main reasons for running PHP on Windows is to develop locally before deploying in a production environment. As most production servers are Unix-based, it is important to consider porting[10] as part of the development process and plan accordingly.
Potential problem areas include applications that rely on external libraries, use native file I/O and security features, access system devices, fork or spawn threads, communicate via sockets, use signals, spawn external executables, or generate platform-specific graphical user interfaces. The good news is that cross-platform development has been a major goal in the development of PHP. For the most part, PHP scripts should be easily ported from Windows to Unix with few problems. However, there are several instances where you can run into trouble when porting your scripts. For instance, some functions that were implemented very early in the life of PHP had to be mimicked for use under Windows. Other functions may be specific to the web server under which PHP is running. 15.2.1. Determining the PlatformTo design with portability in mind, you may want to first test for the platform on which the script is running. PHP defines the constant PHP_OS, which contains the name of the operating system on which the PHP parser is executing. Possible values for the PHP_OS constant include "AIX", "Darwin" (MacOS), "Linux", "SunOS", "WIN32", and "WINNT". The following code shows how to test for a Windows platform prior to setting an include path: <?php if (PHP_OS == "WIN32" || PHP_OS == "WINNT") { define("INCLUDE_DIR","c:\\myapps"); } else { // some other platform define("INCLUDE_DIR", "/include"); } ?> 15.2.2. Handling Paths Across PlatformsPHP understands the use of either backward or forward slashes on Windows platforms, and can even handle paths that mix the use of the two slashes. As of Version 4.0.7, PHP will also recognize the forward slash when accessing Windows UNC paths (i.e., //machine_name/path/to/file). For example, these two lines are equivalent: $fh = fopen('c:/tom/schedule.txt', 'r'); $fh = fopen('c:\\tom\\schedule.txt', 'r'); 15.2.3. The EnvironmentPHP defines the constant array $HTTP_ENV_VARS, which contains the HTTP environment information. Additionally, PHP provides the getenv( ) function to obtain the same information. For example: <?php echo "Windows Directory is ".$HTTP_ENV_VARS["windir"]."\r\n"); echo "Windows Directory is ".getenv("windir")."\r\n"); ?> Windows Directory is C:\WINNT Windows Directory is C:\WINNT 15.2.4. Sending MailOn Unix systems, you can configure the mail( ) function to use sendmail or Qmail to send messages. You can also do this on Windows systems, as long as you define sendmail_path in php.ini and install sendmail for Windows. More convenient is to simply point the Windows version of PHP to an SMTP server: [mail function] SMTP = mail.example.com sendmail_from = gnat@frii.com 15.2.5. Server-Specific FunctionsIf compiled as a plug-in for Apache, PHP includes several functions that are specific to the Apache web server. If you use these functions, and are porting your scripts to run under IIS, you will need to reimplement that functionality. Following are the Apache-specific functions and some solutions for replacing them:
There is also a set of IIS-specific functions, though its purpose is primarily for management of IIS. 15.2.6. Remote FilesUnder Unix, PHP is able to retrieve remote files via HTTP or FTP for inclusion in your script via the require( ) and include( ) functions. These functions are not available under Windows. Instead, you must write your own subroutine to fetch the remote file, save it to a temporary local file, and then include that file, as shown in Example 15-1. Example 15-1. Including a remote file with PHP on Windows<?php function include_remote($filename) { $data = implode("\n", file($filename)); if ($data) { $tempfile = tempnam(getenv("TEMP"),"inc"); $fp = fopen( $tempfile,"w"); fwrite( $fp, "$data"); fclose( $fp ); include($tempfile); unlink($tempfile); } echo "<b>ERROR: Unable to include ".$filename."</b><br>\n"; return FALSE; } // sample usage include_remote("http://www.example.com/stuff.inc"); ?> 15.2.7. End-of-Line HandlingWindows text files have lines that end in "\r\n", whereas Unix text files have lines that end in "\n". PHP processes files in binary mode, so no automatic conversion from Windows line terminators to the Unix equivalent is performed. PHP on Windows sets the standard output, standard input, and standard error file handles to binary mode and thus does not do any translations for you. This is important for handling the binary input often associated with POST messages from web servers. Your program's output goes to standard output, and you will have to specifically place Windows line terminators in the output stream if you want them there. One way to handle this is to define an end-of-line constant and output functions that use it: <?php if (PHP_OS == "WIN32" || PHP_OS == "WINNT") { define("EOL","\r\n"); } else if (PHP_OS == "Linux") { define("EOL","\n"); } else { define("EOL","\n"); } function echo_ln($out) { echo $out.EOL; } echo_ln("this line will have the platforms EOL character"); ?> 15.2.8. End-of-File HandlingWindows text files end in a Control-Z ("\x1A"), whereas Unix stores file-length information separately from the file's data. PHP recognizes the EOF character of the platform on which it is running. The function feof( ) thus works when reading Windows text files. 15.2.9. External CommandsPHP uses the default command shell of Windows for process manipulation. Only rudimentary Unix shell redirections and pipes are available under Windows (e.g., separate redirection of standard output and standard error is not possible), and the quoting rules are entirely different. The Windows shell does not glob (i.e., replace wildcarded arguments with the list of files that match the wildcards). Whereas on Unix you can say system("someprog php*.inc"), on Windows you must build the list of filenames yourself using opendir( ) and readdir( ). 15.2.10. Common Platform-Specific ExtensionsThere are currently over 80 extensions for PHP, covering a wide range of services and functionality. Only about half of these are available for both Windows and Unix platforms. Only a handful of extensions, such as the COM, .NET, and IIS extensions, are specific to Windows. If an extension you use in your scripts is not currently available under Windows, you need to either port that extension or convert your scripts to use an extension that is available under Windows. If you use PHP as a web server plug-in (SAPI), the extensions must be thread-safe. Some extensions depend on third-party libraries that may not be thread-safe, rendering them incompatible with the SAPI plug-in. Unfortunately, the level of thread safety in PHP extensions is poorly documented, and it will require testing on your part to discover where you may run into difficulty. Fortunately, the more popular an extension is, the greater chance there is of that extension being available on Windows. In some cases, some functions are not available under Windows even though the module as a whole is. checkdnsrr( ), in the Networking module, is just one example of this problem. Windows PHP does not support signal handling, forking, or multithreaded scripts. A Unix PHP script that uses these features cannot be ported to Windows. Instead, you should rewrite the script to not take advantage of those features. Copyright © 2003 O'Reilly & Associates. All rights reserved. |
|