第 4 次睡眠后 php 脚本停止
phpscript stops after 4th sleep
我有一个包含大约 3500 个用户数据的 csv 文件。我想将这些用户导入我的数据库并向他们发送一封电子邮件,说明他们已注册。
我有以下代码:
public function importUsers()
{
$this->load->model('perk/engagement_model');
$this->load->model('user/users_model');
$this->load->model('acl/aclUserRoles_model');
$allengagements = $this->engagement_model->getAll();
$filename = base_url() . 'assets/overdracht_users.csv';
$file = fopen($filename, "r");
$count = 0;
$totalImported = 0;
$importFails = array();
$mailFails = array();
while (($mappedData = fgetcsv($file, 10000, ";")) !== FALSE)
{
$count++;
//Skip first line because it is the header
if ($count > 1) {
if (!empty($mappedData[0])) {
$email = $mappedData[0];
$user = $this->users_model->getByEmail($email);
if (!$user) {
$user = new stdClass();
$user->email = $mappedData[0];
$user->first_name = $mappedData[1];
$user->family_name = $mappedData[2];
$user->address_line1 = $mappedData[3];
$user->address_postal_code = $mappedData[4];
$user->address_city = $mappedData[5];
$user->address_country = 'BE';
$user->volunteer_location = $mappedData[5];
$user->volunteer_location_max_distance = 50;
$user->phone = $mappedData[6];
if (!empty($mappedData[7])) {
$user->birthdate = $mappedData[7] . "-01-01 00:00:00";
} else {
$user->birthdate = null;
}
foreach ($allengagements as $eng) {
if ($eng->description == $mappedData[8]) {
$engagement = $eng->engagement_id;
}
}
$user->engagement = $engagement;
if (!empty($mappedData[9])) {
$date_created = str_replace('/', '-', $mappedData[9]);
$date_created = date('Y-m-d H:i:s', strtotime($date_created));
} else {
$date_created = date('Y-m-d H:i:s');
}
$user->created_at = $date_created;
if (!empty($mappedData[10])) {
$date_login = str_replace('/', '-', $mappedData[10]);
$date_login = date('Y-m-d H:i:s', strtotime($date_login));
} else {
$date_login = null;
}
$user->last_login = $date_login;
$user->auth_level = 1;
$user->is_profile_public = 1;
$user->is_account_active = 1;
$combinedname = $mappedData[1] . $mappedData[2];
$username = str_replace(' ', '', $combinedname);
if (!$this->users_model->isUsernameExists($username)) {
$uniqueUsername = $username;
} else {
$counter = 1;
while ($this->users_model->isUsernameExists($username . $counter)) {
$counter++;
}
$uniqueUsername = $username . $counter;
}
$user->username = $uniqueUsername;
$userid = $this->users_model->add($user);
if (!empty($userid)) {
$totalImported++;
//Add the user in the volunteer group in ACL
$aclData = [
'userID' => $userid,
'roleID' => 1,
'addDate' => date('Y-m-d H:i:s')
];
$this->aclUserRoles_model->add($aclData);
//Registration mail to volunteer
$mail_data['name'] = $user->first_name . ' ' . $user->family_name;
$mail_data['username'] = $user->username;
$this->email->from(GENERAL_MAIL, 'Test');
$this->email->to($user->email);
//$this->email->bcc(GENERAL_MAIL);
$this->email->subject('Test');
$message = $this->load->view('mail/register/registration',$mail_data,TRUE);
$this->email->message($message);
$mailsent = $this->email->send();
if (!$mailsent) {
array_push($mailFails, $mappedData);
}
} else {
array_push($importFails, $mappedData);
}
if ($count % 50 == 0) {
var_dump("count is " . $count);
var_dump("we are sleeping");
$min=20;
$max=40;
$randSleep = rand($min,$max);
sleep($randSleep);
var_dump("end of sleep (which is " . $randSleep . "seconds long)");
}
var_dump($user);
} else {
array_push($importFails, $mappedData);
}
}
}
}
var_dump("Totale aantal rijen in het bestand (met header) : " . $count);
var_dump("Totale aantal geimporteerd in de database : " . $totalImported);
var_dump("Totale aantal gefaalde imports in de database : " . count($importFails));
var_dump("Deze zijn gefailed : ");
var_dump($importFails);
}
如果我不在数据库中添加用户或发送邮件,而只是 var_dump() $user,我可以看到在 [=28= 中正确创建了所有 3500 多个用户] 对象(因此它们应该能够正确插入)。
问题是我想在每发送 50 封邮件后 20 到 40 秒之间添加一个随机睡眠。
所以我开始做一些测试,在注释掉插入和邮件代码后,我启动了 运行 脚本,注意到在一定数量(根本不是 50)之后,它只是停止了一点,然后继续并在底部的 if 案例中向我展示 var_dumps,它可以在下面的屏幕截图中显示。
第一个屏幕截图显示代码停止了一点(请注意,我只是 var_dumping 东西,我还没有在数据库中添加东西或发送电子邮件)。
此屏幕截图显示了脚本达到 200 后发生的情况:
脚本从此完全停止。我已经试过 3 次了,每次都正好停在 200。
这里发生了什么??
很可能您达到了默认 PHP 限制。暂时删除 PHP 默认限制:
ini_set('memory_limit',-1);
set_time_limit(0);
然后,重新运行脚本并检查输出。
可能有多种原因,但要知道确切的原因,请启用错误输出。
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
如果限制不是问题,错误会告诉您更多信息。
提示:使用日志仍然比向访问者输出错误要好,但我猜你是在你的计算机上测试这个。
我有一个包含大约 3500 个用户数据的 csv 文件。我想将这些用户导入我的数据库并向他们发送一封电子邮件,说明他们已注册。 我有以下代码:
public function importUsers()
{
$this->load->model('perk/engagement_model');
$this->load->model('user/users_model');
$this->load->model('acl/aclUserRoles_model');
$allengagements = $this->engagement_model->getAll();
$filename = base_url() . 'assets/overdracht_users.csv';
$file = fopen($filename, "r");
$count = 0;
$totalImported = 0;
$importFails = array();
$mailFails = array();
while (($mappedData = fgetcsv($file, 10000, ";")) !== FALSE)
{
$count++;
//Skip first line because it is the header
if ($count > 1) {
if (!empty($mappedData[0])) {
$email = $mappedData[0];
$user = $this->users_model->getByEmail($email);
if (!$user) {
$user = new stdClass();
$user->email = $mappedData[0];
$user->first_name = $mappedData[1];
$user->family_name = $mappedData[2];
$user->address_line1 = $mappedData[3];
$user->address_postal_code = $mappedData[4];
$user->address_city = $mappedData[5];
$user->address_country = 'BE';
$user->volunteer_location = $mappedData[5];
$user->volunteer_location_max_distance = 50;
$user->phone = $mappedData[6];
if (!empty($mappedData[7])) {
$user->birthdate = $mappedData[7] . "-01-01 00:00:00";
} else {
$user->birthdate = null;
}
foreach ($allengagements as $eng) {
if ($eng->description == $mappedData[8]) {
$engagement = $eng->engagement_id;
}
}
$user->engagement = $engagement;
if (!empty($mappedData[9])) {
$date_created = str_replace('/', '-', $mappedData[9]);
$date_created = date('Y-m-d H:i:s', strtotime($date_created));
} else {
$date_created = date('Y-m-d H:i:s');
}
$user->created_at = $date_created;
if (!empty($mappedData[10])) {
$date_login = str_replace('/', '-', $mappedData[10]);
$date_login = date('Y-m-d H:i:s', strtotime($date_login));
} else {
$date_login = null;
}
$user->last_login = $date_login;
$user->auth_level = 1;
$user->is_profile_public = 1;
$user->is_account_active = 1;
$combinedname = $mappedData[1] . $mappedData[2];
$username = str_replace(' ', '', $combinedname);
if (!$this->users_model->isUsernameExists($username)) {
$uniqueUsername = $username;
} else {
$counter = 1;
while ($this->users_model->isUsernameExists($username . $counter)) {
$counter++;
}
$uniqueUsername = $username . $counter;
}
$user->username = $uniqueUsername;
$userid = $this->users_model->add($user);
if (!empty($userid)) {
$totalImported++;
//Add the user in the volunteer group in ACL
$aclData = [
'userID' => $userid,
'roleID' => 1,
'addDate' => date('Y-m-d H:i:s')
];
$this->aclUserRoles_model->add($aclData);
//Registration mail to volunteer
$mail_data['name'] = $user->first_name . ' ' . $user->family_name;
$mail_data['username'] = $user->username;
$this->email->from(GENERAL_MAIL, 'Test');
$this->email->to($user->email);
//$this->email->bcc(GENERAL_MAIL);
$this->email->subject('Test');
$message = $this->load->view('mail/register/registration',$mail_data,TRUE);
$this->email->message($message);
$mailsent = $this->email->send();
if (!$mailsent) {
array_push($mailFails, $mappedData);
}
} else {
array_push($importFails, $mappedData);
}
if ($count % 50 == 0) {
var_dump("count is " . $count);
var_dump("we are sleeping");
$min=20;
$max=40;
$randSleep = rand($min,$max);
sleep($randSleep);
var_dump("end of sleep (which is " . $randSleep . "seconds long)");
}
var_dump($user);
} else {
array_push($importFails, $mappedData);
}
}
}
}
var_dump("Totale aantal rijen in het bestand (met header) : " . $count);
var_dump("Totale aantal geimporteerd in de database : " . $totalImported);
var_dump("Totale aantal gefaalde imports in de database : " . count($importFails));
var_dump("Deze zijn gefailed : ");
var_dump($importFails);
}
如果我不在数据库中添加用户或发送邮件,而只是 var_dump() $user,我可以看到在 [=28= 中正确创建了所有 3500 多个用户] 对象(因此它们应该能够正确插入)。
问题是我想在每发送 50 封邮件后 20 到 40 秒之间添加一个随机睡眠。
所以我开始做一些测试,在注释掉插入和邮件代码后,我启动了 运行 脚本,注意到在一定数量(根本不是 50)之后,它只是停止了一点,然后继续并在底部的 if 案例中向我展示 var_dumps,它可以在下面的屏幕截图中显示。
第一个屏幕截图显示代码停止了一点(请注意,我只是 var_dumping 东西,我还没有在数据库中添加东西或发送电子邮件)。
此屏幕截图显示了脚本达到 200 后发生的情况:
脚本从此完全停止。我已经试过 3 次了,每次都正好停在 200。 这里发生了什么??
很可能您达到了默认 PHP 限制。暂时删除 PHP 默认限制:
ini_set('memory_limit',-1);
set_time_limit(0);
然后,重新运行脚本并检查输出。
可能有多种原因,但要知道确切的原因,请启用错误输出。
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
如果限制不是问题,错误会告诉您更多信息。
提示:使用日志仍然比向访问者输出错误要好,但我猜你是在你的计算机上测试这个。