PHP7 → PHP8 마이그레이션 오류 모음 및 실무 해결 방법 총정리

PHP7에서 PHP8로 업그레이드할 때 발생하는 Fatal Error, Deprecated 경고, TypeError, Undefined Array Key 등 주요 마이그레이션 오류를 사례별로 정리했습니다. 실무 환경에서 바로 적용 가능한 해결 방법과 체크리스트를 함께 소개합니다.

PHP7 -> PHP8 마이그레이션 오류 모음

PHP7 → PHP8 마이그레이션 과정에서는 예상보다 많은 호환성 문제가 발생할 수 있습니다. 특히 오래된 레거시 프로젝트나 CodeIgniter, Laravel, 자체 구축 CMS 환경에서는 PHP8의 강화된 타입 검사와 문법 변경으로 인해 기존 코드가 정상적으로 동작하지 않는 경우가 많습니다.

이번 글에서는 PHP7에서 PHP8로 업그레이드할 때 가장 많이 발생하는 오류와 실무 해결 방법을 정리합니다. 서버 이전, 리눅스 업그레이드, Apache 또는 Nginx 버전 변경과 함께 진행하는 경우가 많기 때문에 실제 운영 환경 기준으로 설명합니다.


PHP8 마이그레이션 전 반드시 확인해야 하는 이유

PHP8은 단순한 성능 개선 버전이 아닙니다.

다음과 같은 큰 변화가 포함되어 있습니다.

구분                                              PHP7                                                         PHP8
타입 검사 비교적 느슨함 엄격함
Warning 무시 가능 Fatal Error 발생 가능
내부 함수 NULL 허용 많음 NULL 허용 제한
문자열 처리 암묵적 변환 명시적 처리 필요
Array 접근 Warning Error 가능

즉, PHP7에서는 동작하던 코드가 PHP8에서는 중단될 수 있습니다.


1. Undefined Array Key 오류

오류 예시

 
$name = $_GET['name'];
 

PHP7

Notice: Undefined index: name
 

PHP8

Warning: Undefined array key "name"
 

원인

존재하지 않는 배열 키를 직접 호출했기 때문입니다.

해결 방법

 
$name = $_GET['name'] ?? '';
 

또는

 
if (isset($_GET['name'])) {
    $name = $_GET['name'];
}
 

실무에서는 Null Coalescing Operator를 사용하는 것이 가장 일반적입니다.

 
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';
 

2. Trying to Access Array Offset on Value of Type Null

오류 예시

 
$data = null;

echo $data['name'];
 

오류

Trying to access array offset on value of type null
 

원인

배열이라고 가정했지만 실제 값은 NULL입니다.

해결 방법

 
echo $data['name'] ?? '';
 

또는

 
if (is_array($data)) {
    echo $data['name'];
}
 

API 응답 처리 시 자주 발생하는 오류입니다.


3. implode() Parameter Order 오류

PHP7에서는 동작하던 코드입니다.

 
implode($array, ',');
 

PHP8에서는 오류가 발생합니다.

TypeError
 

해결 방법

순서를 변경해야 합니다.

 
implode(',', $array);
 

공식 문법은 항상 구분자가 첫 번째 인자입니다.


4. count() Parameter Must Be an Array

오류 예시

 
$data = null;

$count = count($data);
 

PHP8 오류

count(): Argument #1 must be Countable|array
 

해결 방법

 
$count = count($data ?? []);
 

또는

 
$count = is_array($data)
    ? count($data)
    : 0;
 

5. Required Parameter Follows Optional Parameter

오류 예시

 
function test($name = '', $age)
{
}
 

PHP8 Fatal Error

Required parameter $age follows optional parameter $name
 

해결 방법

 
function test($name, $age = 0)
{
}
 

또는

 
function test($age, $name = '')
{
}
 

6. Non-Static Method Cannot Be Called Statically

PHP7 코드

 
class User
{
    public function getName()
    {
        return 'kim';
    }
}

User::getName();
 

PHP8 오류

Non-static method cannot be called statically
 

해결 방법

 
$user = new User();

$user->getName();
 

또는

 
class User
{
    public static function getName()
    {
        return 'kim';
    }
}
 

7. Constructor 이름 방식 오류

PHP4 스타일 생성자는 제거되었습니다.

기존 코드

 
class Member
{
    function Member()
    {
        echo 'start';
    }
}
 

PHP8

Deprecated 또는 동작 안함
 

수정

 
class Member
{
    public function __construct()
    {
        echo 'start';
    }
}
 

8. each() 함수 제거

PHP7에서 Deprecated 되었던 함수입니다.

 
each($array);
 

PHP8에서는 제거되었습니다.

해결 방법

 
foreach ($array as $key => $value)
{
    echo $key;
}
 

9. create_function() 제거

기존 코드

 
create_function('$a', 'return $a * 2;');
 

PHP8 제거

해결 방법

 
fn($a) => $a * 2;
 

또는

 
function($a) {
    return $a * 2;
};
 

10. get_magic_quotes_gpc() 제거

