【问题标题】:Behat: Goutte/Guzzle downloading file via cURL "Warning: curl_setopt_array(): 3607 is not a valid File-Handle resource"Behat:Goutte/Guzzle 通过 cURL 下载文件“警告:curl_setopt_array():3607 不是有效的文件句柄资源”
【发布时间】:2015-11-19 17:17:21
【问题描述】:

使用 Behat 测试一些涉及下载文件的行为。使用 Goutte 和 Guzzle 拦截文件下载,以便我可以在另一个步骤中与之交互。

//Where to put the file
$tmpFile = 'download.zip';
$handle  = fopen($tmpFile, 'w');

$goutteDriver = $this->getSession()->getDriver();
$goutteClient = $goutteDriver->getClient();

/** @var \Guzzle\Http\Client $guzzleClient */
$guzzleClient = $goutteClient->getClient();
$guzzleClient->getConfig()->set('curl.options', [CURLOPT_FILE => $handle]);
$guzzleClient->setSslVerification(false);

$goutteDriver->visit($url);

fclose($handle);

它工作正常,但如果我在同一步骤中连续运行两个不同的场景,我会收到错误:

“警告:curl_setopt_array(): 3607 不是有效的文件句柄资源”

编辑:我尝试不关闭 $handle,然后它之后的每个场景都只是跳过而不是运行。还尝试使用$guzzleClient->getConfig()->remove('curl.options');,这导致后面的步骤不起作用。

Edit2:问题示例:

我采取了所有其他步骤,除了我在此处包含代码的步骤,即下载 zip 文件。

我的功能现在基本上是这样的:

 Background:
   Given I am logged in as an admin

 Scenario: A
    When I click "Export All"

 Scenario: B
    When I click "Export All"

当我运行它时,输出如下所示:

  Background:                        
    Given I am logged in as an admin

  Scenario: A
    When I click "Export All" 

  Scenario: B

Warning: curl_setopt_array(): supplied argument is not a valid File-Handle resource in C:\wamp\www\cems2\vendor\guzzle\guzzle\src\Guzzle\Http\Curl\CurlHandle.php on line 219

Call Stack:
    0.0000     131776   1. {main}() C:\wamp\www\cems2\vendor\behat\behat\bin\behat:0
    0.0360    1699576   2. Symfony\Component\Console\Application->run() C:\wamp\www\cems2\vendor\behat\behat\bin\behat:32


When I click "Export All" (skipped)

后面是一个堆栈跟踪,我在其中找不到任何对我的任何代码的引用。完整的堆栈跟踪在这里:http://pastebin.com/Fv48gdYm

【问题讨论】:

  • 听起来 fopen 第二次失败了,$handle === false。您显然可以对此进行测试。为什么会失败 - 文件是否正在使用中?场景是否同时运行并尝试同时写入同一个文件?
  • 错误实际上发生在步骤之前,甚至发生在下一个场景的第一步之前。他们一个接一个地跑。
  • 错误出现在哪里,我假设在上面代码的set curl.options行。
  • 不,它会在下一个场景运行时立即发生。据我所知,在下一个场景的某种设置中。堆栈跟踪没有指向我的任何代码...
  • 第一个运行,所有步骤都通过,然后第二个场景打印标题,然后立即出错。如果我自己运行每个都没有错误。

标签: php curl behat guzzle goutte


【解决方案1】:

我删除了设置 curl opt 文件的部分,而是将响应的内容读入文件句柄。

//Where to put the file
$tmpFile = 'download.zip';
$handle  = fopen($tmpFile, 'w');

$goutteDriver = $this->getSession()->getDriver();
$goutteClient = $goutteDriver->getClient();

/** @var \Guzzle\Http\Client $guzzleClient */
$guzzleClient = $goutteClient->getClient();

//Remove this
//$guzzleClient->getConfig()->set('curl.options', [CURLOPT_FILE => $handle]);

$guzzleClient->setSslVerification(false);

$goutteDriver->visit($url);

//Add this
fwrite($handle, $goutteDriver->getContent());
fclose($handle); 

现在一切正常。

【讨论】:

  • 您应该可以将顶部和底部两行代码简化为:file_put_contents('download.zip', $goutteDriver->getContent());
  • 谢谢@elazar!完成!
猜你喜欢
  • 2019-08-03
  • 2014-05-03
  • 2012-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多