我制作了一个非常简单的脚本来循环遍历所有用户,每次执行限制为500.
它执行以下操作:
按预期工作并成功完成。
然而,当我运行它时,我无法在另一个窗口中使用该网站,因为它只是“加载”,直到此脚本执行完毕?
就好像脚本在运行时锁定用户表但这不应该发生,因为我们只是使用保存到$result
的数据?
但是我可以在网站冻结的时候通过sqlyog查询数据库,所以不能这样吗?可能只是使用了太多资源?
脚本 - 示例
<?
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++;
}
?>
答案 0 :(得分:2)
这种行为听起来像会话锁定。 PHP会话工作的默认方式是锁定会话(以防止两个进程写入会话对象)。这通常适用于典型的短期PHP脚本,但是当你有长时间运行的东西时可能会咬你。
如果您的应用程序根本没有使用会话,那么您应该关闭php.ini中的session.auto_start
或.htaccess:http://www.php.net/manual/en/session.configuration.php#ini.session.auto-start
(如果你没有在那里看到它,或者它已经关闭,但是你正在使用某种框架,那么框架可能正在为你启动会话;如果是这样,那么去下一个解决方案比尝试战斗更简单框架。)
如果您在某些页面上使用会话,而不是在这个长时间运行的过程中使用会话,解决方案是使用session_write_close()在脚本开头关闭会话:
<?
set_time_limit(0);
require '../connect.php';
require '../includes/ses.php';
session_write_close();
$i = 1;
....
同样,框架警告:如果框架正在为您启动会话,那么在包含框架文件之后放置session_write_close();
,而不是之前! (你在评论中提到过这种情况,这就是为什么我把它放在需求行之后。)
如果长时间运行的进程需要使用会话,但只读,上面的代码仍然有效。见https://stackoverflow.com/a/14409902/841830 (正如答案所示,如果你需要在长时间运行的过程结束时写入会话,那也是可能的。)
(PS这已经在评论中得到了解答,但是我已经把Wrikken的提议作为答案发布了。是的,谣言是真的:我会为一些代表做任何事......)