PHP7 이하 레거시 프로젝트에서 자주 발견됩니다.

 
get_magic_quotes_gpc();
 

PHP8

Call to undefined function
 

해결 방법

관련 코드를 제거합니다.

Magic Quotes 기능 자체가 폐기되었습니다.


11. Call to Undefined Function mysql_connect()

매우 많이 발생하는 오류입니다.

기존 코드

 
mysql_connect();
 

PHP8

Call to undefined function mysql_connect()
 

원인

mysql 확장이 완전히 제거되었습니다.

해결 방법

mysqli 사용

 
$conn = mysqli_connect(
    'localhost',
    'root',
    'password',
    'dbname'
);
 

PDO 사용

 
$pdo = new PDO(
    "mysql:host=localhost;dbname=test",
    "user",
    "password"
);
 

실무에서는 PDO 사용을 권장합니다.


12. TypeError 발생 증가

PHP8은 타입 검사가 매우 엄격합니다.

예시

 
strpos(null, 'abc');
 

오류

TypeError
 

해결

 
strpos($value ?? '', 'abc');
 

또는

 
if (!empty($value)) {
    strpos($value, 'abc');
}
 

13. Fatal error: Uncaught ValueError

PHP8에서 새롭게 등장한 오류입니다.

예시

 
str_repeat('a', -1);
 

오류

ValueError
 

해결

 
$count = max(0, $count);

str_repeat('a', $count);
 

14. match 표현식 관련 오류

PHP8 신규 문법입니다.

 
$result = match($status) {
    1 => 'success',
    2 => 'fail'
};
 

일치하는 값이 없으면

UnhandledMatchError
 

발생할 수 있습니다.

수정

 
$result = match($status) {
    1 => 'success',
    2 => 'fail',
    default => 'unknown'
};
 

15. String to Number 비교 방식 변경

PHP7

 
0 == "test"
 

결과

 
true
 

PHP8

 
false
 

비교 결과가 달라질 수 있습니다.

실무에서는 반드시

 
===
 

사용을 권장합니다.

 
if ($status === 1)
{
}
 

PHP8 마이그레이션 체크리스트

업그레이드 전 다음 항목을 점검하면 대부분의 장애를 예방할 수 있습니다.

점검 항목확인
mysql_* 함수 사용 여부 필수
each 함수 사용 여부 필수
create_function 사용 여부 필수
Magic Quotes 코드 존재 여부 필수
배열 키 존재 여부 검사 필수
count() 사용 위치 확인 필수
implode() 파라미터 순서 확인 필수
정적 호출 여부 확인 필수
타입 선언 검토 권장
Composer 패키지 버전 확인 필수

실무에서 추천하는 PHP8 업그레이드 절차

1단계

현재 서버 버전 확인

 
php -v
 

2단계

Composer 패키지 점검

 
composer outdated
 

3단계

PHP Compatibility 검사

 
composer require --dev phpcompatibility/php-compatibility
 

PHP_CodeSniffer 실행

 
phpcs --standard=PHPCompatibility src/
 

4단계

스테이징 서버 테스트

운영 서버에서 바로 PHP8을 적용하지 말고 반드시 별도 테스트 서버에서 검증합니다.

5단계

에러 로그 모니터링

 
tail -f /var/log/php/error.log
 

또는

 
tail -f /var/log/apache2/error.log
 

FAQ

PHP7에서 PHP8로 업그레이드하면 성능이 얼마나 향상되나요?

일반적으로 PHP8의 JIT 컴파일러와 엔진 개선으로 PHP7 대비 성능 향상을 기대할 수 있습니다. 다만 웹 서비스에서는 코드 구조와 DB 성능의 영향이 더 크기 때문에 실제 체감은 환경마다 다릅니다.

PHP8 업그레이드 전에 가장 먼저 확인해야 할 것은 무엇인가요?

mysql_* 함수, each(), create_function() 같은 제거된 기능 사용 여부를 확인하는 것이 가장 중요합니다.

PHP8로 업그레이드하면 기존 CodeIgniter 프로젝트도 문제가 발생하나요?

구버전 CodeIgniter 3.x는 일부 수정이 필요할 수 있으며, 오래된 라이브러리나 커스텀 코드에서 PHP8 호환성 문제가 자주 발생합니다.

PHP8에서 가장 많이 발생하는 오류는 무엇인가요?

Undefined Array Key, TypeError, count() 관련 오류, mysql_connect 제거 오류가 가장 빈번하게 발생합니다.


마무리

PHP7 → PHP8 마이그레이션은 단순 버전 업그레이드가 아니라 코드 품질과 호환성을 개선하는 작업입니다. 특히 레거시 프로젝트에서는 Undefined Array Key, TypeError, mysql_connect 제거, each 함수 제거 등 다양한 오류가 발생할 수 있으므로 사전 점검이 중요합니다. 운영 서버에 적용하기 전 충분한 테스트 환경을 구축하고 로그를 분석하면서 단계적으로 PHP8 마이그레이션을 진행하는 것을 권장합니다.