การตรวจสอบว่าที่อยู่อีเมลนั้นถูกต้องใน PHP นั้นง่ายแค่ไหน? [ทำซ้ำ]

เมื่อได้รับที่อยู่อีเมลแล้ว ฉันจะตรวจสอบได้อย่างไรว่าถูกต้อง (ว่าโดเมนของอีเมลจะยอมรับอีเมลสำหรับที่อยู่นั้น)

สิ่งนี้จะมีลักษณะอย่างไรใน PHP?

หมายเหตุ: ฉันไม่ต้องการยืนยันว่าที่อยู่อีเมล ตัวมันเอง นั้นถูกต้องตามหลักไวยากรณ์ ฉันต้องการทราบว่าโดเมนจะยอมรับอีเมลที่ส่งไปยังที่อยู่นั้นหรือไม่

ฉันคิดว่ามีวิธีการทำเช่นนี้กับระเบียน MX หรืออะไรสักอย่าง...


person Nathan Osman    schedule 15.05.2010    source แหล่งที่มา
comment
ระเบียน MX จะบอกตำแหน่งของเมลเซิร์ฟเวอร์ .. ไม่ใช่ของผู้ใช้/ที่อยู่แต่ละราย   -  person Tyler Carter    schedule 15.05.2010
comment
ตกลง. ฉันไม่ค่อยรู้เรื่องนี้มากนัก... ดังนั้นคำถามของฉัน   -  person Nathan Osman    schedule 15.05.2010


คำตอบ (7)


ฉันคิดว่าตัวเลือกเดียวของคุณคือคำสั่ง SMTP RCPT TO หรือ VRFY

RCPT TO อาจเป็นวิธีตรวจสอบ ตราบใดที่คุณยกเลิกการเชื่อมต่อหลังจากออกแล้ว อย่างไรก็ตาม ไม่ใช่ทุกเซิร์ฟเวอร์ที่จะบู๊ตคุณหากไม่มีบัญชี (การป้องกัน uce ที่อยู่ที่รับทั้งหมด ฯลฯ...)

VRFY สามารถบอกคุณได้ว่ามีบัญชีอยู่บนเซิร์ฟเวอร์นั้นหรือไม่ แต่การดำเนินการนี้จะถูกปิดใช้งานเกือบทุกครั้งเพื่อป้องกันการตรวจสอบบัญชี

คลาส PHP ที่ทำการตรวจสอบ RCPT TO (นอกเหนือจากวิธีอื่น ๆ ) คือ: http://code.google.com/p/php-smtp-email-validation/

person morbidcoder    schedule 15.05.2010
comment
ขอบคุณ! นี่คือสิ่งที่ฉันกำลังมองหามากกว่า - person Nathan Osman; 15.05.2010

เนื่องจากคุณระบุโดยเฉพาะ

ว่าโดเมนของอีเมลจะยอมรับอีเมลสำหรับที่อยู่นั้น

ไม่มีนิพจน์ทั่วไปจะช่วยคุณได้ วิธีเดียวที่จะตรวจสอบได้คือพยายามส่งอีเมลไปยังที่อยู่นั้นและดูว่ามีการตีกลับหรือไม่ ถึงกระนั้น คุณอาจได้รับผลบวกลวง เนื่องจากเมลเซิร์ฟเวอร์อาจไม่ส่งการแจ้งเตือนความล้มเหลว

การส่งอีเมลพื้นฐานเช่นนี้ด้วย PHP นั้นค่อนข้างง่าย ตรวจสอบเอกสารประกอบสำหรับฟังก์ชัน mail() ที่นี่

