Skip to content

Instantly share code, notes, and snippets.

@copperwall
Last active May 6, 2018 11:23
Show Gist options
  • Save copperwall/784c73cfc08570afef107e2d2663f2af to your computer and use it in GitHub Desktop.
Save copperwall/784c73cfc08570afef107e2d2663f2af to your computer and use it in GitHub Desktop.
<?php
describe(strict_types = 1);
/**
* Example code for consuming data from a Store API (called Storeify) and chaining generators
* together to filter, map, and eventually reduce all Order data into a
* daily revenue total.
*/
function getOrdersFromLastDay(): iterable {
$limit = 20;
$requestParams = [
'lastUpdatedAfter' => new DateTime('yesterday'),
'limit' => $limit,
'offset' => 0
];
$orders = [];
do {
// Grab a batch of orders from Storeify and yield from that list.
$orders = Storeify::getOrders($requestParams);
yield from $orders;
$requestParams['offset'] += $limit;
} while (!empty($orders));
}
/**
* Consumes a generator that produces lists of products
* and produces a new generator that yields a flat list
* of products.
*/
function flatten(iterable $itr): iterable {
foreach ($itr as $products) {
yield from $products;
}
}
/**
* Assume orders have a Shipping Country and a list of Products
* [
* 'ShipCountry' => 'US',
* 'Products' => [
* [ 'name' => 'Pro Tech Toolkit', 'price' => 59.95, 'quantity' => 2],
* [ 'name' => 'iPhone 6 Battery', 'price' => 24.99, 'quantity' => 1]
* ]
* ]
*/
$orders = getOrdersFromLastDay();
// Flatten list of orders into list of all products sold.
$allProducts = flatten(iterator_map(function($order) {
return $order['Products'];
}, $orders));
// Only include 'Pro Tech Toolkit' purchases.
$toolkitProducts = iterator_filter(function($product) {
return $product['name'] === 'Pro Tech Toolkit';
}, $allProducts);
// Up until this point, no work has actually been done.
// $toolkitProducts is a generator can be passed around to other functions
// as a lazy stream of pro tech toolkit products.
// Once iterator_reduce is called, it begins winding its way through
// the composed generators and actually pulling down resources from the Store API
// and mapping and filtering them.
$dailyToolkitRevenue = iterator_reduce(function($total, $toolkit) {
return $total + ($toolkit['price'] * $toolkit['quantity']);
}, $toolkitProducts, 0);
@hranicka
Copy link

hranicka commented May 6, 2018

Hello, thanks for the article on Medium about generators!
There is just a typo: describe(strict_types = 1); should be declare(strict_types = 1);.

Thanks,
Jaroslav

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment