PHP에서 이메일 주소를 확인하는 방법


218

이메일 주소를 확인하는이 기능이 있습니다.

function validateEMAIL($EMAIL) {
    $v = "/[a-zA-Z0-9_-.+]+@[a-zA-Z0-9-]+.[a-zA-Z]+/";

    return (bool)preg_match($v, $EMAIL);
}

이메일 주소가 유효한지 확인해도됩니까?


1
작동하면 작동합니다. 당신은 정말로 더 나아질 수 없습니다. 너무 작습니다. 좋지 않은 것만이 스타일입니다. validateEmail통과 $email하지 않고 코레 트가 될 것 $EMAIL입니다.
Stan

코드에 큰 문제가 없는지 확인하고 싶었습니다.
Cameron

정규식을 사용하여 전자 메일 주소의 유효성을 검사하는 방법과 방법에 대한 자세한 내용은 stackoverflow.com/questions/201323/… 을 참조하십시오 .
legoscia

5
많은 유효한 이메일 주소를 확인하지 못할 것입니다. 예 : *@example.com 또는 '@example.com 또는 me @ [127.0.0.1] 또는 you @ [ipv6 : 08B0 : 1123 : AAAA :: 1234]
jcoder

7
@jcoder, 나는 그 정규 표현식을 권장하지는 않지만 적어도 우리는 노래 등을 위해 이러한 주소를 사용하는 사람이 실패 할 때 불평하지 않기를 바랄 수 있습니다 :)
Halil Özgür

답변:


569

이메일 주소가 올바른지 여부를 확인하는 가장 쉽고 안전한 방법은 다음 filter_var()기능 을 사용하는 것입니다.

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // invalid emailaddress
}

또한 도메인이 MX레코드를 정의하는지 여부를 확인할 수 있습니다 .

if (!checkdnsrr($domain, 'MX')) {
    // domain is not valid
}

그러나 이것은 여전히 ​​메일의 존재를 보장하지 않습니다. 이를 확인하는 유일한 방법은 확인 메일을 보내는 것입니다.


이제 빠른 답변을 얻었으므로 빠른 답변을 배우고 사용하고 계속 진행하려는 경우 이메일 주소 확인에 대해 자유롭게 읽으십시오. 유감 없음.

정규식을 사용하여 이메일 주소를 확인하는 것은 "불가능한"작업입니다. 나는 당신이 만든 정규식이 쓸모 없다고 말하기까지합니다. emailaddresses 및 잘못된 emailaddresses를 잡기 위해 정규식을 작성하는 3 가지 rfc가 있으며 동시에 잘못된 긍정이 없으면 필사자가 할 수없는 일입니다. PHP 함수에서 사용하는 정규식 테스트 (실패 및 성공)를 보려면이 목록 을 확인하십시오 filter_var().

내장 PHP 기능, 이메일 클라이언트 또는 서버조차도 제대로 작동하지 않습니다. 여전히 대부분의 경우 filter_var최선의 선택입니다.

이메일 주소의 유효성을 검사하기 위해 PHP가 현재 사용하는 정규식 패턴을 알고 싶다면 PHP 소스를 참조하십시오 .

이메일 주소에 대해 더 자세히 알고 싶다면 사양을 읽기 시작하는 것이 좋습니다. 그러나 모든 것이 쉽게 읽을 수는 없다고 경고해야합니다.

  • rfc5322
  • rfc5321
  • rfc3696
  • rfc6531 (유니 코드 문자를 허용하지만 많은 클라이언트 / 서버에서는이를 허용하지 않음)

참고 filter_var()로 이미 PHP 5.2으로 만 사용할 수 적혀있다. 이전 버전의 PHP에서 작동하려면 PHP에서 사용되는 정규식을 사용할 수 있습니다.

<?php

$pattern = '/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD';

$emailaddress = 'test@gmail.com';

if (preg_match($pattern, $emailaddress) === 1) {
    // emailaddress is valid
}

PS 위에서 사용한 정규식 패턴에 대한 참고 사항 (PHP 소스에서). Michael Rushton 의 저작권이있는 것 같습니다 . 명시된 바와 같이 : "이 코드를 자유롭게 사용하고 재배포하십시오. 그러나이 저작권 고지 사항을 유지하십시오."


좋은 대답이지만이 링크를 따라 : haacked.com/archive/2007/08/21/… 로컬 부분의 사용자 이름은 따옴표로 묶을 수 있지만 FILTER_VALIDATE_EMAIL 은이를 수락하지 않습니다.
Daniel De León

