编辑:添加DB :: connection() - > reconnect();从会话中检索电子邮件后的发送方法,缓解了问题。因此,似乎数据库正在断开连接,或者存在太多连接或其他内容。
我相信我有一个问题,MySQL在生产服务器上断开连接。服务器匹配我的本地开发设置(使用Homestead 2),并且是Ubuntu,MySQL,Nginx和PHP-FPM。
我使用的是Laravel 4.2,我创建了与Mailchimp广告系列接口的功能,创建了静态细分,并根据过滤后的条件向该细分添加电子邮件以发送电子邮件。
我最初在模型上运行whereIn()方法来检索与电子邮件数组匹配的联系人集合,大约2600封电子邮件传递给whereIn()作为值。
在我的生产服务器上,我一直收到错误(在本地开发设置上完美运行):
Error while sending STMT_PREPARE packet. PID=20615
所以,在我的研究中,我发现它可能与服务器的MySQL配置中的max_allowed_packet有关,所以我修改了my.cnf并将值增加到256M(在我的本地开发机器上的值是16M并且足够了)。这对错误没有影响。
我决定继续而不是使用whereIn(),作为测试构建一个新的集合逐个添加每个联系人但不幸的是我仍然收到相同的错误,即使使用1封电子邮件。这是在此实例中失败的查询:
select * from `contacts` where `contacts`.`deleted_at` is null and `email` = joebloggs@example.com limit 1
所以这清楚地指出了我的生产服务器上的某种错误配置,即使我确保我的本地环境和生产MySQL配置完全匹配。
因此,总而言之,我的本地环境工作正常并且执行代码没有问题,但生产服务器返回数据包错误。
我现在对如何继续有点不知所措。有人可以帮忙吗?
以下是我用来检索记录的代码:
// send() method to filter results based on a set of search fields, probably should rename this to filter
public function send($id)
{
$campaign = $this->getSavedCampaign($id);
$haveAttended = explode(',', Input::get('have_attended'));
$haveNotAttended = explode(',', Input::get('have_not_attended'));
$account = explode(',', Input::get('account'));
$companyName = explode(',', Input::get('company_name'));
$industryType = explode(',', Input::get('industry_type'));
$accountManager = explode(',', Input::get('account_manager'));
$jobTitle = explode(',', Input::get('job_title'));
$contactEmail = explode(',', Input::get('contact_email'));
// Check if there has been a POST request and if so get the filtered contact emails and add them to the session
if (Request::method() == 'POST')
{
// Retrieve an array of contact emails based on the filters supplied
$contactEmails = $this->contact->getContactEmails($haveAttended, $haveNotAttended, $account, $companyName, $industryType, $accountManager, $jobTitle, $contactEmail)->lists('email');
// Create a new Mailchimp static segment and return its ID
$segmentId = $this->createNewSegment(MailchimpWrapper::lists()->staticSegments('123456789'), $id);
// Add the emails array generated above to the static segment in Mailchimp
$this->addContactEmailsToSegment($contactEmails, $segmentId);
// Retrieve all the emails that matched a subscriber in Mailchimp that were added to the static segment
$emails = $this->getSegmentEmails(Config::get('mailchimp::apikey'), '123456789', 'subscribed', $segmentId);
// Put the emails array and the segment id in to the session
Session::put('emails', $emails);
Session::put('segmentId', $segmentId);
}
// Check if the session contains an array of emails and if so retrieve them and pull back an eloquent collection of contacts that match the emails stored in the session
if (Session::get('emails'))
{
$emails = Session::get('emails');
// EDIT: If I add DB::connection()->reconnect(); here this allieviates the issue
$contacts = $this->contact->getContactEmails($haveAttended, $haveNotAttended, $account, $companyName, $industryType, $accountManager, $jobTitle, $contactEmail, $emails)->paginate(10)->appends([
'have_attended' => Input::get('have_attended'),
'have_not_attended' => Input::get('have_not_attended'),
'account' => Input::get('account'),
'industry_type' => Input::get('industry_type'),
'account_manager' => Input::get('account_manager'),
'job_title' => Input::get('job_title'),
'contact_email' => Input::get('contact_email')
]);
}
$this->layout->content = View::make('admin.newsletters.send', compact('campaign', 'contacts'))->withErrors($this->errors);
}
这是我检索Mailchimp广告系列的方式:
// getSavedCampaign() method which retrieves the Mailchimp campaign we will be attaching the filtered segment to
public function getSavedCampaign($id)
{
$campaign = (object) MailchimpWrapper::campaigns()->getList(['campaign_id' => $id], 0, 1)['data'][0];
$campaign->create_time = new Carbon($campaign->create_time);
$campaign->send_time = new Carbon($campaign->send_time);
$campaign->content_updated_time = new Carbon($campaign->content_updated_time);
return $campaign;
}
这是我根据过滤结果检索联系人表格中的联系人/联系人电子邮件的方式:
public function scopeGetContactEmails($query, $haveAttended, $haveNotAttended, $account, $companyName, $industryType, $accountManager, $jobTitle, $contactEmail, $emails = null)
{
// If the emails session variable exists (is not null) simply run a whereIn query on the contacts table to retrieve all contacts that match an email in the array, otherwise run the filters
if ( ! is_null($emails))
{
$query->whereIn('email', $emails);
}
else
{
$query->orderBy('email', 'asc')
->where('contactable', 0)
->where('opt_out', 0)
->where('email', '!=', DB::raw("concat('', email * 1)"));
if ( ! empty($companyName[0]))
{
$query->whereHas('account', function($query) use ($companyName)
{
$query->where('company_name', 'like', "%$companyName[0]%");
});
}
if ( ! empty($account[0]))
{
$query->whereHas('account', function($query) use ($account)
{
$query->whereIn('id', $account);
});
}
if ( ! empty($accountManager[0]))
{
$query->whereHas('account', function($query) use ($accountManager)
{
$query->whereHas('user', function($query) use ($accountManager)
{
$query->whereIn('id', $accountManager);
});
});
}
if ( ! empty($industryType[0]))
{
$query->whereHas('account', function($query) use ($industryType)
{
$query->whereHas('industryType', function($query) use ($industryType)
{
$query->whereIn('id', $industryType);
});
});
}
if ( ! empty($haveAttended[0]) or ! empty($haveNotAttended[0]))
{
$query->join('delegates', 'contacts.id', '=', 'delegates.contact_id')
->join('delegate_event', 'delegates.id', '=', 'delegate_event.delegate_id')
->join('events', 'delegate_event.event_id', '=', 'events.id')
->join('courses', 'events.course_id', '=', 'courses.id');
}
if ( ! empty($haveAttended[0]))
{
$query->whereIn('courses.id', $haveAttended);
}
if ( ! empty($haveNotAttended[0]))
{
$query->whereNotIn('courses.id', $haveNotAttended);
}
if ( ! empty($jobTitle[0]))
{
$query->whereIn('contacts.job_title_id', $jobTitle);
}
if ( ! empty($contactEmail[0]))
{
$query->whereIn('contacts.id', $contactEmail);
}
}
}
这就是我创建新Mailchimp片段的方式:
public function createNewSegment($segments, $campaignId)
{
foreach ($segments as $key => $segment)
{
if ($segment['name'] == 'CREAM-' . $campaignId)
{
MailchimpWrapper::lists()->staticSegmentDel('123456789', $segment['id']);
}
}
$segment = MailchimpWrapper::lists()->staticSegmentAdd('123456789', 'CREAM-' . $campaignId);
return $segment['id'];
}
这是我将检索到的电子邮件添加到创建的细分中的方式:
public function addContactEmailsToSegment($contactEmails, $segmentId)
{
$listEmails = $this->generateListEmails(Config::get('mailchimp::apikey'), '123456789', 'subscribed');
$emails = $this->buildSegmentEmails($contactEmails, $listEmails);
if ($emails)
{
$emailsChunk = array_chunk($emails, 1000);
foreach ($emailsChunk as $emails)
{
MailchimpWrapper::lists()->staticSegmentMembersAdd('123456789', $segmentId, $emails);
}
}
}
这是检索Mailchimp中已匹配订阅者且已添加到细分受众群的所有电子邮件/联系人的功能:
public function getSegmentEmails($apiKey, $listId, $status, $segmentId)
{
$conditions = '&segment[saved_segment_id]=' . $segmentId;
return $this->generateListEmails($apiKey, $listId, $status, $conditions);
}
这是从Mailchimp中提取列表电子邮件的方式:
public function generateListEmails($apiKey, $listId, $status, $conditions = null)
{
$url = 'http://us5.api.mailchimp.com/export/1.0/list?apikey=' . $apiKey . '&id=' . $listId . '&status=' . $status;
if ( ! is_null($conditions))
{
$url .= '&segement[match]=all' . $conditions;
}
$handle = @fopen($url, 'r');
$chunk_size = 4096;
$i = 0;
$header = [];
while ( ! feof($handle))
{
$buffer = fgets($handle, $chunk_size);
if (trim($buffer) != '')
{
$obj = json_decode($buffer);
$listEmails[$obj[0]] = $obj[0];
$i++;
}
}
fclose($handle);
unset($listEmails['Email Address']);
return $listEmails;
}