person Syntactic    schedule 15.05.2010
comment
ฉันไม่ต้องการนิพจน์ทั่วไปจริงๆ (ฉันไม่เคยพูดถึงมันเลย) ดังนั้นสิ่งที่คุณกำลังพูดคือตรวจสอบค่าส่งคืนของ mail() เพื่อดูว่าข้อความได้รับการยอมรับสำหรับการจัดส่งหรือไม่ - person Nathan Osman; 15.05.2010
comment
ฉันรู้วิธีส่งอีเมลด้วย mail() ฉันต้องการทราบวิธีการยืนยันที่อยู่ - person Nathan Osman; 15.05.2010
comment
ใช่ ความคิดเห็นของฉันเกี่ยวกับนิพจน์ทั่วไปเป็นการตอบสนองต่อคำตอบอื่นมากกว่าคำถามของคุณ ค่าที่ส่งคืนเป็น mail() จะบอกคุณว่าการจัดส่งสำเร็จหรือไม่ในขณะนี้ แต่ในทางปฏิบัติ นี่อาจไม่ใช่ข้อบ่งชี้ที่ดีนักว่าที่อยู่อีเมลนั้นมีอยู่จริงหรือไม่ น่าเสียดายที่ลักษณะการทำงานของอีเมลทำให้งานนี้เป็นเรื่องยาก - person Syntactic; 15.05.2010
comment
ฉันรู้. ฉันเดาว่าค่าตอบแทนนั้นดีพอสำหรับตอนนี้ อาจเป็นอีกทางเลือกเดียวเท่านั้นคือบีคอนหรืออะไรสักอย่าง - person Nathan Osman; 15.05.2010

คุณไม่สามารถตรวจสอบได้จริงว่าเซิร์ฟเวอร์จะยอมรับหรือไม่ เมลเซิร์ฟเวอร์ไม่มี API ที่จะจัดการสิ่งนั้น

เคยมีสคริปต์ที่พยายามเชื่อมต่อกับเซิร์ฟเวอร์ MX และมองหาการตอบสนองจากเซิร์ฟเวอร์ที่ระบุว่าต้องการรหัสผ่าน แทนที่จะปฏิเสธเพียงว่าเป็นกล่องจดหมายที่ไม่ได้ใช้งาน อย่างไรก็ตาม นี่เป็นการปฏิบัติที่แย่มาก

สิ่งเดียวที่คุณสามารถทำได้คือตรวจสอบที่อยู่อีเมลที่ถูกต้อง และหวังว่าจะได้ผลดีที่สุด:

http://www.linuxjournal.com/article/9585

นั่นเป็นหนึ่งในบทช่วยสอนที่เป็นไปตามมาตรฐานใน RFC

/**
Validate an email address.
Provide email address (raw input)
Returns true if the email address has the email 
address format and the domain exists.
*/
function validEmail($email)
{
   $isValid = true;
   $atIndex = strrpos($email, "@");
   if (is_bool($atIndex) && !$atIndex)
   {
      $isValid = false;
   }
   else
   {
      $domain = substr($email, $atIndex+1);
      $local = substr($email, 0, $atIndex);
      $localLen = strlen($local);
      $domainLen = strlen($domain);
      if ($localLen < 1 || $localLen > 64)
      {
         // local part length exceeded
         $isValid = false;
      }
      else if ($domainLen < 1 || $domainLen > 255)
      {
         // domain part length exceeded
         $isValid = false;
      }
      else if ($local[0] == '.' || $local[$localLen-1] == '.')
      {
         // local part starts or ends with '.'
         $isValid = false;
      }
      else if (preg_match('/\\.\\./', $local))
      {
         // local part has two consecutive dots
         $isValid = false;
      }
      else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain))
      {
         // character not valid in domain part
         $isValid = false;
      }
      else if (preg_match('/\\.\\./', $domain))
      {
         // domain part has two consecutive dots
         $isValid = false;
      }
      else if
(!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/',
                 str_replace("\\\\","",$local)))
      {
         // character not valid in local part unless 
         // local part is quoted
         if (!preg_match('/^"(\\\\"|[^"])+"$/',
             str_replace("\\\\","",$local)))
         {
            $isValid = false;
         }
      }
      if ($isValid && !(checkdnsrr($domain,"MX") || 
 ↪checkdnsrr($domain,"A")))
      {
         // domain not found in DNS
         $isValid = false;
      }
   }
   return $isValid;
}

เพื่อให้แน่ใจว่าสามารถส่งอีเมลได้ การตรวจสอบความถูกต้องจะดีพอๆ กับที่คุณจะได้รับ

