MapScript and PHP as a CGI

The Problem

Due to some thread-safety problems (and some heritage from PHP3 in the php_mapscript.c code), PHPMapScript versions 3.5 (and 3.6-dev at least) will produce intermittent errors and crashes when used under PHP configured as an Apache DSO or as an ISAPI module.

The workaround (until we rework the PHPMapScript code) is to configure your PHP as a CGI and then things will work just fine. You shouldn't worry too much about the overhead associated with loading the PHP CGI at each request since it is relatively small compared to the processing time involved with accessing megabytes of map data.

So how do I reconfigure my PHP as a CGI?

 > All the documentation only talks about building it as a DSO module for
 > apache. Can you send me a link or have someone add it to Wiki? I think
 > this would be a great help to aid others that might want to work with
 > PHP3 and Mapscript.

You should be able to find detailed information at

PHP's default 'configure' behavior is to build a 'php' CGI executable. It's the --with-apxs and/or --with-apache PHP configure options that enable PHP to be built as an Apache DSO.

So basically to build PHP as a CGI simply make sure that you don't provide the --with-apxs or --with-apache switch to the PHP configure. It is also good practice when building PHP as a CGI to include the --enable-force-cgi-redirect switch for security reasons.

Then once you have a 'php' executable, copy it to your server's cgi-bin directory and add to your httpd.conf:

  AddType  application/x-httpd-php .php3
  AddType  application/x-httpd-php .phtml
  AddType  application/x-httpd-php .php

  Action application/x-httpd-php /cgi-bin/php

The same works for PHP3 or PHP4 as a CGI.

Note: It may be necessary to use a script in the cgi-bin directory rather than the 'php' executable (e.g., as discovered the hard way by a !FreeBSD 5.1 user). See: for a valuable hint.

This URL explains the problem causing the need for the wrapper script: It seems this problem was fixed long ago, but it can be re-activated in sapi/cgi/cgi_main.c by certain combinations of compilation options. The configure option --enable-discard-path is implicated, as well as PHP_FASTCGI and ENABLE_PATHINFO_CHECK.

Note for FreeeBSD? users! You can avoid using the wrapper script noted in the link above IF you make www/php4-cgi as "make -DWITH_FASTCGI". There are three ways to install PHP from ports: lang/php4, which installs a DSO and a CLI, but not a CGI; www/mod_php4, which installs a DSO module; and www/php4-cgi, which installs a CGI version. Use the latter if you can, obviously. If you must have lang/php4 or mod_php4 as well, you can also compile the CGI version ("make -DWITH_FASTCGI build") and copy it into your CGI directory (it's in $SRC/sapi/cgi/).

If your server came preloaded with PHP as an Apache DSO

RedHat and other Linux/Unix? distributions that come with an installed version of Apache often have PHP preloaded as a DSO in their Apache configuration. If you're in that situation and don't feel like recompiling Apache then you can bypass the module by removing the original AddType lines and using another type for your PHP CGI AddType and Action directives, e.g.

  AddType  application/x-httpd-php-cgi .php3
  AddType  application/x-httpd-php-cgi .phtml
  AddType  application/x-httpd-php-cgi .php

  Action application/x-httpd-php-cgi /cgi-bin/php

Running only PHPMapScript scripts as a CGI

This is specially useful when your distribution already comes with the PHP executable _and_ the DSO module, so you can then choose which scripts are run as a CGI and which are run by the DSO module with no compilation at all. You need to add the following lines in your Apache's config file:

 Action phtml-script /cgi/php
 AddHandler phtml-script .phtml

If you choose the .phtml extension (you can choose any extension you like) you must remove it from the AddType? Directive (that also may come in different lines, as shown above).

AddType application/x-httpd-php .php .php4 .php3 .phtml

Remember that Apache must be able to access the php interpreter, so you need to make a link to it in the directory that can execute CGI's. For example, if your scripts are in /var/www/html/mapscript you might need to add to Apache's config file:

 <Directory /var/www/html/mapscript/cgi>
      Options ExecCGI FollowSymLinks

Then, in /var/www/html/mapscript, create the cgi directory, making it readable and executable to apache:

 #mkdir cgi
 #chgrp apache ./cgi (some distributions call the 'apache' group 'nobody')
 #chmod 750 ./cgi

Finally, you must create the link:

ln -s /usr/bin/php /var/www/html/mapscript/cgi/php

where /usr/bin/php is the location of the php executable.

After you restart Apache, any script with the .phtml extension in the /var/www/html/mapscript directory will execute successfully as a CGI (if you try accessing through a browser a .phtml file in another directory a 404 error appears), and all files with .php extension (in any directory) will be interpreted with the DSO module. You can generalize this procedure so any script with .phtml extension executes as a CGI, adjusting the place where you put the link to the executable and using, for instance, the ScriptAlias directive (there are many ways to do it and are dependant on your particular configuration).

If you already have a lot of .php files that now must be run as a CGI (because of the mapscript extension), you can use this script to change them to the new extension (part of the PHPMyAdmin distribution, credits removed due to space):

 if [ $# != 2 ]
 if [ $1 == $2 ]
 for i in `find . -name "*.$1"`
         echo $i
         sed -e 's/\.'$1'/\.'$2'/g' $i > `ls $i|sed -e 's/'$1'/'$2'/g'`
         rm $i

After you save this script in a file, say, and gave it execution permissions, you can run it like this:

 #./ php phtml 

Besides the extension change, the script changes all ocurrences of, in the example, php for phtml (to fix the links).

Last modified 10 years ago Last modified on Jan 27, 2009 8:14:35 AM