3
명시된 모든 이메일 주소 에는 적용되지 않습니다 . 또한 내 대답에 실패한 테스트 목록을 참조하여 인용 된 일부 문자열이 작동하고 다른 문자열은 작동하지 않는지 확인하십시오.
PeeHaa

4
아니요, 해당 패턴에 대한 테스트가 너무 많이 실패했습니다. emailtester.pieterhordijk.com/test-pattern/MTAz :-)
PeeHaa

1
이 패턴은 전자 메일이 포함 된 큰 텍스트 문자열에서 "preg_match_all"과 같은 함수와 함께 사용해야하는 경우 매우 복잡합니다. 더 간단한 사람이 있으면 공유하십시오. 당신이 원한다면 의미 : preg_match_all ($ pattern, $ text_string, $ matches); 이 복잡한 패턴은 실제로 큰 텍스트를 구문 분석해야 할 경우 서버에 과부하가 걸립니다.
Vlado

4
@PeeHaa : Postfix 3.0은 현재 거의 2 년 동안 postfix.org/SMTPUTF8_README.html 을 지원하며 Ubuntu 16.04에 포함되어 있으며 다음 데비안 릴리스에 포함될 것입니다. Exim은 실험적인 지원을 제공합니다. 아직 유니 코드 계정을 만들 수는 없지만 Gmail과 같은 웹 메일 제공 업체는 이러한 이메일 전송 / 수신 지원을 추가했습니다. 광범위한 사용 및 지원이 가능하며 filter_var지금 당장 변경하더라도 상당히 시간이 지체됩니다 (버그 보고서를 게시했습니다).
이키 토

43

이를 위해 filter_var 를 사용할 수 있습니다 .

<?php
   function validateEmail($email) {
      return filter_var($email, FILTER_VALIDATE_EMAIL);
   }
?>

1
도메인의 유효성을 검사하지 않으므로이 기능 추가를 중지하십시오. some @ address를 추가하는 경우 유효합니다. 그리고 그렇지 않습니다!
Herr Nentu의

한 줄 함수를 포함하는 모든 한 줄 함수에는 어떤 것이 있습니까? 나는 그들을 도처에보고있다. 이것이 언제 "일"이 되었습니까? (수사적). 중지해야합니다.
Blue Water

15

내 경험에 따르면 regex솔루션에는 오 탐지가 너무 많고 filter_var()솔루션에는 오 탐지가 있습니다 (특히 모든 최신 TLD에서 ).

대신, 주소에 이메일 주소의 모든 필수 부분 (사용자, "@"기호 및 도메인)이 있는지 확인한 다음 도메인 자체가 존재하는지 확인하는 것이 좋습니다.

전자 메일 사용자가 외부 도메인에 있는지 확인하는 방법 (서버 측)은 없습니다.

이것은 유틸리티 클래스에서 만든 방법입니다.

public static function validateEmail($email)
{
    // SET INITIAL RETURN VARIABLES

        $emailIsValid = FALSE;

    // MAKE SURE AN EMPTY STRING WASN'T PASSED

        if (!empty($email))
        {
            // GET EMAIL PARTS

                $domain = ltrim(stristr($email, '@'), '@') . '.';
                $user   = stristr($email, '@', TRUE);

            // VALIDATE EMAIL ADDRESS

                if
                (
                    !empty($user) &&
                    !empty($domain) &&
                    checkdnsrr($domain)
                )
                {$emailIsValid = TRUE;}
        }

    // RETURN RESULT

        return $emailIsValid;
}

네버 바운스는 그들의 API가 97 % 전달까지 검증 할 수 있다고 주장한다. 물론 연락처 데이터베이스를 넘겨주지 않는 한.
Tom Russell

stristr@ 기호가 여러 개 있으면 도메인을 가져 오지 못합니다. 더 나은 explode('@',$email)확인sizeof($array)==2
Aaron Gillion

@AaronGillion 도메인 부분을 얻는 더 좋은 방법은 정확하지만 도메인 checkdnsrr()에 @ 기호가 있으면 false를 반환하는 것처럼 이 메서드는 여전히 false를 반환합니다.
Jabari

11

PHP의 내장 필터를 사용하는 것이 좋습니다. .이 특별한 경우 :

FILTER_VALIDATE_EMAILparam 과 함께 제공되면 true 또는 false를 반환 할 수 있습니다 .


9

이렇게하면 전자 메일의 유효성이 검사 될뿐만 아니라 예기치 않은 문자에 대해 전자 메일이 삭제됩니다.

$email  = $_POST['email'];
$emailB = filter_var($email, FILTER_SANITIZE_EMAIL);

