Change from old to new PHP functions

Bulk update your code to run with PHP 7.0+

Migrating from PHP 5.x to PHP 7.x is a hassle when youre dealing with a large website or multiple websites on a server. So, Ive made some improvements to an existing a shell script to recursively modify directories of PHP pages that load in 4 or 5 but will no longer run in PHP 7.

The script will replace all the decommissioned mysql_* functions changing them to mysqli_* and some of the previously deprecated functions – replacing ereg, eregi with preg_match, ereg_match with preg_match, split with preg_split and changing the $HTTP globals to their modern versions.

#!/bin/sh

################################################################
#                                                              #
#  FIX DEPRECATED PHP FUNCTIONS                                #
#                                                              #
#  Coded by Noah Hearle, Design Extreme                        #
#  https://designextreme.com                                   #
#  With thanks to: Peter Bowey, pbcomp.com.au                  #
#                                                              #
#  Created: 2015/02/27                                         #
#  Modified: 2019/05/24                                        #
#                                                              #
#  Change old PHP functions to their modern equivalent         #
#                                                              #
#  ereg()                 => preg_match()                      #
#  ereg_replace()         => preg_replace()                    #
#  split()                => preg_split()                      #
#  mysql_escape_string()  => mysql_real_escape_string()        #
#  $HTTP_GET_VARS[]       => $_GET[]                           #
#  $HTTP_POST_VARS[]      => $_POST[]                          #
#  $HTTP_REQUEST_VARS[]   => $_REQUEST[]                       #
#  $HTTP_SESSION_VARS[]   => $_SESSION[]                       #
#  $HTTP_COOKIE_VARS[]    => $_COOKIE[]                        #
#  $HTTP_SERVER_VARS[]    => $_SERVER[]                        #
#  $HTTP_POST_FILES[]     => $_FILES[]                         #
#  mysql_xxx()            => mysqli_xxx()                      #
#                                                              #
#  Post your comments at:                                      #
#  https://blog.nahoo.co.uk/migrate-from-php-5-7/          #
#                                                              #
#  Usage: sh ./php_update.sh <directory> [<database resource>] #
#  Note: For the database resource variable use single quotes  #
#  and escape $ symbol, e.g. '\$db'                            #
#                                                              #
################################################################

directory=$1
db=$2
php_files=()
php_mysql_files=()

if [ ! -n "$1" ]; then
        echo -e "\e[38;5;202mError:\e[0m Missing target PHP directory."
        echo 'Usage: sh ./php_deprecated_functions_update.sh <directory> [<database resource>]'
        exit
fi

if  [ -n "$2" ]; then
        if [[ ! $db =~ ^['\\'] ]] && [[ $db =~ ^['$'] ]] || [[ ! $db =~ ^['$'] ]]; then
                old_db=$db

                if [[ ! $db =~ ^['\\'] ]] && [[ $db =~ ^['$'] ]]; then
                        db='\'"$db"
                else
                        db='\$'"$db"
                fi

                echo -e "\e[38;5;115mDatabase resource string must start with \\\$.\e[0m Changing this from: '\e[38;5;202m$old_db\e[0m' to: '\e[38;5;118m$db\e[0m'"
        fi
fi

