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[@]}" 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
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.