if (filter_var($emailB, FILTER_VALIDATE_EMAIL) === false ||
    $emailB != $email
) {
    echo "This email adress isn't valid!";
    exit(0);
}

4

이메일 확인에 대한 '상단 질문'에서 이에 답변했습니다 https://stackoverflow.com/a/41129750/1848217

나에게 이메일을 확인하는 올바른 방법은 다음과 같습니다.

  1. @ 기호가 있는지 확인하고 그 앞뒤에 @ 이외의 기호가 있는지 확인하십시오. /^[^@]+@[^@]+$/
  2. "활성화 코드"와 함께이 주소로 이메일을 보내십시오.
  3. 사용자가 자신의 이메일 주소를 "활성화"하면 모든 것이 올바른 것입니다.

물론 사용자가 "이상한"이메일을 입력 할 때 프런트 엔드에 경고 나 툴팁을 표시하여 도메인 부분에 점이나 인용 부호없이 공백이없는 것과 같은 일반적인 실수를 피할 수 있습니다. 그러나 사용자가 정말로 원한다면 "hello @ world"주소를 수락해야합니다.

또한 전자 메일 주소 표준은 진화 했으므로 진화 할 수 있으므로 "표준 유효"정규 표현식을 한 번만 입력 할 수는 없습니다. 또한 일부 구체적인 인터넷 서버는 공통 표준에 대한 일부 세부 사항에 실패하고 실제로는 "수정 된 표준"으로 작동 할 수 있음을 기억해야합니다.

따라서 @를 확인하고 프런트 엔드에서 사용자에게 힌트를주고 주어진 주소로 확인 이메일을 보냅니다.


1
정규식은을 확인 @하지만 실제로 전자 메일을 관리하는 RFC마다 유효한지 확인하지는 않습니다. 또한 서면으로 작동하지 않습니다. 나는 regex101.com을 통해 그것을 실행하고 유효한 주소와 일치하지 못했습니다
Machavity

정규식이나 전체 답변 만 읽으십니까? 완전히 동의하지 않습니다. gmail.com 서버가 joe@gmail.com과 jo.e@gmail.com이 동일한 주소라고 가정하는 RFC에 따르면, 제발 말해주세요. 표준이 아닌 FRESH 표준이 아닌 서버가 많이 있습니다. 그러나 thay는 사용자의 이메일을 제공합니다. 정규 표현식을 한 번 입력하고 그에 의해서만 유효성을 검사하는 경우 앞으로 올바르게 유지 될 것이라고 보장 할 수 없으며 향후 사용자가 "새로운 방법"이메일로 실패하지 않을 것입니다. 따라서 제 위치는 동일합니다. 이메일 주소를 확인하려는 경우 요점은 활성화 이메일을 보내면됩니다.
FlameStorm

@Machavity 그러나 regexp의 버그 리포트에 감사드립니다./^[^@]+@[^@+]$//^[^@]+@[^@]+$/
FlameStorm

정규식을 수정하는 데 도움이되지만 방법이 어떻게 향상 filter_var됩니까? 형식이 잘못된 주소를 받아들이는 문제는 해결되지 않습니다. 정규식은 joe@domain유효하지 않은 경우에 유효한 이메일 주소로 기꺼이 받아 들일 것입니다.
Machavity

예를 들어 @Machavity는 서버에 구체적인 버전의 PHP가 있으며 최신 버전으로 업데이트 할 수 없습니다. 예를 들어 php 5.5.15 있습니다. 2018 년에 유효한 이메일 표준이 확장되었습니다. PHP 7.3.10에서 곧 실현 될 것입니다. 그리고 잘 작동하는 기능이 filter_var($email, FILTER_VALIDATE_EMAIL, $newOptions)있습니다. 그러나 서버에 오래된 기능이 있으며 경우에 따라 업데이트 할 수 없습니다. 그리고 당신은 몇 가지 새로운 유효한 이메일로 고객을 잃게됩니다. 또한, 모든 이메일 서비스 서버가 일반적이고 현대적인 이메일 주소 표준에 따라 엄격하게 작동하는 것은 아닙니다.
FlameStorm

3

당신이 있는지 확인하려면 이메일 주소에서 제공하는 도메인이 유효 사용 뭔가 같은 :

/*
* Check for valid MX record for given email domain
*/
if(!function_exists('check_email_domain')){
    function check_email_domain($email) {
        //Get host name from email and check if it is valid
        $email_host = explode("@", $email);     
        //Add a dot to the end of the host name to make a fully qualified domain name and get last array element because an escaped @ is allowed in the local part (RFC 5322)
        $host = end($email_host) . "."; 
        //Convert to ascii (http://us.php.net/manual/en/function.idn-to-ascii.php)
        return checkdnsrr(idn_to_ascii($host), "MX"); //(bool)       
    }
}

