php int 设置超时,php执行程序可设置超时时间,linux下可用

使用php执行外部命令并且取返回值,可设置超时时间,如果超时则中止进程/**

* 执行命令行程序,直到超时退出,只支持linux

* @param string $cmd     命令行程序

* @param string $stdin   标准输入

* @param int    $timeout 时间时间秒

* @return array  输出命令结果和错误内容

* @throws Exception

*/

function exec_timeout(string $cmd, string $stdin, int $timeout): array

{

// 传递给进程的标准描述符

$descriptors = array(

0 => array('pipe', 'r'),  // stdin

1 => array('pipe', 'w'),  // stdout

2 => array('pipe', 'w')   // stderr

);

// 启动进程

$process = proc_open($cmd, $descriptors, $pipes);

if (!is_resource($process)) {

throw new \Exception('Could not execute process');

}

//如果有标准输入内容的话就写入

if ($stdin) {

fwrite($pipes[0], $stdin);

}

fclose($pipes[0]);

// 设置标准输出异步不阻塞

stream_set_blocking($pipes[1], 0);

// 设置标准错误输出异步不阻塞

stream_set_blocking($pipes[2], 0);

// 时间时间转为微妙

$timeout = $timeout * 1000000;

// 标准输出内容

$buffer = '';

// 一直等待到超时退出或执行完自动退出

while ($timeout > 0) {

$start = microtime(true);

// Wait until we have output or the timer expired.

$read  = array($pipes[1]);

$other = array();

stream_select($read, $other, $other, 0, $timeout);

// Get the status of the process.

// Do this before we read from the stream,

// this way we can't lose the last bit of output if the process dies between these functions.

$status = proc_get_status($process);

// Read the contents from the buffer.

// This function will always return immediately as the stream is non-blocking.

$buffer .= stream_get_contents($pipes[1]);

if (!$status['running']) {

// Break from this loop if the process exited before the timeout.

break;

}

// Subtract the number of microseconds that we waited.

$timeout -= (microtime(true) - $start) * 1000000;

}

// Check if there were any errors.

$errors = stream_get_contents($pipes[2]);

// if (!empty($errors)) {

//    throw new \Exception($errors);

// }

// Kill the process in case the timeout expired and it's still running.

// If the process already exited this won't do anything.

proc_terminate($process, 9);

// Close all streams.

// fclose($pipes[0]);

fclose($pipes[1]);

fclose($pipes[2]);

proc_close($process);

return [

'error'  => $errors,

'result' => $buffer

];

}

调用执行一个php的死循环$code    = <<

\$i=0;

while(true){

echo \$i++,PHP_EOL;

sleep(1);

}

eot;

$res = exec_timeout('php -a ', $code, 5);

//替换掉开头的输出和空行

$res['result'] = preg_replace('@Interactive shell\s*\n\s*\n@', '', $res['result']);

print_r($res);

5秒后进程退出

5700a094e1c4bd3448ff333a05660976.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值