PHPackages                             leinonen/php-dataloader - 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. [API Development](/categories/api)
4. /
5. leinonen/php-dataloader

ActiveLibrary[API Development](/categories/api)

leinonen/php-dataloader
=======================

Port of Facebook's dataloader to PHP

3.0.0(11mo ago)1615.8k↓50%5[3 issues](https://github.com/lordthorzonus/php-dataloader/issues)[1 PRs](https://github.com/lordthorzonus/php-dataloader/pulls)MITPHPPHP ^7.4.0|^8.0CI passing

Since Jan 11Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/lordthorzonus/php-dataloader)[ Packagist](https://packagist.org/packages/leinonen/php-dataloader)[ RSS](/packages/leinonen-php-dataloader/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (7)Dependencies (3)Versions (11)Used By (0)

PHP DataLoader
==============

[](#php-dataloader)

Port of the [Facebook's DataLoader](https://github.com/facebook/dataloader) to PHP. Async superpowers from [ReactPHP](https://github.com/reactphp).

DataLoader is a generic utility to be used as part of your application's data fetching layer to provide a simplified and consistent API over various remote data sources such as databases or web services via batching and caching.

[![Build Status](https://camo.githubusercontent.com/3c6c36d91fd1debcc982d599cdd593358c38e979d9e6c40554cc5fc20cc58b0f/68747470733a2f2f6170702e7472617669732d63692e636f6d2f6c6f726474686f727a6f6e75732f7068702d646174616c6f616465722e7376673f6272616e63683d6d6173746572)](https://app.travis-ci.com/lordthorzonus/php-dataloader)[![Code Coverage](https://camo.githubusercontent.com/1c9bdc76c02614e4e1498fd9c6b3238feccb7ccf97cee022d739669ab579d323/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6c6f726474686f727a6f6e75732f7068702d646174616c6f616465722f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/lordthorzonus/php-dataloader/?branch=master)[![Latest Stable Version](https://camo.githubusercontent.com/3c5368dfd5446943d78c48c8fae84fa45d796505f623328105ec2fe4b45d7db9/68747470733a2f2f706f7365722e707567782e6f72672f6c65696e6f6e656e2f7068702d646174616c6f616465722f762f737461626c65)](https://packagist.org/packages/leinonen/php-dataloader)[![Total Downloads](https://camo.githubusercontent.com/44ba2e86c6a4d833406eab2d92690e7557e90ddc703a221253ff4622df236b01/68747470733a2f2f706f7365722e707567782e6f72672f6c65696e6f6e656e2f7068702d646174616c6f616465722f646f776e6c6f616473)](https://packagist.org/packages/leinonen/php-dataloader)[![Latest Unstable Version](https://camo.githubusercontent.com/61c6c8fb44c7efed56e92ab3d5d19f71df1819a66a25485fc8eb440a5a7ca6ff/68747470733a2f2f706f7365722e707567782e6f72672f6c65696e6f6e656e2f7068702d646174616c6f616465722f762f756e737461626c65)](https://packagist.org/packages/leinonen/php-dataloader)[![License](https://camo.githubusercontent.com/05b450fb55373af0d83039275e90c9f9b07fd71038f39017fedf8a78e93b8771/68747470733a2f2f706f7365722e707567782e6f72672f6c65696e6f6e656e2f7068702d646174616c6f616465722f6c6963656e7365)](https://packagist.org/packages/leinonen/php-dataloader)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/36018dcf080b28bc20a60db6a03b117334fab11be18c320dcc567eb831eaf6e7/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6c6f726474686f727a6f6e75732f7068702d646174616c6f616465722f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/lordthorzonus/php-dataloader/?branch=master)[![SensioLabsInsight](https://camo.githubusercontent.com/c127ea4457e8cea6858ce62e2b038c60fa6e102b18c08c54f93a85a5aa72df94/68747470733a2f2f696e73696768742e73656e73696f6c6162732e636f6d2f70726f6a656374732f34346132653066332d636465362d343862392d623438342d3832343361363431343564652f6d696e692e706e67)](https://insight.sensiolabs.com/projects/44a2e0f3-cde6-48b9-b484-8243a64145de)

Table of contents
=================

[](#table-of-contents)

- [Installation](#installation)
- [Usage](#usage)
    - [Batch function](#batch-function)
    - [Caching](#caching)
    - [Usage with common ORM's](#usage-with-common-orms)
- [API](#api)

Installation
------------

[](#installation)

Require this package, with [Composer](https://getcomposer.org/), in the root directory of your project.

```
composer require leinonen/php-dataloader
```

Usage
-----

[](#usage)

To create a loader you must provide a batching function, an internal memoization cache and the global event loop from ReactPHP. To have better understanding what the ReactPHP event loop is and how it is used refer to it's [documentation](https://github.com/reactphp/event-loop).

```
use leinonen\DataLoader\Dataloader;
use React\EventLoop\Factory;

$eventLoop = Factory::create();

$bandLoader = new DataLoader(
    function ($keys) {
        // Batch load bands with given keys.
    },
    $eventLoop,
    new CacheMap()
);
```

Then load individual values from the loader. DataLoader will coalesce all individual loads which occur within a single tick of the event loop and then call your batch function with all requested keys.

```
$bandLoader->load(1)->then(function ($band) {
    echo "Band #${$band->getId()} loaded";
});

$bandLoader->load(2)->then(function ($band) {
    echo "Band #${$band->getId()} loaded";
});

$eventLoop->run(); // The batch function will be called with keys [1, 2] at this point
```

Calling the load function returns `React\Promise\Promise`s. To have a better understanding how to use promises within PHP refer to the [ReactPHP docs](https://github.com/reactphp/promise).

### Batch Function

[](#batch-function)

The batch loading function accepts an array of keys, and must return a Promise which resolves to an Array of values. There are a few other constraints:

- The Array of values must be the same length as the Array of keys.
- Each index in the Array of values must correspond to the same index in the Array of keys i.e. The order of the batch loaded results must be the same as the order of given keys.

For example, if your batch function was provided the Array of keys: `[2, 9, 6, 1]`, and the batch loaded results were:

```
[
    ['id' => 1, 'name' => 'Mojo Waves'],
    ['id' => 2, 'name' => 'Pleasure Hazard'],
    ['id' => 9, 'name' => 'Leka'],
]
```

The loaded results are in a different order that we requested which is quite common with most of the relation dbs for example. Also result for key `6` is omitted which we can interpret as no value existing for that key.

To satisfy the constraints of the batch function we need to modify the results to be the same length as the Array of keys and re-order them to ensure each index aligns with the original keys:

```
[
    ['id' => 2, 'name' => 'Pleasure Hazard'],
    ['id' => 9, 'name' => 'Leka'],
    null,
    ['id' => 1, 'name' => 'Mojo Waves'],
]
```

### Caching

[](#caching)

DataLoader provides a memoization cache for all loads which occur in a single request to your application. After `load()` is called once with a given key, the resulting value is cached to eliminate redundant loads.

In addition to relieving load on your data storage, caching results per-request also creates fewer objects which may relieve memory pressure on your application:

```
$promise1 = $bandLoader->load(1);
$promise2 = $bandLoader->load(2);

($promise1 === $promise2) // true
```

DataLoader caching does not replace Redis, Memcache, or any other shared application-level cache. DataLoader is first and foremost a data loading mechanism, and its cache only serves the purpose of not repeatedly loading the same data in the context of a single request to your Application. To do this it utilizes the CacheMap given as a constructor argument.

This package provides a simple CacheMap (`leinonen\DataLoader\CacheMap`) implementation to be used with DataLoader. You can also use your custom CacheMap with various different [cache algorithms](https://en.wikipedia.org/wiki/Cache_algorithms) by implementing the `leinonen\DataLoader\CacheMapInterface`.

### Usage with common ORM's

[](#usage-with-common-orms)

#### Eloquent (Laravel)

[](#eloquent-laravel)

```
$userByIdLoader = new DataLoader(function ($ids) {
  $users = User::findMany($ids);

  // Make sure that the users are on the same order as the given ids for the loader
  $orderedUsers = collect($ids)->map(function ($id) use ($users) {
    return $users->first(function ($user) use ($id) {
      return $user->id === $id;
    });
  });

   return \React\Promise\resolve($orderedUsers);
}, $eventLoopFromIoCContainer, $cacheMapFromIoCContainer);
```

#### ActiveRecord (Yii2)

[](#activerecord-yii2)

```
$usersByIdLoader = new DataLoader(function ($ids) {
    $users = User::find()->where(['id' => $ids])->all();

    $orderedUsers = \array_map(function ($id) use ($users) {
        foreach ($users as $user) {
            if ($user->id === $id) {
                return $user;
            }
        }

        return null;
    }, $ids);

    return \React\Promise\resolve($orderedUsers);
}, $eventLoopFromDiContainer, $cacheMapImplementationFromDiContainer);
```

API
---

[](#api)

### `load($key)`

[](#loadkey)

Loads a key, returning a `Promise` for the value represented by that key.

- `@param mixed $key An key value to load.`

### `loadMany($keys)`

[](#loadmanykeys)

Loads multiple keys, promising an array of values.

This is equivalent to the more verbose:

```
$promises = \React\Promise\all([
  $myLoader->load('a'),
  $myLoader->load('b')
]);
```

- `@param array $keys: An array of key values to load.`

### `clear($key)`

[](#clearkey)

Clears the value at `$key` from the cache, if it exists.

- `@param mixed key: An key value to clear.`

### `clearAll()`

[](#clearall)

Clears the entire cache.

### `prime($key, $value)`

[](#primekey-value)

Primes the cache with the provided key and value. If the key already exists, no change is made. (To forcefully prime the cache, clear the key first with `$loader->clear($key)->prime($key, $value)`.

###  Health Score

51

—

FairBetter than 96% of packages

Maintenance64

Regular maintenance activity

Popularity34

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor1

Top contributor holds 93.4% 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

Every ~513 days

Recently: every ~755 days

Total

7

Last Release

333d ago

Major Versions

0.2.0 → 1.0.02017-05-16

1.0.0 → 2.0.02020-05-07

2.1.0 → 3.0.02025-06-20

PHP version history (2 changes)2.0.0PHP ^7.4.0

2.1.0PHP ^7.4.0|^8.0

### Community

Maintainers

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

---

Top Contributors

[![lordthorzonus](https://avatars.githubusercontent.com/u/8689671?v=4)](https://github.com/lordthorzonus "lordthorzonus (71 commits)")[![enumag](https://avatars.githubusercontent.com/u/539462?v=4)](https://github.com/enumag "enumag (2 commits)")[![MartynasKasp](https://avatars.githubusercontent.com/u/33058459?v=4)](https://github.com/MartynasKasp "MartynasKasp (2 commits)")[![renovate-bot](https://avatars.githubusercontent.com/u/25180681?v=4)](https://github.com/renovate-bot "renovate-bot (1 commits)")

---

Tags

async-phpbatch-loadingbatchingdataloaderfacebook-dataloaderphpphp-dataloadergraphqldataLoaderbatch loading

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/leinonen-php-dataloader/health.svg)

```
[![Health](https://phpackages.com/badges/leinonen-php-dataloader/health.svg)](https://phpackages.com/packages/leinonen-php-dataloader)
```

###  Alternatives

[webonyx/graphql-php

A PHP port of GraphQL reference implementation

4.7k77.3M333](/packages/webonyx-graphql-php)[nuwave/lighthouse

A framework for serving GraphQL from Laravel

3.5k10.7M93](/packages/nuwave-lighthouse)[team-reflex/discord-php

An unofficial API to interact with the voice and text service Discord.

1.1k379.4k24](/packages/team-reflex-discord-php)[overblog/graphql-bundle

This bundle provides tools to build a GraphQL server in your Symfony App.

8027.9M28](/packages/overblog-graphql-bundle)[smile/elasticsuite

Magento 2 merchandising and search engine built on ElasticSearch

8044.5M33](/packages/smile-elasticsuite)[gmostafa/php-graphql-client

GraphQL client and query builder.

3217.6M25](/packages/gmostafa-php-graphql-client)

PHPackages © 2026

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