Skip to content

Commit 8adc4f5

Browse files
committed
add support for curl_multi_getcontent
s
1 parent 469ac33 commit 8adc4f5

File tree

3 files changed

+94
-2
lines changed

3 files changed

+94
-2
lines changed

src/VCR/CodeTransform/CurlCodeTransform.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class CurlCodeTransform extends AbstractCodeTransform
2121
'/(?<!::|->|\w_)\\\?curl_multi_remove_handle\s*\(/i' => '\VCR\LibraryHooks\CurlHook::curl_multi_remove_handle(',
2222
'/(?<!::|->|\w_)\\\?curl_multi_exec\s*\(/i' => '\VCR\LibraryHooks\CurlHook::curl_multi_exec(',
2323
'/(?<!::|->|\w_)\\\?curl_multi_info_read\s*\(/i' => '\VCR\LibraryHooks\CurlHook::curl_multi_info_read(',
24+
'/(?<!::|->|\w_)\\\?curl_multi_getcontent\s*\(/i' => '\VCR\LibraryHooks\CurlHook::curl_multi_getcontent(',
2425
'/(?<!::|->|\w_)\\\?curl_reset\s*\(/i' => '\VCR\LibraryHooks\CurlHook::curl_reset(',
2526
'/(?<!::|->|\w_)\\\?curl_error\s*\(/i' => '\VCR\LibraryHooks\CurlHook::curl_error(',
2627
'/(?<!::|->|\w_)\\\?curl_errno\s*\(/i' => '\VCR\LibraryHooks\CurlHook::curl_errno(',

src/VCR/LibraryHooks/CurlHook.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class CurlHook implements LibraryHook
3737
protected static $responses = [];
3838

3939
/**
40-
* @var array<int,mixed> additinal curl options, which are not stored within a request
40+
* @var array<int,mixed> additional curl options, which are not stored within a request
4141
*/
4242
protected static $curlOptions = [];
4343

@@ -51,6 +51,11 @@ class CurlHook implements LibraryHook
5151
*/
5252
protected static $multiExecLastChs = [];
5353

54+
/**
55+
* @var array<int, string|null> return values of curl_multi responses
56+
*/
57+
protected static $multiReturnValues = [];
58+
5459
/**
5560
* @var CurlException[] last cURL error, as a CurlException
5661
*/
@@ -276,7 +281,7 @@ public static function curlMultiExec($multiHandle, ?int &$stillRunning): int
276281
foreach (self::$multiHandles[(int) $multiHandle] as $curlHandle) {
277282
if (!isset(self::$responses[(int) $curlHandle])) {
278283
self::$multiExecLastChs[] = $curlHandle;
279-
self::curlExec($curlHandle);
284+
self::$multiReturnValues[(int) $curlHandle] = self::curlExec($curlHandle);
280285
}
281286
}
282287
}
@@ -306,6 +311,20 @@ public static function curlMultiInfoRead()
306311
return false;
307312
}
308313

314+
/**
315+
* Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set.
316+
*
317+
* @see https://www.php.net/manual/en/function.curl-multi-getcontent.php
318+
*
319+
* @param resource $curlHandle
320+
*
321+
* @return string|null return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set
322+
*/
323+
public static function curlMultiGetcontent($curlHandle): ?string
324+
{
325+
return self::$multiReturnValues[(int) $curlHandle] ?? null;
326+
}
327+
309328
/**
310329
* Get information regarding a specific transfer.
311330
*

tests/VCR/LibraryHooks/CurlHookTest.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,78 @@ function () use ($testClass): void {
373373
curl_multi_close($curlMultiHandle);
374374
}
375375

376+
public function testShouldReturnMultiCallValues(): void
377+
{
378+
$testClass = $this;
379+
$callCount = 0;
380+
$this->curlHook->enable(
381+
function (Request $request) use ($testClass, &$callCount) {
382+
$testClass->assertEquals(
383+
'example.com',
384+
$request->getHost(),
385+
''
386+
);
387+
++$callCount;
388+
389+
return new Response('200', [], $testClass->expected.$callCount);
390+
}
391+
);
392+
393+
$curlHandle1 = curl_init('http://example.com');
394+
Assertion::isResource($curlHandle1);
395+
curl_setopt($curlHandle1, \CURLOPT_RETURNTRANSFER, true);
396+
$curlHandle2 = curl_init('http://example.com');
397+
Assertion::isResource($curlHandle2);
398+
curl_setopt($curlHandle2, \CURLOPT_RETURNTRANSFER, true);
399+
$curlHandle3 = curl_init('http://example.com');
400+
Assertion::isResource($curlHandle3);
401+
curl_setopt($curlHandle3, \CURLOPT_RETURNTRANSFER, false);
402+
403+
$curlMultiHandle = curl_multi_init();
404+
Assertion::isResource($curlMultiHandle);
405+
curl_multi_add_handle($curlMultiHandle, $curlHandle1);
406+
curl_multi_add_handle($curlMultiHandle, $curlHandle2);
407+
curl_multi_add_handle($curlMultiHandle, $curlHandle3);
408+
409+
$stillRunning = null;
410+
ob_start();
411+
curl_multi_exec($curlMultiHandle, $stillRunning);
412+
$output = ob_get_contents();
413+
ob_end_clean();
414+
415+
$returnValue1 = curl_multi_getcontent($curlHandle1);
416+
$returnValue2 = curl_multi_getcontent($curlHandle2);
417+
$returnValue3 = curl_multi_getcontent($curlHandle3);
418+
419+
curl_multi_remove_handle($curlMultiHandle, $curlHandle1);
420+
curl_multi_remove_handle($curlMultiHandle, $curlHandle2);
421+
curl_multi_remove_handle($curlMultiHandle, $curlHandle3);
422+
curl_multi_close($curlMultiHandle);
423+
424+
$this->curlHook->disable();
425+
426+
$this->assertEquals(3, $callCount, 'Hook should have been called thrice.');
427+
$this->assertSame(
428+
$this->expected.'1',
429+
$returnValue1,
430+
'When called with the first handle the curl_multi_getcontent should return the body of the first response.'
431+
);
432+
433+
$this->assertSame(
434+
$this->expected.'2',
435+
$returnValue2,
436+
'When called with the second handle the curl_multi_getcontent should return the body of the second response.'
437+
);
438+
439+
$this->assertNull($returnValue3, 'When called with the third handle the curl_multi_getcontent should return null.');
440+
441+
$this->assertSame(
442+
$this->expected.'3',
443+
$output,
444+
'The third response was not written on stdout.'
445+
);
446+
}
447+
376448
/**
377449
* @requires PHP 5.5.0
378450
*/

0 commit comments

Comments
 (0)