curl_exec()是同步的方式执行还是异步的?CURLOPT_TIMEOUT有什么作用?

seai 2010-06-25 04:34:43
<?php
//a.php
$ch = curl_init("http://127.0.0.1/b.php");
$ch_arr = array(CURLOPT_TIMEOUT=>2,CURLOPT_RETURNTRANSFER=>1);//2秒超时限制?
curl_setopt_array($ch,$ch_arr);
curl_exec($ch);
curl_close($ch);
echo 234;
?>

<?php
//b.php
sleep(6);//等待6秒
?>

上面的页面测试中,浏览a.php时很快就返回(毫秒级),浏览b.php可以明显看到>6秒才出来。

请问curl_exec到底是异步还是同步执行呢?CURLOPT_TIMEOUT参数有什么用?
...全文
5546 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
dereksangshi2000 2012-05-04
  • 打赏
  • 举报
回复
curl必须可以异步。说什么执行不完的都是错的。。
http://www.paul-norman.co.uk/2009/06/asynchronous-curl-requests/
seai 2010-06-25
  • 打赏
  • 举报
回复
只是为何直接运行b.php可以,从a.php调用就不可以了呢?
seai 2010-06-25
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 amani11 的回复:]

把txt文件删了,,,,,$ch = curl_init("http://127.0.0.1/b.php?t=" . time());再试试???
我本地测试,会生成文件的,
[/Quote]

看来是权限的问题,我在另外的机器上就成功了。
amani11 2010-06-25
  • 打赏
  • 举报
回复
把txt文件删了,,,,,$ch = curl_init("http://127.0.0.1/b.php?t=" . time());再试试???
我本地测试,会生成文件的,
seai 2010-06-25
  • 打赏
  • 举报
回复
a.php就是前面那样的

<?php
$start = time();//记录下时间
echo 'test';
$ch = curl_init("http://127.0.0.1/b.php");
$ch_arr = array(CURLOPT_TIMEOUT=>3,CURLOPT_RETURNTRANSFER=>1);
curl_setopt_array($ch,$ch_arr);
curl_exec($ch);
curl_close($ch);
echo time() - $start;
exit();
?>
CunningBoy 2010-06-25
  • 打赏
  • 举报
回复
a.php中的返回内容是什么?
seai 2010-06-25
  • 打赏
  • 举报
回复
我把b.php改成这样

<?php
echo "first line";
sleep(6);
$content = "写入的内容";
$fileopen = fopen("testcurl.txt","a+");
fwrite($fileopen,$content);
fclose($fileopen);
echo "after 6 second";
?>

结果,测试中从a.php浏览时没有生成文件,只有从b.php浏览时有生成文件。。。
amani11 2010-06-25
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 seai 的回复:]

简单说就是希望,不论请求时指定多少的时间,被请求的脚本都希望按照b.php自己的超时时间去执行。
[/Quote]

就是这样的,,,,,,,

不信,你可以试试b.php,sleep(20)后写一个文件
CunningBoy 2010-06-25
  • 打赏
  • 举报
回复
1、既然是同步方式执行的话,是否意味着,如果CURLOPT_TIMEOUT指定时间小于被请求页面实际时间的话,将导致被请求脚本不能完全执行呢?

是地。

比如b.php中需要做一系列数据的操作,会不会导致那些操作不能被执行完?如果这样,那么如何指定异步方式执行?

cURL本身没有异步执行,你可以自己写多线程去模拟异步。

2、上面的情况似乎是缓存的问题。后来又在b.php不加输出的情况下也会2秒才执行完。假设不是缓存的原因,请问为什么不加输出时,请求页面没有等待足够的时间才返回呢?

再次提醒,不是2秒执行完,而是2秒到了还没有完全返回b.php,只返回了一部分。
seai 2010-06-25
  • 打赏
  • 举报
回复
简单说就是希望,不论请求时指定多少的时间,被请求的脚本都希望按照b.php自己的超时时间去执行。
seai 2010-06-25
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 cunningboy 的回复:]

因为你请求的b.php,这个页面是存在的,只是在6秒内没有内容输出。
所以a.php用curl可以获取b.php但是实际上没有内容。

你可以将b.php改为:
<?php
echo "first line";
sleep(6);
echo "after 6 second";
?>

然后用a.php去取b.php看看返回的内容是什么。
[/Quote]

嗯,这样测试对了。

还是有两个疑问请教楼上:
1、既然是同步方式执行的话,是否意味着,如果CURLOPT_TIMEOUT指定时间小于被请求页面实际时间的话,将导致被请求脚本不能完全执行呢?比如b.php中需要做一系列数据的操作,会不会导致那些操作不能被执行完?如果这样,那么如何指定异步方式执行?
2、上面的情况似乎是缓存的问题。后来又在b.php不加输出的情况下也会2秒才执行完。假设不是缓存的原因,请问为什么不加输出时,请求页面没有等待足够的时间才返回呢?
amani11 2010-06-25
  • 打赏
  • 举报
回复
有没有朋友有环境的测试下,我测了3楼代码,,,,输出是 2

Apache/2.2.11 (Win32) PHP/5.2.8
CunningBoy 2010-06-25
  • 打赏
  • 举报
回复
因为你请求的b.php,这个页面是存在的,只是在6秒内没有内容输出。
所以a.php用curl可以获取b.php但是实际上没有内容。

你可以将b.php改为:
<?php
echo "first line";
sleep(6);
echo "after 6 second";
?>

然后用a.php去取b.php看看返回的内容是什么。
seai 2010-06-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dingsongtao 的回复:]

同步
CURLOPT_TIMEOUT是CURL的超时限制,并不是说要让它执行那么多秒。而是说超过那么多秒,即终止,如果不需要那么长时间就能获取到结果,则提前完成(就不在CURLOPT_TIMEOUT限制之内)。
[/Quote]

被请求的页面本身100%肯定要6秒以上执行完,超时时间设置成2秒,却能毫秒内返回,这是什么原因呢?
seai 2010-06-25
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 amani11 的回复:]

我怀疑不对


$start = time();//记录下时间
$ch = curl_init("http://127.0.0.1/post.php");
$ch_arr = array(CURLOPT_TIMEOUT=>2,CURLOPT_RETURNTRANSFER=>1);//2秒超时限制?
curl_setopt_array($ch,$ch_arr);
curl_exec(……
[/Quote]

用你的代码是了,确认是毫秒级的,时间输出是0。

我说明下,即使前面的代码,我说的毫秒级,不是感觉到的,而是firebug里显示的“等待时间”。

CunningBoy 2010-06-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 seai 的回复:]

同步执行,不是应该2秒后才完成吗?
[/Quote]

CURLOPT_TIMEOUT是指超时时间,不是说2秒后才完成执行,而是指如果curl_exec()大于2秒还没有执行完成,就不等结果直接返回了。
goldily 2010-06-25
  • 打赏
  • 举报
回复
同步执行,CURLOPT_TIMEOUT是设定超时时间,超过这个时间将不去读取页面了。
Dleno 2010-06-25
  • 打赏
  • 举报
回复
同步
CURLOPT_TIMEOUT是CURL的超时限制,并不是说要让它执行那么多秒。而是说超过那么多秒,即终止,如果不需要那么长时间就能获取到结果,则提前完成(就不在CURLOPT_TIMEOUT限制之内)。
amani11 2010-06-25
  • 打赏
  • 举报
回复
我打错字了,,,,,http://127.0.0.1/b.php
amani11 2010-06-25
  • 打赏
  • 举报
回复
我怀疑不对


$start = time();//记录下时间
$ch = curl_init("http://127.0.0.1/post.php");
$ch_arr = array(CURLOPT_TIMEOUT=>2,CURLOPT_RETURNTRANSFER=>1);//2秒超时限制?
curl_setopt_array($ch,$ch_arr);
curl_exec($ch);
curl_close($ch);
echo time() - $start;//比对时间,试试,是不是2秒??????毫秒级是错觉吧?
加载更多回复(2)
<?php class Request{ public static function post($url, $post_data = '', $timeout = 5){//curl $ch = curl_init(); curl_setopt ($ch, CURLOPT_URL, $url); curl_setopt ($ch, CURLOPT_POST, 1); if($post_data != ''){ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); } curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_HEADER, false); $file_contents = curl_exec($ch); curl_close($ch);Post()函数用于向窗口发送非PowerBuilder预定义事件的消息,这个窗口可以是PowerBuilder应用的窗口,也可以是其它应用的窗口。Post()函数把发送的消息放置在指定窗口消息队列的尾部,然后返回到应用程序中,它并不等待相应事件事件处理程序的执行。这一点与Send()函数不同,Send()函数直接触发指定窗口相应的事件,执行事件处理程序后返回到调用应用中。因此,我们说Post()函数采用的是异步方式,Send()函数采用的是同步方式。Post()函数的参数handle指定接收消息的窗口句柄,对PowerBuilder窗口来说,使用Handle()函数可以得到该句柄。对其它应用程序的窗口来说,可以调用系统API函数查找窗口并得到相应窗口的句柄。如果应用程序要邮寄PowerBuilder定义事件(包括预定义事件和用户定义事件),那么使用PostEvent()函数既简单有方便。当应用程序在long参数位置指定一个字符串时,Post()函数复制一个该字符串的副本,然后将副本的地址传送给指定窗口。

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