This article explains how to set up a custom php.ini that overides your servers default php.ini, providing an easier alternative (in the long run) than using .htaccess to overide php.ini settings. It assumes that you have a ssh account set-up and are using a ssh client (e.g. putty - http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html). You are also expected to logically replace directory structures given here, with your own, if they are different.

Procedure for allowing php.ini configuration for a website (shows changing file upload max)

1/ Create a cgi-bin Directory

First you’ll need a cgi-bin directory:

mkdir ~/[your website directory]/cgi-bin/

This directory will be hosting your copy of php and your php.ini file.


2/ Create a script to retrieve the latest copy of php.cgi and php.ini

Make a file in ~/ called php-copy.sh containing the following, where 100M contains whatever file size limit you like, and [your website directory] is appropriately substituted.

For PHP4:

#!/bin/sh
CGIFILE="$HOME/[your website directory]/cgi-bin/php.cgi"
INIFILE="$HOME/[your website directory]/cgi-bin/php.ini"
rsync -a /dh/cgi-system/php.cgi "$CGIFILE"
# REMOVE THE FOLLOWING LINE TO CREATE THE UPDATE-ONLY SCRIPT:
cp /etc/php/cgi/php.ini "$INIFILE"

perl -p -i -e '
s/.*post_max_size.*/post_max_size = 100M/;
s/.*upload_max_filesize.*/upload_max_filesize = 100M/;
' "$INIFILE"

For PHP5:

#!/bin/sh
CGIFILE="$HOME/[your website directory]/cgi-bin/php.cgi"
INIFILE="$HOME/[your website directory]/cgi-bin/php.ini"
rsync -a /dh/cgi-system/php5.cgi "$CGIFILE"
# REMOVE THE FOLLOWING LINE TO CREATE THE UPDATE-ONLY SCRIPT:
cp /etc/php5/cgi/php.ini "$INIFILE"

perl -p -i -e '
s/.*post_max_size.*/post_max_size = 100M/;
s/.*upload_max_filesize.*/upload_max_filesize = 100M/;
' "$INIFILE"

A more general script with options (for references purposes only, do not do this):

#!/bin/sh
 
 test $# = 0 && exit 1
 while test "$1";do
   case $1 in
     -php5) PHP=php5 ;; 
     -sm) shift; SM=$1 ;;
     -rg) shift; RG=$1 ;;
     -pms) shift; PMS=$1 ;;
     -umfs) shift; UMFS=$1 ;;
     -mqg) shift; MQG=$1 ;;
     -met) shift; MET=$1 ;;
     -mit) shift; MIT=$1 ;;
     -ml) shift; ML=$1 ;;
     *) D=$1 ;;
   esac
   shift
 done
 test "$D" || exit 1
 test -d "$HOME/$D" || exit 1
 CGI="$HOME/$D/cgi-bin"
 mkdir -m0755 -p $CGI || exit 2
 
 PHP=${PHP:-php}
 SM=${SM:-On}
 RG=${RG:-Off}
 PMS=${PMS:-8M}
 UMFS=${UMFS:-7M}
 MQG=${MQG:-Off}
 MET=${MET:-30}
 MIT=${MET:-60}
 ML=${ML:-8M}
 
 CGIFILE="$CGI/$PHP.cgi"
 INIFILE="$CGI/php.ini"
 
 echo "CGI=$CGI MQG=${MQG} UMFS=${UMFS} PMS=${PMS} RG=${RG} SM=${SM} MET=${MET} MIT=${MIT} ML=${ML}" >&2
 
 rsync -au /dh/cgi-system/$PHP.cgi "$CGIFILE"
 [ -s /etc/$PHP/cgi/php.ini ] && \
   sed -e "s/^safe_mode[ ]*=.*/safe_mode = $SM/" \
   -e "s/register_globals[ ]*=.*/register_globals = $RG/" \
   -e "s/magic_quotes_gpc[ ]*=.*/magic_quotes_gpc = $MQG/" \
   -e "s/.*post_max_size.*/post_max_size = $PMS/" \
   -e "s/.*upload_max_filesize.*/upload_max_filesize = $UMFS/" \
   -e "s/.*max_execution_time.*/max_execution_time = $MET/" \
   -e "s/.*max_input_time.*/max_input_time = $MIT/" \
   -e "s/.*memory_limit.*/memory_limit= $ML/" \
   # REMOVE THE FOLLOWING LINE TO CREATE THE UPDATE-ONLY SCRIPT:
   /etc/$PHP/cgi/php.ini > "$INIFILE"
 
 chmod 0755 "$CGIFILE"
 chmod 0644 "$INIFILE"
 [ -s $CGI/.htaccess ] || echo "Options -Indexes" > $CGI/.htaccess
 touch $HOME/$D/.htaccess
 if grep -q '^Options' $HOME/$D/.htaccess; then
   grep -q '+ExecCGI' $HOME/$D/.htaccess || \
     sed -i 's/^Options\(.*\)/Options\1 +ExecCGI/' $HOME/$D/.htaccess
 else
   echo "Options +ExecCGI" >> $HOME/$D/.htaccess
 fi
 grep -q '^AddHandler[ ]\+php-cgi[ ]\+.php' $HOME/$D/.htaccess ||
   echo "AddHandler php-cgi .php" >> $HOME/$D/.htaccess
 if grep -q '^Action[ ]\+php-cgi' $HOME/$D/.htaccess; then
   sed -i "s@^Action[ ]\+php-cgi.*@Action php-cgi /cgi-bin/$PHP.cgi@" \
     $HOME/$D/.htaccess
 else
   echo "Action php-cgi /cgi-bin/$PHP.cgi"  >> $HOME/$D/.htaccess
 fi

