curl: Add curl_multi_get_handles() (#16363)

see https://curl.se/libcurl/c/curl_multi_get_handles.html
This commit is contained in:
Tim Düsterhus 2024-10-16 16:24:04 +02:00 committed by GitHub
parent b7fd773cc6
commit cb6025cdac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 111 additions and 1 deletions

3
NEWS
View file

@ -5,6 +5,9 @@ PHP NEWS
- COM:
. Fix property access of PHP objects wrapped in variant. (cmb)
- Curl:
. Added curl_multi_get_handles(). (timwolla)
- DOM:
. Added Dom\Element::$outerHTML. (nielsdos)

View file

@ -78,6 +78,11 @@ PHP 8.5 UPGRADE NOTES
6. New Functions
========================================
- Curl:
. curl_multi_get_handles() allows retrieving all CurlHandles current
attached to a CurlMultiHandle. This includes both handles added using
curl_multi_add_handle() and handles accepted by CURLMOPT_PUSHFUNCTION.
- PGSQL:
. pg_close_stmt offers an alternative way to close a prepared
statement from the DEALLOCATE sql command in that we can reuse

View file

@ -3702,6 +3702,8 @@ function curl_upkeep(CurlHandle $handle): bool {}
function curl_multi_add_handle(CurlMultiHandle $multi_handle, CurlHandle $handle): int {}
function curl_multi_get_handles(CurlMultiHandle $multi_handle): array {}
function curl_multi_close(CurlMultiHandle $multi_handle): void {}
function curl_multi_errno(CurlMultiHandle $multi_handle): int {}

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 6a6a7461b475bb10cef3048ee2c11ab0dd32f328 */
* Stub hash: e2800e5ecc33f092576c7afcdb98d89825809669 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_close, 0, 1, IS_VOID, 0)
ZEND_ARG_OBJ_INFO(0, handle, CurlHandle, 0)
@ -60,6 +60,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_multi_add_handle, 0, 2, IS_
ZEND_ARG_OBJ_INFO(0, handle, CurlHandle, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_multi_get_handles, 0, 1, IS_ARRAY, 0)
ZEND_ARG_OBJ_INFO(0, multi_handle, CurlMultiHandle, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_multi_close, 0, 1, IS_VOID, 0)
ZEND_ARG_OBJ_INFO(0, multi_handle, CurlMultiHandle, 0)
ZEND_END_ARG_INFO()
@ -153,6 +157,7 @@ ZEND_FUNCTION(curl_init);
ZEND_FUNCTION(curl_upkeep);
#endif
ZEND_FUNCTION(curl_multi_add_handle);
ZEND_FUNCTION(curl_multi_get_handles);
ZEND_FUNCTION(curl_multi_close);
ZEND_FUNCTION(curl_multi_errno);
ZEND_FUNCTION(curl_multi_exec);
@ -190,6 +195,7 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(curl_upkeep, arginfo_curl_upkeep)
#endif
ZEND_FE(curl_multi_add_handle, arginfo_curl_multi_add_handle)
ZEND_FE(curl_multi_get_handles, arginfo_curl_multi_get_handles)
ZEND_FE(curl_multi_close, arginfo_curl_multi_close)
ZEND_FE(curl_multi_errno, arginfo_curl_multi_errno)
ZEND_FE(curl_multi_exec, arginfo_curl_multi_exec)

View file

@ -174,6 +174,29 @@ PHP_FUNCTION(curl_multi_remove_handle)
}
/* }}} */
PHP_FUNCTION(curl_multi_get_handles)
{
zval *z_mh;
php_curlm *mh;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_OBJECT_OF_CLASS(z_mh, curl_multi_ce)
ZEND_PARSE_PARAMETERS_END();
mh = Z_CURL_MULTI_P(z_mh);
array_init(return_value);
zend_llist_position pos;
zval *pz_ch;
for (pz_ch = (zval *)zend_llist_get_first_ex(&mh->easyh, &pos); pz_ch;
pz_ch = (zval *)zend_llist_get_next_ex(&mh->easyh, &pos)) {
Z_TRY_ADDREF_P(pz_ch);
add_next_index_zval(return_value, pz_ch);
}
}
/* {{{ Get all the sockets associated with the cURL extension, which can then be "selected" */
PHP_FUNCTION(curl_multi_select)
{

View file

@ -0,0 +1,71 @@
--TEST--
array curl_multi_get_handles ( CurlMultiHandle $mh );
--EXTENSIONS--
curl
--FILE--
<?php
$urls = array(
"file://".__DIR__."/curl_testdata1.txt",
"file://".__DIR__."/curl_testdata2.txt",
);
$mh = curl_multi_init();
$map = new WeakMap();
foreach ($urls as $url) {
echo "Initializing {$url}.", PHP_EOL;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle($mh, $ch);
printf("%d handles are attached\n", count(curl_multi_get_handles($mh)));
$map[$ch] = $url;
}
do {
$status = curl_multi_exec($mh, $active);
if ($status !== CURLM_OK) {
throw new \Exception(curl_multi_strerror(curl_multi_errno($mh)));
}
if ($active) {
$activity = curl_multi_select($mh);
if ($activity === -1) {
throw new \Exception(curl_multi_strerror(curl_multi_errno($mh)));
}
}
while (($info = curl_multi_info_read($mh)) !== false) {
if ($info['msg'] === CURLMSG_DONE) {
$handle = $info['handle'];
$url = $map[$handle];
echo "Request to {$url} finished.", PHP_EOL;
printf("%d handles are attached\n", count(curl_multi_get_handles($mh)));
curl_multi_remove_handle($mh, $handle);
printf("%d handles are attached\n", count(curl_multi_get_handles($mh)));
if ($info['result'] === CURLE_OK) {
echo "Success.", PHP_EOL;
} else {
echo "Failure.", PHP_EOL;
}
}
}
} while ($active);
printf("%d handles are attached\n", count(curl_multi_get_handles($mh)));
?>
--EXPECTF--
Initializing %scurl_testdata1.txt.
1 handles are attached
Initializing %scurl_testdata2.txt.
2 handles are attached
Request to %scurl_testdata%d.txt finished.
2 handles are attached
1 handles are attached
Success.
Request to %scurl_testdata%d.txt finished.
1 handles are attached
0 handles are attached
Success.
0 handles are attached