개발자들이 보고서나 테이블을 만들 때 자주 마주치는 문제가 있다. 숫자 앞에 0을 붙여야 하거나, 텍스트를 일정 길이로 채워야 하는데 어떤 함수를 써야 할지 모르는 경우다. 대부분은 반복문에서 조건문으로 직접 처리하거나, 정규표현식을 가져다 쓴다. 다만 PHP는 이미 이 일을 완벽하게 해주는 내장 함수 str_pad()가 있다는 것을 모르는 경우가 많다. 이번에는 str_pad()가 정확히 뭔지, 왜 필요한지, 어떻게 제대로 써야 하는지 완벽하게 정리하겠다.
기본 형태는 이렇다.
str_pad(string $string, int $length, string $pad_string = " ", int $pad_type = STR_PAD_RIGHT): string
각 매개변수의 의미는 다음과 같다.
$string: 원본 문자열$length: 최종 문자열의 길이(바이트 단위)$pad_string: 채울 문자(기본값은 공백)$pad_type: 어디에 채울지를 결정하는 상수
패딩 방식은 세 가지가 있다.
| 상수 | 동작 | 사용 예 |
|---|---|---|
| STR_PAD_RIGHT | 문자열 뒤에 추가 (기본값) | 이름을 표 맨 앞에 왼쪽 정렬 |
| STR_PAD_LEFT | 문자열 앞에 추가 | 숫자 앞에 0을 붙이기 (주문번호, 송장번호) |
| STR_PAD_BOTH | 양쪽에 추가 | 제목을 중앙 정렬 |
✗ 잘못된 방법: 반복문으로 직접 0 추가
$order_id = 123;
$formatted = '';
for ($i = 0; $i < (5 - strlen($order_id)); $i++) {
$formatted .= '0';
}
$formatted .= $order_id;
echo $formatted; // 00123
✓ 올바른 방법: str_pad() 사용
$order_id = 123;
$formatted = str_pad($order_id, 5, '0', STR_PAD_LEFT);
echo $formatted; // 00123
$order_id = 45678;
$formatted = str_pad($order_id, 5, '0', STR_PAD_LEFT);
echo $formatted; // 45678 (이미 5자리 이상이면 변화 없음)
한 줄로 깔끔하고 읽기 쉽다. 반복문이 전혀 필요 없다.
$amounts = [100, 5000, 250000, 42];
foreach ($amounts as $amount) {
echo str_pad($amount, 10, ' ', STR_PAD_LEFT) . ' 원' . "\n";
}
// 출력:
// 100 원
// 5000 원
// 250000 원
// 42 원
콘솔이나 텍스트 파일에서 숫자가 세로로 정렬된다.
$files = [];
for ($i = 1; $i <= 100; $i++) {
$filename = 'photo_' . str_pad($i, 3, '0', STR_PAD_LEFT) . '.jpg';
$files[] = $filename;
}
print_r(array_slice($files, 0, 5));
// Array
// (
// [0] => photo_001.jpg
// [1] => photo_002.jpg
// [2] => photo_003.jpg
// [3] => photo_004.jpg
// [4] => photo_005.jpg
// )
파일 탐색기에서 순서대로 정렬된다. 010, 020 같은 순서 오류가 없다.
✗ 잘못된 방법: STR_PAD_LEFT를 선택한 경우
$name = '김철수';
echo str_pad($name, 10, '.', STR_PAD_LEFT);
// 출력: .......김철수 (이름 앞에 점이 붙음)
✓ 올바른 방법: STR_PAD_RIGHT 사용
$name = '김철수';
echo str_pad($name, 10, '.', STR_PAD_RIGHT);
// 출력: 김철수....... (이름 뒤에 점이 붙음)
$names = ['이순신', '장보고', '세종'];
foreach ($names as $name) {
echo str_pad($name, 8, '-', STR_PAD_RIGHT) . ' : 역사 인물' . "\n";
}
// 이순신---- : 역사 인물
// 장보고--- : 역사 인물
// 세종----- : 역사 인물
$title = '공지사항';
echo str_pad($title, 20, '=', STR_PAD_BOTH);
// 출력: ======공지사항====== (양쪽에 추가)
$title = '회의록';
echo str_pad($title, 15, '*', STR_PAD_BOTH);
// 출력: ****회의록***** (양쪽 중앙 정렬)
// 실제 텍스트 리포트 생성 예
$report_title = '월간 판매 보고서';
echo "\n" . str_pad($report_title, 50, '-', STR_PAD_BOTH) . "\n\n";
echo "작성일: 2025-01-15\n";
echo "판매액: 50,000,000원\n";
✗ 잘못된 기대: str_pad()가 문자열을 자른다고 생각
$text = '안녕하세요반갑습니다';
$result = str_pad($text, 5, '*', STR_PAD_RIGHT);
echo $result;
// 출력: 안녕하세요반갑습니다 (길이 10이므로 변화 없음)
✓ 올바른 방법: substr()과 조합
$text = '안녕하세요반갑습니다';
$result = substr($text, 0, 5);
echo str_pad($result, 10, '*', STR_PAD_RIGHT);
// 출력: 안녕하세요***** (5자리로 자른 후 10자리로 패딩)
✗ 문제 상황: 한글이 예상보다 길게 인식됨
$name = '김철수'; // 한글 3글자
echo strlen($name); // 9 (UTF-8에서 한글은 1글자 = 3바이트)
$result = str_pad($name, 10, '*', STR_PAD_RIGHT);
echo $result;
// 출력: 김철수* (바이트 기준 10이므로 1글자만 추가됨)
✓ 올바른 방법: mb_strlen() 사용
$name = '김철수';
$char_length = mb_strlen($name, 'UTF-8'); // 3
$target_length = 10;
$pad_length = $target_length - $char_length; // 7
$result = $name . str_repeat('*', $pad_length);
echo $result;
// 출력: 김철수******* (글자 단위로 정확히 패딩)
// 또는 mb_str_pad() 함수 작성
function mb_str_pad($input, $length, $pad = ' ', $type = STR_PAD_RIGHT, $encoding = 'UTF-8') {
$input_length = mb_strlen($input, $encoding);
if ($length <= $input_length) {
return $input;
}
$pad_length = $length - $input_length;
$pad = mb_substr($pad, 0, 1, $encoding);
switch ($type) {
case STR_PAD_LEFT:
return str_repeat($pad, $pad_length) . $input;
case STR_PAD_BOTH:
$left = floor($pad_length / 2);
$right = $pad_length - $left;
return str_repeat($pad, $left) . $input . str_repeat($pad, $right);
default:
return $input . str_repeat($pad, $pad_length);
}
}
echo mb_str_pad('김철수', 10, '*', STR_PAD_RIGHT);
// 출력: 김철수******* (정확히 작동)
✗ 예상과 다른 동작: 패딩 문자 여러 글자
echo str_pad('123', 10, 'AB', STR_PAD_RIGHT);
// 출력: 123ABABABA (AB를 반복하되, 정확히 10자리가 되도록 자름)
// 기대값이 123AB이 아님
str_pad()는 패딩 문자가 여러 글자일 때 반복해서 채우되, 정확히 목표 길이가 되도록 마지막 문자를 자른다. 보통은 1글자 문자만 쓰는 것이 안전하다.
echo str_pad('123', -5, '0', STR_PAD_LEFT);
// 출력: 123 (음수는 무시되고 원본 그대로)
데이터베이스에서 조회한 주문 목록을 텍스트 보고서 형식으로 출력하는 상황을 예로 들어보자.
$orders = [
['id' => 1, 'name' => '이순신', 'amount' => 25000],
['id' => 42, 'name' => '세종', 'amount' => 150000],
['id' => 789, 'name' => '장보고', 'amount' => 8500],
];
echo "\n";
echo str_pad('주문번호', 10, ' ', STR_PAD_RIGHT);
echo str_pad('고객명', 15, ' ', STR_PAD_RIGHT);
echo str_pad('금액', 15, ' ', STR_PAD_LEFT);
echo "\n";
echo str_repeat('-', 40) . "\n";
foreach ($orders as $order) {
echo str_pad(
str_pad($order['id'], 5, '0', STR_PAD_LEFT),
10,
' ',
STR_PAD_RIGHT
);
echo str_pad($order['name'], 15, ' ', STR_PAD_RIGHT);
echo str_pad($order['amount'], 15, ' ', STR_PAD_LEFT);
echo "\n";
}
// 출력:
// 주문번호 고객명 금액
// ----------------------------------------
// 00001 이순신 25000
// 00042 세종 150000
// 00789 장보고 8500
이 코드는 주문번호를 5자리로 고정하고, 고객명은 왼쪽 정렬, 금액은 오른쪽 정렬하는 프로페셔널한 보고서를 만든다. str_pad()가 없었다면 각각 다른 로직이 필요했을 것이다.
| 함수 | 용도 | 예 |
|---|---|---|
| str_pad() | 지정된 길이로 맞추기 | str_pad('123', 5, '0', STR_PAD_LEFT) → '00123' |
| str_repeat() | 문자를 N번 반복 | str_repeat('*', 5) → '*****' |
| sprintf() | 형식화된 문자열 생성 | sprintf('%05d', 123) → '00123' |
| substr() | 문자열 자르기 | substr('hello', 0, 3) → 'hel' |
숫자 패딩만 필요하면 sprintf('%05d')가 더 간결할 수 있지만, 문자열 패딩이 필요하면 str_pad()가 필수다.