PHPackages                             alexpw/multicurl-iterator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. alexpw/multicurl-iterator

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

alexpw/multicurl-iterator
=========================

0.1.0(11y ago)066PHPPHP &gt;=5.3.0

Since Sep 15Pushed 11y ago1 watchersCompare

[ Source](https://github.com/alexpw/multicurl-iterator)[ Packagist](https://packagist.org/packages/alexpw/multicurl-iterator)[ RSS](/packages/alexpw-multicurl-iterator/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (2)Used By (0)

Multicurl Iterator
==================

[](#multicurl-iterator)

This iterator class makes it simple to use PHP's multicurl effectively.

However, it does not curl\_init() for you. Instead, it gives you full control over what requests you'll be making.

Install
-------

[](#install)

Composer/Packagist

-

Basic usage
-----------

[](#basic-usage)

1. You instantiate a Multicurl\\Iterator instance.
2. You give it some curl resource handles from curl\_init().
3. You start foreach'ing over the results.

```
$mci = new Alexpw\Multicurl\Iterator();

foreach ($curl_handles as $handle) {
	$mci->add($handle /*[, mixed $data = null] */);
}

foreach ($mci as $result) {
	doSomething($result);
}
```

It executes as many curl requests in parallel as you allow it. As soon as the first response is received, the foreach is allowed to continue, and you are given the `$result` of parsing the response.

### The contents of $result

[](#the-contents-of-result)

An approximation:

```
$result = curl_getinfo($ch);
$result['handle']   = $ch;
$result['data']     = // Optional data associated with curl handle
$result['header']   = $header_string_or_parsed_array;
$result['body']     = $body_string;
$result['errno']    = curl_errno($ch);
$result['error']    = curl_error($ch);
$result['errorstr'] = curl_errstr($ch); // when function_exists
```

### $data, or How to ID a Request

[](#data-or-how-to-id-a-request)

The results are returned out of order and as soon as they are ready, but you can ID them easily.

The most convenient: `$mci->add($handle, $data = null);`

$data can be anything that's meaningful to you:

- a unique id
- a copy of the request parameters
- whatever

Options
-------

[](#options)

- How many curl requests to execute simultaneously.

`$mci->setMaxExecuting(10); // default: 10 `

- Parse the response header as an array (if your request asked for headers). `$mci->setParseResponseHeader(true); // default: true`
- Whether to automatically close curl handles after using them.

`$mci->setCloseCurlHandles(true); // default: true`

Note, if you want to be able to reuse curl handles for retries or whatever, you'll need to manage and close them yourself.

Real world usage
----------------

[](#real-world-usage)

You don't need to create all of your curl handles in advance, they can be added at any time.

1. Setup your data
2. You instantiate a Multicurl\\Iterator instance.
3. You configure options.
4. You give it some curl resource handles from curl\_init().
5. You start foreach'ing over the results.

```
$article_ids       = array(1, 2, 3, 4 /*,...*/);
$article_id_chunks = array_chunk($article_ids, 50);

$curr_chunk   = 0;
$total_chunks = count($article_id_chunks);

function addArticlesToIterator($mci, $chunk)
{
	foreach ($chunk as $article_id) {
		$ch = initCurlHandleForArticle($article_id);
		$mci->add($ch, $article_id);
	}
}

$mci = new Alexpw\Multicurl\Iterator();
$mci->setMaxExecuting(6);

addArticlesToIterator($mci, $article_id_chunks[$curr_chunk++]);

foreach ($mci as $result) {
	if ($mci->getCountPendingRequests() < 10 &&
		$curr_chunk < $total_chunks) {
		addArticleRequests($mci, $article_id_chunks[$curr_chunk++]);
	}

	if ($result['errno'] !== 0) {
		logFailed($result);
	} elseif ($result['http_code'] === 408) {
		$ch = initCurlHandleForRetry($result);
		$mci->add($ch);
    } else {
		doSomething($result);
    }
}
```

License
-------

[](#license)

Multicurl Iterator is licensed under the MIT License - see the LICENSE file for details.

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

4263d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a63c5f8f6c526c76097bb11d2f1c0b622af9f724619ad603ff0e6d052762eee2?d=identicon)[alexpw](/maintainers/alexpw)

---

Top Contributors

[![alexpw](https://avatars.githubusercontent.com/u/347573?v=4)](https://github.com/alexpw "alexpw (1 commits)")

### Embed Badge

![Health badge](/badges/alexpw-multicurl-iterator/health.svg)

```
[![Health](https://phpackages.com/badges/alexpw-multicurl-iterator/health.svg)](https://phpackages.com/packages/alexpw-multicurl-iterator)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