for file in $(find $directory -type f \( -name "*.php" -o -name "*.inc" -o -name "*.install" -o -name "*.module" -o -name "*.html" \)); do
        outdated_file=$(grep -El "([^_]eregi?(_replace)?\(|[^_.]split\(|mysql_escape_string\(|\\\$HTTP_(POST_FILES|((GET|POST|REQUEST|SESSION|COOKIE|SERVER|ENV)_VARS)))" "$file")
        outdated_file_mysql=$(grep -El  "mysql_[a-z_]+\s?\(" "$file")
        if [ -n "$outdated_file" ] || [ -n "$outdated_file_mysql" ] && [ -n "$db" ]; then
                if [ -n $outdated_file_mysql ] && [ -n "$db" ]; then
                        php_mysql_files+=($file)
                else
                        php_files+=($file)
                fi

                if [ -n "$outdated_file" ]; then
                        perl -pi -e "s@\\\$HTTP_(GET|POST|REQUEST|SESSION|COOKIE|SERVER|ENV)_VARS@\\\$_\1@g" $file
                        perl -pi -e "s@\\\$HTTP_POST_(FILES)@\\\$_\1@g" $file
                        perl -pi -e "s@([^_])ereg(i?)\(['\"]([^\/'\"]*)['\"], ?@\1preg_match('\/\3\/\2', @g" $file
                        perl -pi -e "s@([^_])ereg(i?)\(['\"]([^#'\"]*)['\"], ?@\1preg_match('#\3#\2', @g" $file
                        perl -pi -e "s@([^_])ereg(i?)\(['\"]([^~'\"]*)['\"], ?@\1preg_match('~\3~\2', @g" $file
                        perl -pi -e "s@([^_])ereg(i?)\([\"]([^\/]*)[\"], ?@\1preg_match(\"\/\3\/\2\", @g" $file
                        perl -pi -e "s@([^_])ereg(i?)\((\\\$[^\\\$,]+)([^)+])@\1preg_match('\/'.preg_quote(\3, '\/').'\/\2'\4@g" $file
                        perl -pi -e "s@([^_])ereg(i?)_replace\(['\"]([^\/'\"]*?)['\"], ?@\1preg_replace('\/\3\/\2', @g" $file
                        perl -pi -e "s@([^_])ereg(i?)_replace\(['\"]([^#'\"]*?)['\"], ?@\1preg_replace('#\3#\2', @g" $file
                        perl -pi -e "s@([^_])ereg(i?)_replace\(['\"]([^~'\"]*?)['\"], ?@\1preg_replace('~\3~\2', @g" $file
                        perl -pi -e "s@([^_])ereg(i?)_replace\([\"]([^\/]*?)[\"], ?@\1preg_replace("\/\3\/\2", @g" $file
                        perl -pi -e "s@([^_])ereg(i?)_replace\((\\\$[^\\\$,]+)([^)+])@\1preg_replace('\/'.preg_quote(\3, '\/').'\/\2'\4@g" $file
                        perl -pi -e "s@([^_.])(split)\(['\"]([^/'\"]*)['\"], ?@\1preg_\2('/\3/\',@g" $file
                        perl -pi -e "s@([^_.])(split)\(['\"]([^#'\"]*)['\"], ?@\1preg_\2('#\3#\',@g" $file
                        perl -pi -e "s@([^_.])(split)\(['\"]([^~'\"]*)['\"], ?@\1preg_\2('~\3~\',@g" $file
                        perl -pi -e "s@(mysql_)(escape_string)\(@\1real_\2(@g" $file
                fi

                outdated_file_check=$(grep -El "([^_]eregi?(_replace)?\(|[^_.]split\(|\\\$HTTP_(POST_FILES|((GET|POST|REQUEST|SESSION|COOKIE|SERVER|ENV)_VARS)))" "$file")

                if [ -n $outdated_file_mysql ] && [ -n "$db" ]; then
                        php_function_class_exists=$(grep -El  "class\s+[A-Za-z][0-9A-Za-z_]*\s*|function\s+[A-Za-z][0-9A-Za-z_]*\s*\([^\)]*\)" "$file")
                        php_database_resource_global_exists=$(grep -El 'global\s+.*'"$db"'[\s;,]' "$file")

                        perl -pi -e 's@(mysql)_(query|select_db|set_charset)\s?\(([^\),]+),\s*[^\),]+\)@\1i_\2('"$db"', \3)@g' $file
                        perl -pi -e 's@(mysql)_(query|select_db|set_charset|(?:real_)escape_string)\s?\(@\1i_\2('"$db"', @g' $file
                        perl -pi -e 's@(mysql)_(affected_rows|close|errno|error|get_[a-z]_info|info|insert_id|ping|stat|thread_id)\s?\(\s*\)@\1i_\2('"$db"')@g' $file
                        perl -pi -e 's@(mysql)_([a-z_]+)\s?\(@\1i_\2(@g' $file

                        outdated_file_mysql_check=$(grep -El "mysql_[a-z_]+\s?\(" "$file")

                        if [ -n "$outdated_file_mysql_check" ]; then
                                echo -e "\e[38;5;202mDeprecated functions (including MySQL) not fully updated:\e[0m $file";
                        elif [ -n "$outdated_file_check" ]; then
                                echo -e "\e[38;5;202mDeprecated functions not fully updated (MySQL updated):\e[0m $file";
                        elif [ -n "$php_function_class_exists" ] && [ ! -n "$php_database_resource_global_exists" ]; then
                                echo -e "\e[38;5;118mDeprecated functions, including MySQL, updated\e[0m \e[33m[Database resource may not be set as a global in functions/classes]:\e[0m $file"
                        else
                                echo -e "\e[38;5;118mDeprecated functions, including MySQL, updated:\e[0m $file"
                        fi
                elif [ -n "$outdated_file_check" ]; then
                        echo -e "\e[38;5;202mDeprecated functions not fully updated:\e[0m $file"
                else
                        echo -e "\e[38;5;118mDeprecated functions updated:\e[0m $file"
                fi
        fi
done

if [ ${#php_files[@]} -gt 0 ]; then
        if [ ${#php_mysql_files[@]} -gt 0 ]; then
                echo -e "\e[38;5;115mUpdated files with deprecated functions (excluding MySQL):\e[0m ${#php_files[@]}"
        else
                echo -e "\e[38;5;115mUpdated files with deprecated functions:\e[0m  ${#php_files[@]}"
        fi
fi

if [ ${#php_mysql_files[@]} -gt 0 ]; then
        echo -e "\e[38;5;115mUpdated files with deprecated functions (including MySQL):\e[0m ${#php_mysql_files[@]}"
fi

Save this as a bash file (e.g. php_deprecated_functions_update.sh) and run using: sh php_deprecated_functions_update.sh /home/user/directory ‘\$db’. The second argument is optional and will need something like $db being accessible within classes and functions (such as a global variable). If you haven’t added the global it will display a warning that may assist with manually adding these to classes and functions.

Please always remember backup the files before running this script!

Last updated on

One thought on “Bulk update your code to run with PHP 7.0+”

  1. I’ve added a sanity check on the MySQL resource string (e.g. $db) so it will format this correctly within the script – now you can just use “db” without worrying about the dollar symbol.

Leave a Reply

Your email address will not be published. Required fields are marked *