개발하다 보면 쉼표로 구분된 문자열을 배열로 만들거나, 배열의 요소들을 하나의 문자열로 합쳐야 할 일이 자주 생긴다. 대부분의 PHP 개발자는 implode()와 explode()를 써봤을 테지만, 매개변수 순서를 헷갈리거나 null/빈 배열 처리에서 예상과 다른 결과를 만나곤 한다. 이번에는 이 두 함수의 정확한 동작 방식, 실무에서 자주 벌어지는 실수, 그리고 성능 최적화까지 완벽하게 정리해서 소개하겠다.
implode()는 배열의 모든 요소를 하나의 문자열로 합치는 함수다. explode()는 그 반대로, 특정 구분자를 기준으로 문자열을 배열로 쪼개는 함수다. 이름만 봐서는 어느 것이 어떤 역할을 하는지 헷갈리기 쉬운데, 이게 PHP 개발자들 사이에서 가장 흔한 실수 중 하나다.
실무에서는 데이터베이스 저장/조회, 폼 데이터 처리, CSV 파일 생성 등 문자열과 배열 변환이 매우 빈번하게 일어난다. 따라서 이 두 함수를 확실히 이해하는 것이 기본이다.
explode()의 기본 문법은 다음과 같다.
explode(string $separator, string $string, int $limit = PHP_INT_MAX): array
separator는 구분자(쉼표, 공백, 파이프 등), string은 쪼갤 문자열이다. limit은 몇 개까지 쪼갤지 결정하는 선택적 매개변수다.
기본 사용 예제
✗ 잘못된 것
$data = "apple, banana, orange";
$fruits = explode($data, ","); // 매개변수 순서 뒤바뀜
var_dump($fruits);
// 경고: explode(): Argument #2 must be of type string 에러 발생
✓ 올바른 것
$data = "apple, banana, orange";
$fruits = explode(",", $data); // 구분자가 먼저
var_dump($fruits);
// array(3) { [0]=> string(5) "apple" [1]=> string(8) " banana" [2]=> string(7) " orange" }
매개변수 순서를 주의하자. 첫 번째가 separator, 두 번째가 string이다. 많은 개발자가 직관적이지 않다고 느껴 순서를 자주 헷갈린다.
공백 제거하기
위 예제를 보면 "banana" 앞에 공백이 있다. 이건 구분자가 쉼표뿐이기 때문이다. 공백까지 제거하려면 trim()을 조합해야 한다.
✗ 잘못된 것
$data = "apple, banana, orange";
$fruits = explode(", ", $data); // 구분자에 공백 포함
var_dump($fruits);
// array(3) { [0]=> string(5) "apple" [1]=> string(6) "banana" [2]=> string(6) "orange" }
// 이 방법은 구분자가 정확히 ", "(쉼표+공백)일 때만 작동
✓ 올바른 것 - 배열 요소 각각 공백 제거
$data = "apple, banana, orange";
$fruits = explode(",", $data);
$fruits = array_map('trim', $fruits);
var_dump($fruits);
// array(3) { [0]=> string(5) "apple" [1]=> string(6) "banana" [2]=> string(6) "orange" }
limit 매개변수 활용
$data = "apple,banana,orange,grape";
// limit을 2로 설정하면 최대 2개까지만 쪼갬
$fruits = explode(",", $data, 2);
var_dump($fruits);
// array(2) { [0]=> string(5) "apple" [1]=> string(19) "banana,orange,grape" }
// 음수 limit은 마지막 요소를 제외
$fruits = explode(",", $data, -1);
var_dump($fruits);
// array(3) { [0]=> string(5) "apple" [1]=> string(6) "banana" [2]=> string(6) "orange" }
implode()의 기본 문법은 다음과 같다.
implode(string $separator, array $array): string
// PHP 7.4.0부터는 매개변수 순서를 바꿀 수도 있지만, 권장하지 않음
implode(array $array, string $separator): string
기본 사용 예제
✗ 잘못된 것
$fruits = ['apple', 'banana', 'orange'];
$result = implode($fruits, ","); // 매개변수 순서 뒤바뀜
echo $result;
// PHP 7.4+에서는 작동하지만, 이전 버전에서는 에러
✓ 올바른 것
$fruits = ['apple', 'banana', 'orange'];
$result = implode(",", $fruits); // 구분자가 먼저
echo $result;
// apple,banana,orange
키-값 배열 합치기
implode()는 배열 값만 합친다. 키까지 포함하려면 array_map()을 써야 한다.
$user = ['name' => 'John', 'age' => 30, 'city' => 'Seoul'];
// 값만 합치기
$result = implode(",", $user);
echo $result;
// John,30,Seoul
// 키=값 형태로 합치기
$result = implode("&", array_map(function($key, $value) {
return "$key=$value";
}, array_keys($user), $user));
echo $result;
// name=John&age=30&city=Seoul
// 또는 간단하게
$result = implode("&", array_map(
fn($k, $v) => "$k=$v",
array_keys($user),
$user
));
echo $result;
// name=John&age=30&city=Seoul
explode()와 implode()는 edge case에서 예상과 다르게 동작할 수 있다.
explode() null/빈 문자열 처리
✗ 잘못된 것
$data = null;
$result = explode(",", $data);
// PHP 8.0+에서 TypeError 발생: Argument #2 must be of type string, null given
✓ 올바른 것 - 타입 체크
$data = null;
if (is_string($data) && !empty($data)) {
$result = explode(",", $data);
} else {
$result = [];
}
var_dump($result);
// array(0) { }
✓ 또는 coalesce 연산자
$data = null;
$result = explode(",", $data ?? "");
var_dump($result);
// array(1) { [0]=> string(0) "" } // 빈 문자열도 배열 원소가 됨
// 빈 배열을 원하면
$result = explode(",", $data ?? "") ?
array_filter(explode(",", $data ?? "")) :
[];
// 더 간단하게는
$result = $data ? explode(",", $data) : [];
implode() 빈 배열 처리
$items = [];
$result = implode(",", $items);
echo $result;
// (아무것도 출력 안 됨 - 빈 문자열)
echo strlen($result) === 0 ? "empty" : "not empty";
// empty
// 데이터베이스 저장 시 주의
$tags = []; // 빈 배열
$sql = "INSERT INTO posts (tags) VALUES ('" . implode(",", $tags) . "')";
// INSERT INTO posts (tags) VALUES ('')
// 빈 문자열이 저장됨
// 더 안전하게
$tags = ['php', 'mysql'];
$tag_string = !empty($tags) ? implode(",", $tags) : null;
implode()와 explode()의 가장 실용적인 사용 예는 CSV 파일 처리다.
CSV 데이터 생성
// ✗ 잘못된 것 - 데이터에 쉼표나 따옴표가 있으면 깨짐
$users = [
['John', 'john@example.com', '30'],
['Jane Smith', 'jane@example.com', '28'], // 이름에 공백
['Bob', 'bob@example.com', '35']
];
$csv = "";
foreach ($users as $user) {
$csv .= implode(",", $user) . "\n";
}
echo $csv;
// John,john@example.com,30
// Jane Smith,jane@example.com,28 // 데이터가 2개 컬럼으로 파싱될 위험
// Bob,bob@example.com,35
// ✓ 올바른 것 - fputcsv() 사용
$users = [
['John', 'john@example.com', '30'],
['Jane Smith', 'jane@example.com', '28'],
['Bob', 'bob@example.com', '35']
];
$fp = fopen('php://memory', 'r+');
foreach ($users as $user) {
fputcsv($fp, $user);
}
rewind($fp);
$csv = stream_get_contents($fp);
fclose($fp);
echo $csv;
// "John","john@example.com","30"
// "Jane Smith","jane@example.com","28"
// "Bob","bob@example.com","35"
CSV 데이터 파싱
// ✗ 잘못된 것 - 따옴표나 쉼표 이스케이프를 처리 못 함
$csv = '"John","john@example.com","30"';
$user = explode(",", $csv);
var_dump($user);
// array(3) { [0]=> string(6) "\"John\"" ... } // 따옴표가 남아있음
// ✓ 올바른 것 - fgetcsv() 사용
$csv_content = '"John","john@example.com","30"' . "\n" .
'"Jane Smith","jane@example.com","28"';
$fp = fopen('php://memory', 'r+');
fwrite($fp, $csv_content);
rewind($fp);
$users = [];
while (($row = fgetcsv($fp)) !== false) {
$users[] = $row;
}
fclose($fp);
var_dump($users);
// array(2) {
// [0]=> array(3) { [0]=> string(4) "John" [1]=> string(15) "john@example.com" ... }
// [1]=> array(3) { [0]=> string(10) "Jane Smith" ... }
// }
문자열을 반복적으로 합칠 때는 implode()를 한 번에 쓰는 것이 훨씬 빠르다.
// ✗ 느린 것 - 반복 연결
$items = range(1, 10000);
$result = "";
foreach ($items as $item) {
$result .= $item . ",";
}
// 매번 새로운 문자열 객체 생성 → 메모리 낭비
// ✓ 빠른 것 - implode 한 번에
$items = range(1, 10000);
$result = implode(",", $items);
// 한 번에 메모리 할당
10000개 요소 기준으로 반복 연결은 implode()보다 수십 배 느릴 수 있다. 배열의 모든 요소를 합칠 때는 항상 implode()를 쓰자.
배열을 저장할 때 implode()로 구분자 기반 문자열로 할지, json_encode()로 JSON으로 할지 고민될 수 있다.
| 구분 | implode() 문자열 | JSON |
|---|---|---|
| 형식 | apple,banana,orange | ["apple","banana","orange"] |
| 용량 | 매우 작음 | 더 큼 |
| 구조 | 1차원만 가능 | 다차원 가능 |
| 타입 | 항상 문자열 | 정수, 불린 등 지원 |
| 호환성 | 텍스트 기반 포맷(CSV 등) | API, 설정 파일 |
간단한 태그나 카테고리 목록은 implode()로 충분하지만, 중첩된 데이터나 메타데이터는 JSON을 쓰는 게 낫다.
implode()와 explode()는 매우 기본적인 함수지만, 매개변수 순서, null 처리, CSV 같은 특수 형식에서 실수하기 쉽다. 특히 데이터 저장/조회가 빈번한 실무에서는 이 함수들의 정확한 동작을 아는 것이 중요하다. 더 복잡한 문자열 조작이 필요하면 str_replace(), str_pad(), substr() 같은 함수들과 조합해서 쓰면 되고, CSV 파일은 fgetcsv()/fputcsv()를 쓰는 게 훨씬 안전하다는 점을 잊지 말자. 이 글의 매개변수 순서와 edge case 처리 부분을 참고해 코드를 작성하면, 문자열과 배열 변환으로 인한 버그를 확실히 줄일 수 있을 것이다.