I'm trying to install a pre-Iraq-Surge 4.4.9 PHP in a modern Apache 2.4.6 and want to run it in CGI mode.
The current configuration is as follows:
The PHP executable is /usr/local/php-4.4.9/bin/php
A test file exists in $documentroot/phphere/index.php
of the virtual server, it contains:
<?php
phpinfo();
?>
If I execute the index.php
using php
, all is hunky dory.
Running
/usr/local/php-4.4.9/bin/php $documentroot/phphere/index.php | less
yields
X-Powered-By: PHP/4.4.9
Content-type: text/html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html><head>
<style type="text/css">
body {background-color: #ffffff; color: #000000;}
body, td, th, h1, h2 {font-family: sans-serif;}
pre {margin: 0px; font-family: monospace;}
a:link {color: #000099; text-decoration: none; background-color: #
etc.
Excellent!
However, calling index.php
via a web client results in this:
Warning: Unexpected character in input: '' (ASCII=1) state=1 in /usr/local/php-4.4.9/bin/php on line 277
Warning: Unexpected character in input: '' (ASCII=15) state=1 in /usr/local/php-4.4.9/bin/php on line 277
Parse error: syntax error, unexpected T_STRING in /usr/local/php-4.4.9/bin/php on line 277
which is exactly the output that one gets if one processes the php executable with itself, i.e. the output of
/usr/local/php-4.4.9/bin/php /usr/local/php-4.4.9/bin/php
(less any headers additionally generated).
Ok, so there is some problem in the Apache setup. But what?
The following is configured:
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
ScriptAlias /outsidephp /usr/local/php-4.4.9/bin
Action application/x-httpd-php /outsidephp/php
If I understand correctly, AddType tags any file ending in .php
with MIME type application/x-httpd-php
.
If PHP shall be run via CGI conventions, then the executable to run whenever a file with the MIME type application/x-httpd-php
is requested is indicated with Action. The ScriptAlias gives an URL-path to the directory in which the php
executable can be found. (This syntax sounds awkward though, why not have a single command for that?)
Additionally, the option ExecCGI
has been set in the directory containing index.php
and the SELinux contexts on that filesystem tree are marked with httpd_sys_script_exec_t
.
Note that there is absolutely no
AddHandler cgi-script .php
in the configuration because THAT make Apache try to execute files ending in .php
directly as scripts, which predictably fails with Error 500:
Error message:
End of script output before headers: index.php
What's wrong exactly?
How do I make Apache run
php index.php
instead of
php php
(i.e. quite probably php php index.php
)
This is completely crazy but I have found the following solution:
Create a script
redirect.pl
(which can also be a small binary of course) to "wrap" thephp
executable (note that there is nophp-cgi
in PHP 4.4.9).The script is invoked from Apache httpd by:
The full pathname to the script is
/usr/local/php-4.4.9/bin/redirect.pl
; it just does this:Why the above? The environment variables that Apache Httpd sets for the CGI executable if
index.php
is requested are:Empirically this makes
php
just execute itself i.e.php
assumes thatSCRIPT_FILENAME
contains the filename of PHP script, with some justification.Therefore, we need the script above to set the value of
SCRIPT_FILENAME
to the value ofPATH_TRANSLATED
.Now the question is, why does Apache Httpd set the value of
SCRIPT_FILENAME
the way it does?The Apache documentation for handlers says the originally requested document is pointed to by the PATH_TRANSLATED environment variable. It doesn't mention SCRIPT_FILENAME.
The CGI RFC 3875 also doesn't mention SCRIPT_FILENAME. One the other hand, your examples show that the php-cgi you are using expects the name of the PHP file in SCRIPT_FILENAME. This seems to be relying on undefined behavior.
Note that PHP 4.4.9 is quite old, while the Apache server you are using is probably newer. So it is possible that the Apache from that time passed the name of the script file (also) in SCRIPT_FILENAME, and the behavior has changed since then.
You don't need perl to assign the environment variable, a simple scell script will also do, but use what you are comfortable with.