限制php执行时间

时间:2012-02-14 17:05:38

标签: php

我进行挖掘查询。有时回复很快,有时超过10秒。我的问题是我需要在5秒后停止查询,然后更新数据库。那么问题是如何在5秒后让$ip停止更新我的数据库?

$host = "@$ns1 $subdomain";
$ip = `/usr/bin/dig $host +short A`;

// if $ip is more than 5 sec than stop the query. How to do this?

mysql_query("UPDATE dns SET query_ns = '1' WHERE zone ='123'");

更新: 我很抱歉任何困惑。我在query的意思是使用dig来进行ns查找。再次抱歉了。

7 个答案:

答案 0 :(得分:3)

您可以使用proc_open打开dig命令的管道,stream_select它并等待5秒钟,然后读取并关闭proc。

或多或少这样:

function getip()
{
$ip = null;

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")  // stderr
);

$process = proc_open("/usr/bin/dig $host +short A", $descriptorspec, $pipes);

if (is_resource($process)) {
    // $pipes now looks like this:
    // 0 => writeable handle connected to child stdin
    // 1 => readable handle connected to child stdout
    // 2 => readable handle


    $ip = fgetsPending($pipes[1]);

    fclose($pipes[0]);
    fclose($pipes[1]);
    fclose($pipes[2]);

    // It is important that you close any pipes before calling
    // proc_close in order to avoid a deadlock
    proc_close($process);
}

return $ip;
}

function fgetsPending(&$in,$tv_sec=5) 
{
    if ( stream_select($read = array($in),$write=NULL,$except=NULL,$tv_sec) ) return fgets($in);
    else return FALSE;   
}

echo getip();

答案 1 :(得分:1)

查看mysql_unbuffered_query函数的文档: http://www.php.net/manual/en/function.mysql-unbuffered-query.php

这些方面应该做你想做的事情:

<?php
// a db link for queries
$lh  = mysql_connect( 'server', 'uname', 'pword' );
// and a controller link
$clh = mysql_connect( 'server', 'uname', 'pword', true );

if ( mysql_select_db ( 'big_database', $lh ) )
{
  $began  =  time();
  $tout   = 60 * 5; // five minute limit
  $qry    = "SELECT * FROM my_bigass_table";
  $rh     = mysql_unbuffered_query( $qry, $lh );
  $thread = mysql_thread_id ( $lh );
  while ( $res = mysql_fetch_row( $rh ) )
  {
    /* do what you need to do
     * ...
     * ...
     */
    if ( ( time() - $began ) > $tout )
    {
      // this is taking too long
      mysql_query( "KILL $thread", $clh );
      break;
    }
  }
}
?>

答案 2 :(得分:1)

只是在黑暗中拍摄,但我会尝试这样的事情:

$default_exe_time = ini_get('max_execution_time');
try {
    ini_set('max_execution_time', 5);
    $host = "@$ns1 $subdomain";
    $ip = `/usr/bin/dig $host +short A`;
    if (!mysql_query("UPDATE dns SET query_ns = '1' WHERE zone ='123'")){
        throw new Exception('');
    }
} catch Exception ($e) {
   // update db
}
ini_set('max_execution_time', $default_exe_time);

答案 3 :(得分:1)

我不知道如何使用mysql扩展(它没有这样的功能或设置)但你可以用程序方式使用mysqli轻松完成:

mysqli_options($connection, MYSQLI_OPT_CONNECT_TIMEOUT, 5);

或以OOP方式:

$connection->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5);

您可以阅读有关mysqli及其功能here

的信息

答案 4 :(得分:1)

根据官方文档,“PHP将尝试以shell命令”执行反引号的内容,这意味着您应该能够执行以下操作:

$ip = `/usr/bin/dig $host +short A   & pid=$! ; sleep 5; kill -9 $pid`

这个技巧在shell中有效,所以如果PHP在shell中执行反引号,你应该很好。

编辑:您可能需要应用一些额外的润色,以便PHP不会尝试展开$pid ...

答案 5 :(得分:0)

您可以切换为使用mysqli并使用mysqli_kill()命令:http://php.net/manual/en/mysqli.kill.php

答案 6 :(得分:0)

问题已经解决了,感谢ajreal给了我他的想法。我决定通过挖掘实用程序来限制查询。解决方案:https://serverfault.com/questions/360102/dig-timeout-option-dont-work

感谢大家的帮助和投入。