Migrating from PHP 5.x to PHP 7.x is a hassle when you’re dealing with a large website or multiple websites on a server. So, I’ve 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[@]}"
fiSave 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


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.