douhuang5331 2014-09-13 14:28
浏览 23
已采纳

在一个PHP脚本中通过电子邮件发送整个用户库? [关闭]

I'm wondering how do people handle emailing their userbase. I'm using PHP and SendGrid is handling the emails. The use case is a newsletter.

When I send myself 50 emails in testing the script already takes quite a long time and I worry that the application will time out if go for more emails at a time.

I don't really want to send myself 100, then 1,000, then 10,000 emails to see what the upper limit is testing this out.

I'm running this on a medium EC2 Linux if that is helpful.

  • 写回答

1条回答 默认 最新

  • doumaojin4008 2014-09-13 16:13
    关注

    There are several ways to accomplish this with SendGrid.

    Send Emails in Parallel

    It's likely that you're currently sending your emails in a series (i.e. send one email, wait for it to send, then send the next). This means if it takes you 1 second to send an email, it will take you 100 seconds to send one hundred.

    Luckily, PHP's cURL Library allows you to send many POST requests in parallel, rather than in a series.

    // An array of the emails you want to send to:
    $emails = array("joe@example.org", "sue@example.com");
    
    $credentials = array("api_user" => YOUR_SENDGRID_USERNAME, "api_key" => YOUR_SENDGRID_PASSWORD);
    
    $multi_handle = curl_multi_init();
    $handles = array();
    // Loop through each email and create a cURL Handle for the email
    // The cURL handle will POST an email to SendGrid with the proper info
    foreach ($emails as $key => $email) {
        // Create an email data object with your credentials in it,
        // we'll POST this to SendGrid
        $email_data = $credentials;
    
        // Fill out all the information you want for the email
        $email_data = array(
            "to" => $email,
            "from" => "you@example.net",
            "subject" => generate_subject(),
            "html" => generate_html(),
            "text" => generate_text()
        );
    
        $handles[$key] = curl_init();
        curl_setopt($handles[$key], CURLOPT_URL, "https://api.sendgrid.com/api/mail.send.json");
        curl_setopt($handles[$key], CURLOPT_POST, 1);
        curl_setopt($handles[$key], CURLOPT_POSTFIELDS, $email_data);
    
        curl_setopt($handles[$key], CURLOPT_RETURNTRANSFER, true);
        curl_multi_add_handle($multi_handle, $handles[$key]);
    }
    
    $running = null;
    // Run through each cURL handle and execute it.
    do {
        curl_multi_exec($multi_handle, $running);
    } while ($running);
    
    curl_multi_close($multi_handle);
    

    This method works well if you have lots of hyper-unique emails that you want to send, however it still results in a bunch of POST requests from your server, which are slow and resource consuming. There's often a better way.

    Send Emails Using the SMTPAPI

    SendGrid has an SMTPAPI which allows you to send up to 10,000 emails with one POST request using the to parameter. You can make these emails semi-unique by using substitution tags.

    For this you'd do something like the following:

    // An array of the emails you want to send to:
    $emails = array("joe@example.org", "sue@example.com");
    
    // Encode it into the SendGrid SMTPAPI Format
    $smtpapi = array( "to" =>  $emails );
    
    $params = array(
        "api_user"  => YOUR_SENDGRID_USERNAME,
        "api_key"   => YOUR_SENDGRID_PASSWORD,
        "to"        => "you@example.com",
        "subject"   => "testing from curl",
        "html"      => "testing body",
        "text"      => "testing body",
        "from"      => "you@example.com",
        "x-smtpapi" => json_encode($smtpapi);
      );
    
    
    $request =  "https://api.sendgrid.com/api/mail.send.json";
    
    // Generate curl request
    $session = curl_init($request);
    // Tell curl to use HTTP POST
    curl_setopt ($session, CURLOPT_POST, true);
    // Tell curl that this is the body of the POST
    curl_setopt ($session, CURLOPT_POSTFIELDS, $params);
    // Tell curl not to return headers, but do return the response
    curl_setopt($session, CURLOPT_HEADER, false);
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
    
    // obtain response
    $response = curl_exec($session);
    curl_close($session);
    

    However, it's probably better to do this with SendGrid's PHP Library

    $emails = array("joe@example.org", "sue@example.com");
    
    $sendgrid = new SendGrid(YOUR_SENDGRID_USERNAME, YOUR_SENDGRID_PASSWORD);
    $email    = new SendGrid\Email();
    $email->setTos($emails)->
           setFrom('me@bar.com')->
           setSubject('Subject goes here')->
           setText('Hello World!')->
           setHtml('<strong>Hello World!</strong>');
    
    $sendgrid->send($email);
    

    Queueing

    Finally, you could utilize a queue and send all the emails from a different process to speed up your execution time, information on how to do that is in this StackOverflow response.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 各位请问平行检验趋势图这样要怎么调整?说标准差差异太大了
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 wpf界面一直接收PLC给过来的信号,导致UI界面操作起来会卡顿
  • ¥15 init i2c:2 freq:100000[MAIXPY]: find ov2640[MAIXPY]: find ov sensor是main文件哪里有问题吗
  • ¥15 运动想象脑电信号数据集.vhdr
  • ¥15 三因素重复测量数据R语句编写,不存在交互作用
  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab