<?php
header('Content-Type: text/html; charset=utf8');
$dbhost = '192.168.1.23';
$dbuser = 'demouser01';
$dbpass = 'demo*PW';
$dbname = 'testdb1';
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die('Error with MySQL connection');
mysql_select_db($dbname);
mysql_query("SET NAMES 'utf8'");
mysql_query("SET CHARACTER_SET_CLIENT='utf8'");
mysql_query("SET CHARACTER_SET_RESULTS='utf8'");
if(isset($_POST['start'])) {
$chi = 'chiiiii';
$id = 1;
for ($i = 1; $i <= 99999999999; $i++) {
$eng = substr(str_shuffle(str_repeat("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 5)), 0, 1024);
$math = substr(str_shuffle(str_repeat("1234567890", 6)), 0, 16);
$sql = "INSERT INTO test_tb (id,chi,eng,num) VALUES (".$id.",'".$chi."','".$eng."',".$math.")";
$result = mysql_query($sql) or die('MySQL query error');
$id++;
}
$id = 0;
sleep(60);
mysql_close($conn);
} else if(isset($_POST['stop'])) {
mysql_close($conn);
}
?>
<form action="<?=$_SERVER['PHP_SELF'];?>" method="post">
<input type="submit" name="start" value="Start Insert">
<input type="submit" name="stop" value="Stop Insert">
</form>
网站中有两个按钮,插入以重复插入记录,并停止暂停插入。但是,我尝试使用MySQL关闭连接,它将在PHP中停止运行,但活动仍然存在。插入仍然保持执行。如何解决问题?感谢。
答案 0 :(得分:2)
由于PHP不允许您在请求者之间共享资源(AFAIK),因此有几种方法可以实现在另一个请求中停止进程的能力:
首先添加以下行:
if ( isset ($_POST['start']) ) {
$_SESSION['continue'] = true;
然后用while替换你的for语句(看起来你不关心itterations的数量,如果是这样你可以改变这种行为):
for ($i = 1; $i <= 99999999999; $i++) {
替换为:
while ( $_SESSION['continue'] )
而不是关闭连接以停止插入执行此操作:
mysql_close ($con)
将按照:
$_SESSION['continue'] = false;
注意:不要忘记在脚本开头调用session_start()。 多数民众赞成。
如果不是这种情况你可以使用ACP ore SHM,我认为你想要停止同一会话中的页面。例如:
替换:
$_SESSION['continue'] = true
with:
apc_store( 'continue', true );
和
while ( $_SESSION['continue'] )
使用:
while ( acp_fetch ('continue') )
和
$_SESSION['continue'] = false;
使用:
apc_store( 'continue', false );
完成!
答案 1 :(得分:2)
本页中的每个答案都转过一点:
当然主要的问题是php是一个share nothing的东西。
因此有人建议使用会话,这可能很难做到,因为会话在关闭之前不会重新读取,您可能很容易在会话中覆盖数据。其他人建议使用共享内存或APC。
我们谈论的是某种外部semaphore。当然,解决方案不是关闭连接,而是打破外部信号的循环。
但是你已经拥有了一个大而简单,可能太明显的共享系统。 您的数据库连接。
只需在数据库中检查循环说明的早期结束。
数据库通常为此任务提供顾问锁系统。例如,使用GET_LOCK和RELEASE_LOCK说明。在主插入循环的每次迭代中使用IS_FREE_LOCK并使用停止操作获取此锁定将是一种方法。由于释放锁定的问题,可能是在来自所有记录的插入循环的另一个信号之后,或者在一段时间之后。但您也可以管理自己的基于表的系统。
咨询锁系统的一个“优势”是它们忽略了交易。如果您构建自己的基于表的系统,则必须确保使用事务处理来确保其他事务的写入可用(如果不是可序列化的事务,则确定)。
使用数据库在PHP实例之间共享信息通常是LAMP中的默认情况,并且保证在插入情况下使用此工具,而APC不是这种情况。
答案 2 :(得分:1)
每次调用PHP脚本都会打开自己与MySQL的连接,并且它们不会相互干扰。与mysql_pconnect()
打开的连接是一个例外:它们保持打开状态并将被共享,但也可以使用mysql_close()关闭 。
结论:你要做的事情是行不通的(无论如何都是个坏主意)。
您可能需要的是为插入创建后台任务并检查其中的中断消息(可能就像空文件.STOP[PID]
一样简单[PID]
=进程ID)
<强>更新强>
我可以不使用APC吗?
是的,只要安装了APC扩展程序,可以使用APC获取此消息。情况并非如此,因此出现此错误:
在第31行的/home/ext/library/public/testdb/test.php中调用未定义的函数acp_fetch()
您是否拥有服务器的root权限?然后你可以自己安装扩展程序:
sudo pecl install apc
如果此命令不起作用,您需要先获取PECL安装程序,请参阅此处:sudo pecl install apc returns error
答案 3 :(得分:1)
这是一个完整的解决方案:
<?php
header('Content-Type: text/html; charset=utf8');
$dbhost = '192.168.1.23';
$dbuser = 'demouser01';
$dbpass = 'demo*PW';
$dbname = 'testdb1';
$SHMKEY = ftok ( __FILE__, 'a');
$SHMID = shm_attach ( $SHMKEY );
if ( !shm_has_var ( $SHMID, 1 ) ) {
shm_put_var ( $SHMID, 1, true );
}
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die('Error with MySQL connection');
mysql_select_db($dbname);
mysql_query("SET NAMES 'utf8'");
mysql_query("SET CHARACTER_SET_CLIENT='utf8'");
mysql_query("SET CHARACTER_SET_RESULTS='utf8'");
if(isset($_POST['start'])) {
$chi = 'chiiiii';
$id = 1;
// for ($i = 1; $i <= 99999999999; $i++) {
while ( shm_get_var ( $SHMID, 1) ) {
$eng = substr(str_shuffle(str_repeat("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 5)), 0, 1024);
$math = substr(str_shuffle(str_repeat("1234567890", 6)), 0, 16);
$sql = "INSERT INTO test_tb (id,chi,eng,num) VALUES (".$id.",'".$chi."','".$eng."',".$math.")";
$result = mysql_query($sql) or die('MySQL query error');
$id++;
}
$id = 0;
shm_detach ( $SHMID );
sleep(60);
mysql_close($conn);
}
else if(isset($_POST['stop'])) {
shm_put_var ( $SHMID, 1, false );
// mysql_close($conn);
}
?>
<form action="<?=$_SERVER['PHP_SELF'];?>" method="post">
<input type="submit" name="start" value="Start Insert">
<input type="submit" name="stop" value="Stop Insert">
</form>
答案 4 :(得分:1)
有人建议:
实际上是关闭了另一个连接(在if(isset($_POST['stop']))
分支中)
您不能跨PHP脚本共享与MySQL的连接,因为您无法在会话中存储资源
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if(isset($_POST['start'])) {
// store current connection ID
// store an array of connection ID's in case several connections may run simultaneously
$result = mysqli_query($conn, 'SELECT CONNECTION_ID()');
$row = mysql_fetch_row($result);
$_SESSION['connection_id'] = $row[0];
// close session file
// or else concurrent scripts using the same session will be blocked
session_write_close();
// do actual work here
sleep(10);
// keep in mind the connection may be killed from another script at any time, e.g.
if (mysqli_query("...") == false) {
// connection was probably killed
}
// reopen session (optional, do it only if you need your session data later)
session_start();
} else if(isset($_POST['stop'])) {
// kill pending connection(s)
mysqli_kill($conn, $_SESSION['connection_id']);
// equivalent query in pure (My)SQL : 'KILL ' . $_SESSION['connection_id']
}
而不是KILL [connection_id]
,您可以使用KILL QUERY [connection_id]
。这将终止任何正在运行的查询但不会关闭连接(但在您的情况下,您可能希望完全关闭连接)。