person Tyler Carter    schedule 15.05.2010
comment
ไม่ไม่. ฉันไม่ต้องการ ตรวจสอบ ที่อยู่อีเมล ฉันต้องการ ยืนยัน ที่อยู่อีเมล (ตรวจสอบให้แน่ใจว่าโดเมนจะยอมรับอีเมลที่ส่งถึงโดเมนนั้น) - person Nathan Osman; 15.05.2010
comment
ฉันไม่แน่ใจว่านี่คือสิ่งที่ OP ถาม ฉันรู้สึกว่าคำถามเกี่ยวกับการตรวจสอบว่าเซิร์ฟเวอร์จะรับอีเมลตามที่อยู่ที่ให้ไว้หรือไม่ แม้ว่าจะต้องมีการชี้แจงก็ตาม - person Jakub Hampl; 15.05.2010
comment
ฉันทวนคำถามอีกครั้ง - person Nathan Osman; 15.05.2010
comment
@George และคำตอบของฉันยังคงใช้ได้ :) - person Tyler Carter; 15.05.2010
comment
แน่นอน ฉันสามารถตรวจสอบได้ตลอดเวลาว่าการจัดส่งสำเร็จหรือไม่ (เหมือนเซิร์ฟเวอร์ยอมรับข้อความ) - person Nathan Osman; 15.05.2010

การตรวจสอบว่าที่อยู่อีเมลนั้นถูกต้องนั้นง่ายแค่ไหน?

ไม่ใช่เรื่องง่ายเลย ดูที่ การตรวจสอบอีเมลของ Dominic Sayers ใน PHP ซึ่งอาจเป็นไลบรารีการตรวจสอบอีเมลที่สมบูรณ์แบบที่สุดในทุกภาษา รวมถึงการตรวจสอบ DNS ด้วย

ดูเพิ่มเติมที่ บทความที่เกี่ยวข้องนี้จาก Jeff Atwood เกี่ยวกับการตรวจสอบที่จำเป็นเพื่อรับประกันการมาถึงของอีเมล

person Mauricio Scheffer    schedule 15.05.2010
comment
คุณช่วยชี้ให้ฉันดูส่วนที่เกี่ยวข้องที่ตรวจสอบ DNS ได้ไหม ฉันหามันไม่เจอ - person Nathan Osman; 15.05.2010
comment
@George Edison: ค้นหา 'checkDNS' ในหน้าซึ่งฝังอยู่ในความคิดเห็น - person Mauricio Scheffer; 15.05.2010

อีเมลที่ถูกต้อง (ทางไวยากรณ์) นั้นไม่เหมือนกับการรับอีเมล ในการตรวจสอบว่าโดเมนจะยอมรับอีเมลหรือไม่ คุณต้องลองส่งอีเมลโดยตรงไปยัง MX แต่ถึงอย่างนั้น หากเซิร์ฟเวอร์ SMTP ยอมรับ คุณจะไม่รับประกันว่าจะไม่ถูกปฏิเสธในภายหลัง เช่น รายงานการไม่จัดส่งจะถูกส่งไป และเซิร์ฟเวอร์ SMTP อาจจะปฏิเสธอีเมลของคุณหากคุณอยู่ในกลุ่มที่อยู่แบบไดนามิกหรือไม่มีการย้อนกลับ DNS

person Artefacto    schedule 15.05.2010

แค่คิดว่าฉันจะพูดถึงว่า PHP มีฟังก์ชันในตัว getmxrr() ที่ดึงข้อมูลระเบียน MX จากโดเมน

สิ่งนี้มีประโยชน์อย่างไร ฉันไม่รู้... บนหน้าเว็บระบุว่า:

ไม่ควรใช้ฟังก์ชันนี้เพื่อวัตถุประสงค์ในการตรวจสอบที่อยู่

ดังนั้นการใช้งานจึงจำกัดอยู่เพียงการยืนยันว่าโดเมนมีเมลเซิร์ฟเวอร์ด้วย

person Nathan Osman    schedule 15.05.2010

หากคุณใช้ PHP 5.2.x ขณะนี้ไม่จำเป็นต้องใช้ฟังก์ชันการตรวจสอบความถูกต้องแบบกำหนดเอง PHP มาพร้อมกับฟังก์ชัน ในตัว

person Gabriel Sosa    schedule 15.05.2010
comment
โปรดอ่านคำถาม - นี่ไม่ใช่สิ่งที่ฉันกำลังมองหา - person Nathan Osman; 15.05.2010