JSON Error: Single unpaired UTF-16 surrogate in unicode escape

2025. 1. 10. 13:57개발/개발 필기

반응형

PHP에서 JSON 데이터 처리: 나의 3시간을 날려버린 오류와 해결책

예기치 않은 오류는 개발 과정에서 피할 수 없는 일입니다.

최근에 PHP로 개발하면서 JSON 데이터를 배열로 변환하려고 할 때,

"Single unpaired UTF-16 surrogate in unicode escape" 오류에 부딪혔습니다.

이 오류는 작은 문제 같지만 결국 저를 괴롭히며 소중한 3시간을 날려버렸습니다.

 

JSON 데이터 디코딩의 기본

JSON 문자열을 배열로 변환할 때, 우리는 흔히 다음과 같은 코드를 사용합니다:

$arrayData = json_decode($jsonData,true);

하지만 이 방법이 실패할 수도 있습니다.

오류를 확인하는 방법은 다음과 같습니다:

 

$arrayData = json_decode($jsonData,true);
if (json_last_error() !== JSON_ERROR_NONE) {
    echo 'JSON Error: ' . json_last_error_msg(); // 에러 메시지 출력
}

 

제 경우, 출력된 오류 메시지는 다음과 같았습니다:

JSON Error: Single unpaired UTF-16 surrogate in unicode escape

이 오류는 꽤 머리 아픈 원인으로 연결되었습니다.

 

오류의 원인

  1. 불완전한 UTF-16 서로게이트 쌍
    UTF-16 인코딩에서 특정 문자는 두 개의 16비트 코드 유닛(서로게이트 쌍)으로 표현됩니다. 하나가 결여될 경우, 이 오류가 발생할 수 있습니다.
  2. 귀여운 이모지 사용
    다음과 같은 귀여운 이모지가 포함된 데이터를 수신했을 때도 문제가 발생했습니다:
...[
	{
    	"categoryId":"aa95b614cf7646169421427cae6459b1",
        "title":"🎉곱이곱다",
        "displayCount":12,
        "categoryType":"DISPLAY"
    },
    {
    	"categoryId":"1f6e1a2f75bf4003903a6feccd489f5f",
        "title":"🍜내일도착보장🚨",
        "displayCount":12,
        "categoryType":"DISPLAY"
    },
    {
    	"categoryId":"b9f162e5fc464bf0a1dd8f70cac52d1e",
        "title":"🚀무료배송🌶️",
        "displayCount":12,
        "categoryType":"DISPLAY"
    },
     ...

이러한 이모지는 JSON 데이터의 파싱을 방해했습니다.

 

해결 방법

이 문제를 해결하는 두 가지 방법을 발견했습니다:

1. 이모지를 제거해 줍니다

이모지를 사라지게 하기 위해 다음과 같은 정규 표현식을 사용할 수 있습니다:

$cleaned_data = pregReplace('/[\x{1F000}-\x{1FFFF}]|[\x{2600}-\x{27BF}]|[\x{1F900}-\x{1F9FF}]/u', '', $jsonData);

 

2.잘못된 유니코드 이스케이프 시퀀스 제거

불완전한 Unicode 이스케이프 시퀀스를 제거하는 방법은 다음과 같습니다:

$cleanedData = preg_replace('/\\\\u[dD][89abAB][0-9a-fA-F]{2}(?!\\\\u[dD][c-fC-F][0-9a-fA-F]{2})/', '', $cleanedData);

 

 

 

이 두 스텝을 다음과 같이 결합하여 최종 코드를 작성했습니다:

// 이모지를 제거해 줍니다.
$cleanedData = preg_replace('/[\x{1F000}-\x{1FFFF}]|[\x{2600}-\x{27BF}]|[\x{1F900}-\x{1F9FF}]/u', '', $jsonData); 
// 잘못된 유니코드 이스케이프 시퀀스 제거:
$cleanedData = preg_replace('/\\\\u[dD][89abAB][0-9a-fA-F]{2}(?!\\\\u[dD][c-fC-F][0-9a-fA-F]{2})/', '', $cleanedData); 

// 디코딩
$arrayData = json_decode($cleanedData,true);

이렇게 하면 JSON 데이터를 문제 없이 배열로 변환할 수 있었습니다.

 

개발할 때 겪는 시행착오가 귀중한 교훈으로 이어지는 법입니다.

이러한 경험이 다른 개발자에게도 도움이 되기를 바랍니다!

 

필요한 부분이나 추가하고 싶은 내용이 있다면 말씀해 주세요!

 

 

반응형