mtWeb  Home > PHP > Make Your PHP Code PortableSitemap  Search

Make Your PHP Code Portable

Posted by martin on 1 Jun 2002, last updated on 10 Sep 2002.

Make sure your program can run on different PHP setups by distributing a custom environment setup. Expalins how to create the config and how to get your current configuration.

Why should I care

People are different and they use different PHP configurations so if you want to run a script on your system you have two choices:

  • set your global configuration to something that allows the code to run
  • set a configuration specific to the program

If you go for the first one you're in trouble if you try to run two programs which require completely different setups. So the only choice seems to be the second one.

Well, then how do I do this

There are four different ways to set a PHP configuration option:

  • through php.ini
  • through httpd.conf
  • through a .htaccess file
  • or directly in PHP code

The first and second ones are only available to the system administrator of a website so you generally have to avoid them. Yes you may have access to those files but think about the other people that may be using the code - do they have access to those files? Usually not.

The third method - via a .htaccess file is available only on Apache and probably the NCSA httpd, but since Apache is the most popular webserver that is usually not a problem. The other thing that you should know about .htaccess files is that they may be disabled by the webmaster. If this is the case your only chance is to use a globally included PHP file which configures the system.

Setting the options with PHP code is the most portable way to configure a system. The only problem is that the accessible options are fewer than those available to a .htaccess file.

I'll go for a .htaccess file

The syntax for setting an option is:

php_value name value
php_flag name on or off

Example:

php_flag register_globals off
php_value arg_separator.output &

The example turns off register_globals and sets the value of arg_separator.output to & which is preferred rather than the default &.

Note: you can also set boolean options with the php_value directive, the string will be converted to boolean before assignment.

I'll go for PHP code

There's only one function for setting an option and it is ini_set() it is also aliased as ini_alter(). There is also a function that restores the original value and it is ini_restore().

How to use these:

ini_set('display_errors', false);
ini_set('arg_separator.input', ';');
...
ini_restore('display_errors');

Note: in the first call to ini_set() you can also use any type of variable it will be converted to boolean before setting the option.

Very nice but I don't know my configuration

I've got something for you too. This is a script that will detect common settings that may prevent your code from executing properly on a different system.

<?php

  define('boolean', 1);
  define('string', 2);
  define('integer', 3);

  $php_ini_all = Array(
    Array(string, 'arg_separator.input'),
    Array(string, 'arg_separator.output'),
    Array(boolean, 'display_errors'),
    Array(boolean, 'display_startup_errors'),
    Array(boolean, 'magic_quotes_runtime'),
    Array(integer, 'error_reporting'),
    Array(string, 'variables_order'),
    Array(string, 'gpc_order')
  );

  $php_ini_perdir = Array(
    Array(boolean, 'asp_tags'),
    Array(boolean, 'magic_quotes_gpc'),
    Array(string, 'output_buffering'),
    Array(boolean, 'register_globals'),
    Array(boolean, 'short_open_tag')
  );
?>

<?php
  function display_php_conf() {
    foreach ( $GLOBALS['php_ini_all'] as $option ) {
      $value = ini_get($option[1]);
      echo "ini_set('$option[1]', '$value');\n";
    }
  }

  function display_htaccess_conf() {
    global $php_ini_all, $php_ini_perdir;

    foreach ( array_merge($php_ini_all, $php_ini_perdir) as $option ) {
      $value = ini_get($option[1]);

      if ( $option[0] == boolean ) {
        $value = $value ? 'on' : 'off';
        $directive = 'php_flag';
      } else {
        $directive = 'php_value';
      }

      echo "$directive $option[1] $value\n";
    }
  }
?>

First we define these common options in two arrays for the different access levels, the first one for options available to both PHP code and .htaccess files, and the second only for .htaccess files. You may need to modify that in case you use non-default settings for other options too.

The two function display_php_conf() and display_htaccess_conf() print the PHP code and .htaccess directives for your config respectively.

Show me the config

<?php

  header('Content-type: text/plain');

  echo "PHP settings:\n";
  display_php_conf();

  echo "\n.htaccess settings:\n";
  display_htaccess_conf();
?>