유효한 이메일 형식 이 유효한 이메일을 의미하지 않기 때문에 표준 이메일 유효성 검사와 함께 많은 유효하지 않은 이메일 주소를 필터링하는 편리한 방법입니다. 입니다.

그 주 idn_to_ascii()(또는 그의 여동생 기능 idn_to_utf8()) 기능을 하지 않을 수 있습니다 당신의 PHP 설치에서 사용할 수있는, 그것은 확장을 필요로 PECL의 국제> = 1.0.2 및 PECL IDN> = 0.1.

또한 이메일의 도메인 부분 (예 :)으로 IPv4 또는 IPv6은 user@[IPv6:2001:db8::1]검증 할 수 없으며 이름지정됩니다. 호스트 할 수 있습니다.

자세한 내용은 여기를 참조 하십시오 .


이메일 주소의 호스트 부분이 IPv6 형식의 IP 주소 인 경우 작동하지 않을 것입니다.
GordonM

2

여기에서 답변을 읽은 후에 이것이 내가 끝낸 것입니다.

public static function isValidEmail(string $email) : bool
{
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        return false;
    }

    //Get host name from email and check if it is valid
    $email_host = array_slice(explode("@", $email), -1)[0];

    // Check if valid IP (v4 or v6). If it is we can't do a DNS lookup
    if (!filter_var($email_host,FILTER_VALIDATE_IP, [
        'flags' => FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE,
    ])) {
        //Add a dot to the end of the host name to make a fully qualified domain name
        // and get last array element because an escaped @ is allowed in the local part (RFC 5322)
        // Then convert to ascii (http://us.php.net/manual/en/function.idn-to-ascii.php)
        $email_host = idn_to_ascii($email_host.'.');

        //Check for MX pointers in DNS (if there are no MX pointers the domain cannot receive emails)
        if (!checkdnsrr($email_host, "MX")) {
            return false;
        }
    }

    return true;
}

1

다양한 점, 밑줄 및 대시를 허용하는 실제 정규식을 찾고 있다면 다음과 같습니다 [a-zA-z0-9.-]+\@[a-zA-z0-9.-]+.[a-zA-Z]+.. 그렇게하면 상당히 어리석은 이메일 tom_anderson.1-neo@my-mail_matrix.com을 확인할 수 있습니다.


0
/(?![[:alnum:]]|@|-|_|\.)./

요즘 HTML5 양식을 사용하는 경우 type=email브라우저 엔진에는 자체 유효성 검사기가 있으므로 이미 80 % 안전합니다. 그것을 보완하려면이 정규식을 추가 preg_match_all()하고 부정하십시오.

if (!preg_match_all("/(?![[:alnum:]]|@|-|_|\.)./",$email)) { .. }

유효성 검사를 위해 HTML5 양식에 사용되는 정규식을 찾으십시오.
https://regex101.com/r/mPEKmy/1


나는 설명없이 다운 투표를 싫어한다. 글쎄, 그는 말할 것입니다 : 브라우저 이메일 확인 (클라이언트 측)은 전혀 안전하지 않습니다. 누구나 코드를 변경하여 서버로 무엇이든 보낼 수 있습니다. 따라서 서버 측을 다시 검사하는 가장 분명하고 안전한 방법입니다. 여기서 질문은 PHP를 기반으로하므로 명백한 Cameron은 클라이언트 솔루션이 아닌 서버 솔루션을 찾고있었습니다.
Jonny

이 답변은 PHP와 완전히 관련이 없을 수도 있지만 HTML 제안은 전화 / PC 만 사용하는 "표준"사용자를 포함합니다. 또한 사용자는 사이트를 사용하는 동안 "자신의"브라우저에서 직접 정보를 얻습니다. 서버 측의 실제 점검은 여기에서 다루지 않습니다. Btw, @Thielicious는 PHP 변경을 언급 했으므로 그의 의견은 IMHO와 관련이 있습니다.
k00ni 2019

"브라우저 엔진에는 자체 유효성 검사기가 있으므로 80 % 안전"이라는 가정하에 투표 결과가 떨어졌습니다. 브라우저를 통하는 것보다 http 요청을 보내는 다른 많은 방법이 있으므로 브라우저 에이전트를 확인하더라도 요청이 안전하다고 가정 할 수 없습니다.
Jabari
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.