PHP Deprecated 함수 사용 문제 해결하기

프리터코더·2025년 5월 29일
0

php 문제 해결

목록 보기
43/79

PHP 버전 업그레이드 시 deprecated 함수로 인한 경고나 오류를 해결하는 방법을 알아보겠습니다. 안전하고 효율적인 대체 방법들을 제시합니다.

1. mysql_* 함수 대체

문제: PHP 7.0에서 완전히 제거된 mysql_* 함수들

해결책: PDO 또는 MySQLi로 마이그레이션

// 기존 mysql_* 함수 (제거됨)
// $conn = mysql_connect($host, $user, $pass);
// $result = mysql_query("SELECT * FROM users");

// PDO로 대체
class DatabaseHelper {
    private $pdo;
    
    public function __construct($host, $dbname, $user, $pass) {
        try {
            $this->pdo = new PDO(
                "mysql:host=$host;dbname=$dbname;charset=utf8mb4",
                $user, $pass,
                [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
            );
        } catch (PDOException $e) {
            throw new Exception("DB 연결 실패: " . $e->getMessage());
        }
    }
    
    public function query($sql, $params = []) {
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    public function insert($table, $data) {
        $columns = implode(',', array_keys($data));
        $placeholders = ':' . implode(', :', array_keys($data));
        
        $sql = "INSERT INTO $table ($columns) VALUES ($placeholders)";
        $stmt = $this->pdo->prepare($sql);
        return $stmt->execute($data);
    }
}

2. each() 함수 대체

문제: PHP 7.2에서 deprecated, PHP 8.0에서 제거

해결책: foreach 또는 array 함수로 대체

// 기존 each() 사용 (deprecated)
// while (list($key, $value) = each($array)) {
//     echo "$key => $value\n";
// }

// foreach로 대체 (권장)
function processArrayModern($array) {
    foreach ($array as $key => $value) {
        echo "$key => $value\n";
    }
}

// each() 동작을 완전히 재현해야 하는 경우
class ArrayIteratorHelper {
    public static function each(&$array) {
        $key = key($array);
        if ($key === null) {
            return false;
        }
        
        $value = current($array);
        next($array);
        
        return [
            0 => $key,
            1 => $value,
            'key' => $key,
            'value' => $value
        ];
    }
    
    // 더 현대적인 방법
    public static function processWithGenerator($array) {
        foreach ($array as $key => $value) {
            yield ['key' => $key, 'value' => $value];
        }
    }
}

// 사용 예시
$data = ['a' => 1, 'b' => 2, 'c' => 3];

// 기존 방식 대체
foreach (ArrayIteratorHelper::processWithGenerator($data) as $item) {
    echo "{$item['key']} => {$item['value']}\n";
}

3. create_function() 대체

문제: PHP 7.2에서 deprecated, PHP 8.0에서 제거

해결책: 익명 함수(클로저) 사용

// 기존 create_function() 사용 (deprecated)
// $func = create_function('$a,$b', 'return $a + $b;');

// 익명 함수로 대체
$func = function($a, $b) {
    return $a + $b;
};

// 동적 함수 생성이 필요한 경우
class FunctionFactory {
    public static function createMathFunction($operation) {
        switch ($operation) {
            case 'add':
                return function($a, $b) { return $a + $b; };
            case 'multiply':
                return function($a, $b) { return $a * $b; };
            case 'power':
                return function($a, $b) { return pow($a, $b); };
            default:
                throw new InvalidArgumentException("Unknown operation: $operation");
        }
    }
    
    // 문자열 기반 함수 생성 (주의해서 사용)
    public static function createFromString($params, $body) {
        // 보안상 위험하므로 가능한 피하고, 필요시 검증 추가
        $code = "return function($params) { $body };";
        return eval($code);
    }
}

// 사용 예시
$addFunc = FunctionFactory::createMathFunction('add');
echo $addFunc(5, 3); // 8

4. ereg_* 함수 대체

문제: PHP 7.0에서 제거된 POSIX 정규표현식 함수들

해결책: PCRE 함수로 마이그레이션

// 기존 ereg_* 함수들 (제거됨)
// ereg(), eregi(), ereg_replace(), eregi_replace()

class RegexHelper {
    // ereg() 대체
    public static function match($pattern, $string, &$matches = null) {
        // POSIX를 PCRE 패턴으로 변환
        $pcrePattern = '/' . $pattern . '/';
        return preg_match($pcrePattern, $string, $matches);
    }
    
    // eregi() 대체 (대소문자 무시)
    public static function matchIgnoreCase($pattern, $string, &$matches = null) {
        $pcrePattern = '/' . $pattern . '/i';
        return preg_match($pcrePattern, $string, $matches);
    }
    
    // ereg_replace() 대체
    public static function replace($pattern, $replacement, $string) {
        $pcrePattern = '/' . $pattern . '/';
        return preg_replace($pcrePattern, $replacement, $string);
    }
    
    // 일반적인 패턴 변환 도우미
    public static function convertPosixToPcre($posixPattern) {
        // 기본적인 POSIX -> PCRE 변환
        $conversions = [
            '\<' => '\b',  // 단어 경계
            '\>' => '\b',
            '[:alnum:]' => 'a-zA-Z0-9',
            '[:alpha:]' => 'a-zA-Z',
            '[:digit:]' => '0-9'
        ];
        
        $pcrePattern = $posixPattern;
        foreach ($conversions as $posix => $pcre) {
            $pcrePattern = str_replace($posix, $pcre, $pcrePattern);
        }
        
        return '/' . $pcrePattern . '/';
    }
}

// 사용 예시
$text = "Hello World 123";
if (RegexHelper::matchIgnoreCase('[a-z]+', $text, $matches)) {
    echo "매치됨: " . $matches[0];
}

5. 포괄적인 Deprecated 함수 감지 및 대체

문제: 코드베이스 전체의 deprecated 함수 사용 현황 파악

해결책: 자동 감지 및 대체 도구 구현

class DeprecatedFunctionHandler {
    private static $deprecatedFunctions = [
        'mysql_connect' => 'PDO 또는 MySQLi 사용',
        'mysql_query' => 'PDO prepare/execute 사용',
        'each' => 'foreach 사용',
        'create_function' => '익명 함수 사용',
        'ereg' => 'preg_match 사용',
        'eregi' => 'preg_match with /i flag 사용',
        'split' => 'explode 또는 preg_split 사용'
    ];
    
    public static function checkCode($code) {
        $issues = [];
        
        foreach (self::$deprecatedFunctions as $func => $suggestion) {
            if (preg_match('/\b' . preg_quote($func) . '\s*\(/', $code)) {
                $issues[] = [
                    'function' => $func,
                    'suggestion' => $suggestion,
                    'line' => self::findLineNumber($code, $func)
                ];
            }
        }
        
        return $issues;
    }
    
    private static function findLineNumber($code, $function) {
        $lines = explode("\n", $code);
        foreach ($lines as $lineNum => $line) {
            if (strpos($line, $function) !== false) {
                return $lineNum + 1;
            }
        }
        return null;
    }
    
    // 자동 대체 (간단한 경우만)
    public static function autoReplace($code) {
        $replacements = [
            '/\beach\s*\(\s*\$([^)]+)\s*\)/' => 'foreach ($\1 as $key => $value)',
            '/mysql_real_escape_string\s*\(\s*([^)]+)\s*\)/' => 'addslashes(\1)', // 임시 대체
        ];
        
        foreach ($replacements as $pattern => $replacement) {
            $code = preg_replace($pattern, $replacement, $code);
        }
        
        return $code;
    }
    
    // 파일 스캔
    public static function scanFile($filepath) {
        if (!file_exists($filepath)) {
            throw new Exception("파일을 찾을 수 없습니다: $filepath");
        }
        
        $code = file_get_contents($filepath);
        $issues = self::checkCode($code);
        
        return [
            'file' => $filepath,
            'issues' => $issues,
            'count' => count($issues)
        ];
    }
}

// 사용 예시
$result = DeprecatedFunctionHandler::scanFile('legacy_code.php');
foreach ($result['issues'] as $issue) {
    echo "라인 {$issue['line']}: {$issue['function']} - {$issue['suggestion']}\n";
}
profile
일용직 개발자. freetercoder@gmail.com

0개의 댓글