PHP foreach 用户脚本似乎使 apache 挂起 [英] PHP foreach user script seems to make apache hang

查看:32
本文介绍了PHP foreach 用户脚本似乎使 apache 挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了一个非常简单的脚本来遍历我们所有的用户,每次执行限制为 500.

I've made a very simple script to loop through all of our users with a limit of 500 per execution.

它执行以下操作:

  1. 选择用户数据
  2. 插入一行
  3. 向用户发送电子邮件
  4. 更新一行
  5. 下一个用户

它按预期工作并成功完成.

但是,当我运行它时,我无法在另一个窗口中使用该网站,因为它只是加载",直到该脚本完成执行?

However when I run it I cannot use the website in another window because it just 'loads' until this script has finished executing?

就好像脚本在运行时锁定了用户表,但这不应该发生,因为我们只是使用保存到 $result 的数据?

It's as if the script locks the user table whilst it's running but this shouldn't happen because we're just using the data saved to $result?

但是我可以在网站冻结时通过sqlyog查询数据库,所以不能这样吗?会不会只是使用了太多资源?

But I can query the database through sqlyog while the website freezes so it can't be that? Could it just be using too many resources?

脚本 - 示例

<?
set_time_limit(0);

require '../connect.php';
require '../includes/ses.php';

$i = 1;

$ses = new simpleemailservice();

$result = mysql_query("SELECT id, username, email FROM `user` WHERE thiscol = 0 LIMIT 500");

while($row = mysql_fetch_row($result)){

    mysql_query("INSERT INTO table (data) VALUES (1)");

    $m = new SimpleEmailServiceMessage();

        $m->addTo($row[1]." <".$row[2].">");
        $m->setFrom("Emailer <no-reply@emailer.com>");
        $m->setSubject("Subject");
        $m->setMessageFromString("Email Text", "Email HTML");

    if($ses->sendEmail($m))
        mysql_query("UPDATE `user` SET thiscol = 1 WHERE id = ".$row[0]);

    $i++;
}
?>

推荐答案

这种行为听起来像会话锁定.PHP 会话的默认工作方式是锁定会话(以防止两个进程写入会话对象).这对于典型的短期 PHP 脚本来说通常是没问题的,但是当你有一些长期运行的东西时,它会咬你.

This behaviour sounds like session-locking. The default way PHP sessions work is to lock the session (to prevent two processes writing to the session object). This is normally fine for typical short-lived PHP scripts, but can bite you when you have something that is long-running.

如果您的应用程序根本不使用会话,那么您应该在 php.ini 或 .htaccess 中关闭 session.auto_start:http://www.php.net/manual/en/session.configuration.php#ini.session.自动启动(如果您没有在那里看到它,或者它已经关闭,但您正在使用某种框架,则该框架可能会为您启动会话;如果是这样,转到下一个解决方案比尝试抗争要简单框架.)

If your application is not using sessions at all, then you should turn off session.auto_start in php.ini or .htaccess: http://www.php.net/manual/en/session.configuration.php#ini.session.auto-start (If you don't see it there, or it is already off, but you are using some kind of framework, the framework might be starting the session for you; if so it is simpler to go to the next solution than try to fight the framework.)

如果您在某些页面上使用会话,而不是在这个长时间运行的过程中,解决方案是在脚本开始时关闭会话,使用 session_write_close():

If you are using the session on some pages, but not on this long-running process, the solution is to close the session at the start of your script, with session_write_close():

<?
set_time_limit(0);

require '../connect.php';
require '../includes/ses.php';

session_write_close();

$i = 1;
....

再次,框架警告:如果框架正在为您启动会话,则将 session_write_close(); 放在包含框架文件之后,而不是之前!(您在评论中提到了这种情况,这就是我将它放在 require 行之后的原因.)

Again, the framework warning: if the framework is starting a session for you, then put session_write_close(); after including the framework files, not before! (You mentioned that was the case in your comments, which is why I've put it after the require lines.)

如果你的长时间运行的进程需要使用会话,但是是只读的,上面的仍然有效.请参阅 https://stackoverflow.com/a/14409902/841830(如该答案所示,如果您需要在长时间运行的进程结束时写入会话,那也是可能的.)

If your long-running process needs to use the session, but read-only, the above still works. See https://stackoverflow.com/a/14409902/841830 (As that answer shows, if you need to write to the session at the end of the long-running process, that is also possible.)

(PS 这已经在评论中得到了回答,但我已经接受了 Wrikken 的提议,将其作为答案发布.是的,谣言是真的:我会为一些代表做任何事情......)

(P.S. This was already answered in the comments, but I've taken Wrikken up on his offer to post it as an answer. Yes, the rumours are true: I'll do anything for a few rep...)

这篇关于PHP foreach 用户脚本似乎使 apache 挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