PHP 메일 발송 스팸 처리 문제와 해결책

프리터코더·2025년 7월 3일

php 문제 해결

목록 보기
76/79

PHP 메일 발송 스팸 처리 문제와 해결책

PHP로 메일을 발송할 때 스팸으로 분류되거나 발송이 실패하는 문제가 자주 발생합니다. 이런 문제들의 주요 원인과 해결책을 살펴보겠습니다.

1. 발신자 정보 누락으로 스팸 처리

문제: From 헤더가 없거나 잘못 설정되어 스팸으로 분류

해결책:

$headers = "From: noreply@yourdomain.com\r\n";
$headers .= "Reply-To: support@yourdomain.com\r\n";
$headers .= "Return-Path: noreply@yourdomain.com\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();

mail($to, $subject, $message, $headers);

2. HTML 메일이 스팸으로 분류

문제: HTML 형식 메일이 제대로 인식되지 않아 스팸 처리

해결책:

$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
$headers .= "From: sender@yourdomain.com\r\n";

$htmlMessage = "
<html>
<head><title>제목</title></head>
<body>
<p>안녕하세요!</p>
</body>
</html>";

mail($to, $subject, $htmlMessage, $headers);

3. 대량 발송으로 인한 차단

문제: 한 번에 많은 메일을 발송하여 서버에서 차단

해결책:

// 배치 발송으로 처리
$emails = ['user1@email.com', 'user2@email.com', 'user3@email.com'];
$batchSize = 10;

foreach (array_chunk($emails, $batchSize) as $batch) {
    foreach ($batch as $email) {
        mail($email, $subject, $message, $headers);
        sleep(1); // 1초 대기
    }
    sleep(5); // 배치 간 5초 대기
}

4. SPF/DKIM 설정 누락

문제: 도메인 인증 설정이 없어 스팸으로 분류

해결책:

// PHPMailer 라이브러리 사용 (DKIM 서명 지원)
use PHPMailer\PHPMailer\PHPMailer;

$mail = new PHPMailer();
$mail->isSMTP();
$mail->Host = 'smtp.yourdomain.com';
$mail->SMTPAuth = true;
$mail->Username = 'your-email@yourdomain.com';
$mail->Password = 'your-password';

// DKIM 설정
$mail->DKIM_domain = 'yourdomain.com';
$mail->DKIM_private = '/path/to/private.key';
$mail->DKIM_selector = 'phpmailer';

$mail->send();

5. 수신거부 링크 누락

문제: 수신거부 옵션이 없어 스팸으로 신고됨

해결책:

$unsubscribeLink = "https://yourdomain.com/unsubscribe.php?token=" . md5($email);

$message = "
메일 내용...

---
수신거부: {$unsubscribeLink}
";

$headers .= "List-Unsubscribe: <{$unsubscribeLink}>\r\n";
mail($to, $subject, $message, $headers);

6. 메일 발송 빈도 제한

문제: 동일 사용자에게 너무 자주 메일 발송하여 스팸 처리

해결책:

// 발송 이력 체크
function canSendEmail($email, $type = 'general') {
    $lastSent = getLastSentTime($email, $type); // DB에서 조회
    $minInterval = 3600; // 1시간
    
    return (time() - $lastSent) > $minInterval;
}

if (canSendEmail($email, 'newsletter')) {
    mail($email, $subject, $message, $headers);
    updateLastSentTime($email, 'newsletter'); // DB 업데이트
}

7. 이메일 주소 검증 누락

문제: 잘못된 이메일로 발송하여 반송률 증가

해결책:

function isValidEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

function isDomainValid($email) {
    $domain = substr(strrchr($email, "@"), 1);
    return checkdnsrr($domain, 'MX');
}

if (isValidEmail($email) && isDomainValid($email)) {
    mail($email, $subject, $message, $headers);
}

8. 플레인 텍스트와 HTML 혼합 발송

문제: 일부 메일 클라이언트에서 제대로 표시되지 않음

해결책:

$boundary = uniqid('boundary_');

$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/alternative; boundary=\"{$boundary}\"\r\n";
$headers .= "From: sender@yourdomain.com\r\n";

$message = "
--{$boundary}
Content-Type: text/plain; charset=UTF-8

플레인 텍스트 버전

--{$boundary}
Content-Type: text/html; charset=UTF-8

<html><body><p>HTML 버전</p></body></html>

--{$boundary}--";

mail($to, $subject, $message, $headers);

9. 메일 전송 실패 처리

문제: 발송 실패 시 재시도 로직 없음

해결책:

function sendEmailWithRetry($to, $subject, $message, $headers, $maxRetries = 3) {
    for ($i = 0; $i < $maxRetries; $i++) {
        if (mail($to, $subject, $message, $headers)) {
            return true;
        }
        sleep(pow(2, $i)); // 지수 백오프
    }
    
    // 실패 로그 기록
    error_log("메일 발송 실패: {$to}");
    return false;
}
profile
일용직 개발자. freetercoder@gmail.com

0개의 댓글