This will just call the functions defined above so you can easily copy & paste it to a file or pipe it if you are using the CGI version of PHP.

Example output from the script

PHP settings:
ini_set('arg_separator.input', ';&');
ini_set('arg_separator.output', ';');
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
ini_set('magic_quotes_runtime', '');
ini_set('error_reporting', '2047');
ini_set('variables_order', 'GPCS');
ini_set('gpc_order', 'GPC');

.htaccess settings:
php_value arg_separator.input ;&
php_value arg_separator.output ;
php_flag display_errors on
php_flag display_startup_errors on
php_flag magic_quotes_runtime off
php_value error_reporting 2047
php_value variables_order GPCS
php_value gpc_order GPC
php_flag asp_tags off
php_flag magic_quotes_gpc off
php_value output_buffering 4096
php_flag register_globals off
php_flag short_open_tag off

Some general considerations

The above code didn't mention track_vars even a single time because as of PHP 4.0.3 it is always on. The example output was run on PHP 4.2.1 and ini_get() returns FALSE for track_vars as if it does not even exist. If you have an earlier version of PHP it is recommended to set it to true and disable register_globals for security and performance issues.

If you want to find even more information you can always count on the PHP manual.

Comments

config via .htaccess
by david mintz (dmintz@panix.com) on 9 Sep 2002 3:38pm GMT

Nice job on this article, both in terms of content as well as style. Thank you.

och aye
by John Lambie (jla@johndoegayhoe.biz) on 29 Nov 2002 4:19pm GMT

Good stuff

htaccess info
by kumar (at) chicagomodular.com () on 1 Jan 2003 12:34am GMT

might be worth pointing out that Mac OSX ships Apache with AllowOverride None in the main httpd.conf. For .htaccess files or php_in() to have any effect, one needs to set AllowOverride All (not very secure) or something more allowing so that php or .htaccess can set values like register_globals, etc. Maybe some other Apache installs default to this too.

ps. OSX also creates user-specific conf files so you need to change allowances there too. look in /etc/httpd/users/*.conf not just /etc/httpd/httpd.conf

thanks
by () on 24 Feb 2003 12:11pm GMT

thank you!

results vary with output_buffering set to off...
by Cameron Gull (cgull@operamail.com) on 28 Apr 2003 1:04am GMT

I wasn't able to write anything out, so I used:

<?php

ob_start();

.. < insert his code obove here > ....

ob_end_flush();

?>

It was then output like it should without the silly warning: Warning: Cannot add header information - headers already sent by (output started at.....

results vary with output_buffering set to off...
by Cameron Gull (cgull@operamail.com) on 28 Apr 2003 1:05am GMT

I wasn't able to write anything out, so I used:

< ?php

ob_start();

.. insert his code above here ....

ob_end_flush();

? >

It was then output like it should without the silly warning: Warning: Cannot add header information - headers already sent by (output started at.....

Great!
by Mike Kent (mike.kent@indystar.com) on 9 Jun 2003 11:23pm GMT

Great resource, the .htaccess lines were just what I needed. Anyone know of a complete listing somewhere?

php
by Yogesh (frnd4gan@yahoo.com) on 12 Jun 2003 2:02pm GMT

sending php

Admin functions
by Fred Trotter (tr0tt3r@dontspamme.yahoo.com) on 4 Oct 2003 9:50am GMT

There are some commands that cannot be overridden with the .htaccess files or using virtual hosts in an apache file.

For instance, if you want to modify the safe_mode setting you will have to add the following line to the httpd.conf file or (with apache 2.0) one of the other loaded config files...

php_admin_flag safe_mode off

Thanks for the excellent article

Fred Trotter

Man
by Dave () on 30 Jan 2004 9:21pm GMT

You Rock!

Complete listing
by Aidan Steele (aidan.s@NOsofthomeSPAM.net) on 13 Aug 2004 7:55am GMT

It's late, but here's a complete listing off all the possible variables you can change:

http://php.net/ini_set

Everything but PHP_INI_SYSTEM can be set in a .htaccess file :-)

gd
by Himanshu patel (himanshupatel79@redifffmail.com) on 19 Dec 2004 4:52am GMT

Hi

How can i configure gd library with php5?