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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #!/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.noah.hearle.com/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!
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.