3/ Prepare script for execution

Execute the following commands into the shell. This will give you permission to execute the php-copy.sh that we just created.

chmod +x php-copy.sh

This calls our new shell script to copy the php.cgi and php.ini files into our cgi-bin directory.

./php-copy.sh

If you get the error message: "bad interpreter: No such file or directory", there is probably an unseen problem with the formatting of the file.

Run the following command to convert it to proper Unix format before calling the script again: dos2unix php-copy.sh


4/ Test your new PHP setup

Open one of your existing PHP pages in your browser to ensure that your newly-installed local copy of PHP is functioning properly. If there is a problem, go back over the prior steps and use your debugging skills and your mastery of PHP, shell scripts and Linux to get your newly-copied PHP interpreter working! Once everything works properly, go on to the next step.


5/ Create a shell script to make a fresh copy of php (for future use)

cp php-copy.sh php-update.sh

Open the newly-created php-update.sh script in your favorite text editor and find this line:

# REMOVE THE FOLLOWING LINE TO CREATE THE UPDATE-ONLY SCRIPT:

Delete that line as well as the line following it. Then save php-update.sh

If you got a "bad interpreter: No such file or directory" error message when you executed ./php-copy.sh previously, remember to convert the new file to unix format by running the following command: dos2unix php-update.sh


6/ Set up a cron task to keep php up to date

Type:

crontab -e

And then enter the following in the text editor that shows up (replacing 'myusername' with your specific username):

@weekly /home/myusername/php-update.sh

This will update the php binary and config file once a week.

7/ Configure your website to use new the php.ini that we just set up

Create the file ~/[your website directory]/.htaccess which contains the lines:

Options +ExecCGI
AddHandler php-cgi .php
Action php-cgi /cgi-bin/php.cgi

This is telling Apache (the webserver) to use the php.cgi and php.ini that php-update.sh copied into ~/[your website directory]/cgi-bin.

Comments

poushag’s picture

I have found it saves a lot of time and headaches to run my Drupal6 website as a JumpBox VM. If there is a new Drupal6 release then I can deploy it quite easily by downloading the latest JumpBox VM, starting it up, and importing my last data backup. I have been customizing my Drupal instance and preserving those changes is a concern. So when I decided to increase the upload_max_filesize variable in php.ini, the above post was helpful. In my case the script came out like so (without the CGI intermediation):

#!/bin/sh
INIFILE="/etc/php5/apache2/php.ini"

perl -p -i -e '
s/.*post_max_size.*/post_max_size = 100M/;
s/.*upload_max_filesize.*/upload_max_filesize = 50M/;
' "$INIFILE"

apache2ctl graceful

After executing the script manually, I then added a file to /etc/cron.d/ configured to execute the script daily (which will reinstate my customizations automatically after a JumpBox VM upgrade).

Inclusion of these custom files in my JumpBox data backups was easily configured by editing the /jumpbox/etc/user.yml file.

Regards,