el_*_*riz 6 php mysql memory memory-management
我有一个包含100,000个用户个人信息的数组(ID,名称,电子邮件等).我需要循环遍历数组的每一行,并根据行数据将mysql记录插入表中.我的问题是我在大约70,000行后耗尽内存.
我的代码:
if(!empty($users)){
$c = 0;
foreach($users as $user){
$message = // Some code to create custom email
queue_mail_to_send($user->user_email, $subject, $message, $db_options, $mail_options, $mail_queue);
}
}
Run Code Online (Sandbox Code Playgroud)
背景:
我正在建立一个电子邮件系统,向我的网站用户发送一封电子邮件.上面的代码循环遍历用户数组并执行函数'queue_mail_to_send',该函数将mysql行插入到电子邮件队列表中.(我正在使用PEAR库错开电子邮件发送)
题:
我知道我只是在一次执行中尝试做太多而耗费内存.那么有没有人知道更好的方法而不是试图在一个大循环中执行所有东西?
谢谢
我认为减少脚本的有效负载会很麻烦,并且不会给您带来令人满意的结果。如果您有可能这样做,我建议您记录已经处理的行,并让脚本运行接下来的 x 行。如果您可以使用 cronjob,则可以暂存邮件,并让 cronjob 每 5 分钟将邮件添加到队列中,直到处理完所有用户。
最简单的方法是将您处理过的最高用户 ID 存储在某个地方。我不建议您存储用户数量,因为在批次之间可以添加或删除用户,导致用户收不到电子邮件。但如果您按用户 ID 排序(假设您对 ID 使用自动递增列!),您可以确保每个用户都会得到处理。
所以你的用户查询将是这样的:
SELECT * FROM users WHERE user_id > [highest_processed_user_id] ORDER BY user_id LIMIT 1000
Run Code Online (Sandbox Code Playgroud)
然后处理循环,并存储最后一个用户 ID:
if(!empty($users)) {
$last_processed_id = null;
foreach($users as $user) {
$message = // Message creation magic
queue_mail_to_send( /** parameters **/ );
$last_processed_id = $user->id;
}
// batch done! store processed user id
$query = 'UPDATE mail_table SET last_processed_user_id = '. $last_processed_id; // please use parameterized statements here
// execute the query
}
Run Code Online (Sandbox Code Playgroud)
并在下次执行时再次执行,直到所有用户都收到邮件。