PHP串行调用系统命令延时问题

夜已深了,这是第三个夜。对一个不知天高地厚的菜鸟程序猿来说,用PHP对所要做的事情串行起来并调用一下外部命令并没有什么难点,然而书到用时方恨少啊!

先说主要人物:PHP调用外部命令的函数system()。这个函数在调用shell命令的时候会把返回结果打印出来。但是当返回结果相当庞大时,它就会掉链子导致程序卡死。当然强大的机器也有解决方案就是将返回结果打印到一个文件中。像这样system('gradle bulid > abc.txt');这样所有的返回结果都会写入到当前文件夹下的abc.txt文件中而不会影响程序的运行。

如果你是冲着标题来的,看到这里您的问题应该得到解决。下面是我这几天关于程序串行,调用外部命令的自我总结。

首先,有一个这样的任务:用户有一些可以编译的java文件,每当用户请求时,后台自动将这些文件编译为可操作程序。编译过程会对服务器带来不小的压力所以不允许同时执行。串行程序我的想法是利用数据库。

每个用户的请求存入数据,当执行该用户的请求时改变记录状态。循环执行数据库中所有的记录并删除。

<?php
error_reporting(E_ALL^E_NOTICE^E_WARNING);
ini_set('max_execution_time', '0');
/**
*省略插入操作
*/
$sql1 = "select * from table order by `id` ASC";
$item1=mysql_query($sql1,$conn);
$row = mysql_fetch_array($item1,MYSQL_ASSOC);
if(!$row || $row['statue']==1){
	die("正在编译中。。");//编译中退出命令
}

while(true){
	$sql = "select `id` from table order by id";
	$item=mysql_query($sql,$conn);
	$search = mysql_fetch_row($item);
	if(!$search){
		//如果队列中没有数据,则结束定时器
		break;
	}
        //更新状态 编译中
        $sqlup='UPDATE table SET `statue` = 1 WHERE id ='. $search[0];
        mysql_query($sqlup,$conn);
//执行编译命令
	$result=system("cd". $search["0"]." && gradle build > abc.txt");
	$delsql="delete from table where `id`= '$search[0]'";
	mysql_query($delsql,$conn);
	sleep(10); //每隔十秒循环一次
}

由于编译过程时间较长所以在文件开头加入
ini_set('max_execution_time', '0');
防止请求超时浏览器卡死或失去响应。

PHP调用外部命令有四种方法:exec()、passthru()、system()、shell_exec()。

exec执行系统外部命令时不会输出结果,而是返回结果的最后一行。system在执行系统外部命令时,直接将结果输出到游览器,如果执行命令成功则返回true,否则返回false。

passthru直接将结果输出到游览器,不返回任何值,且其可以输出二进制,比如图像数据。在shell_exec函数可用的情况下你还可以用反撇号eg:echo `ls`来调用外部命令。

安全性说明:当你使用这些函数执行命令时,如果是根据用户提交数据作为执行命令的话,你需要考虑系统安全性,可以使用escapeshellcmd()和escapeshellarg()函数阻止用户恶意在系统上执行命令,escapeshellcmd()针对的是执行的系统命令,而escapeshellarg()针对的是执行系统命令的参数。这两个参数有点类似addslashes()的功能。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值