SlideShare a Scribd company logo
A Functional Guide to
Cat Herding with PHP
Generators
The Filter/Map/Reduce Pattern for PHP
Generators
A Functional Guide to Cat Herding with PHP Generators
• Blog Post
http://markbakeruk.net/2016/01/19/a-functional-guide-to-cat-herding-with-
php-generators/
• Code Examples
https://github.com/MarkBaker/GeneratorFunctionExamples
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/1"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<trk>
<name>Roman 2015-11-23</name>
<trkseg>
<trkpt lat="53.54398800" lon="-2.7403680000">
<ele>146.100</ele><time>2015-11-23T11:05:07Z</time>
</trkpt>
<trkpt lat="53.54401600" lon="-2.7402620000">
<ele>141.300</ele><time>2015-11-23T11:05:15Z</time>
</trkpt>
...
<trkpt lat="53.54384500" lon="-2.7426130000">
<ele>110.500</ele><time>2015-11-23T14:58:57Z</time>
</trkpt>
</trkseg>
</trk>
</gpx>
A Functional Guide to Cat Herding with PHP Generators
namespace GpxReader;
class GpxHandler {
protected $gpxReader;
public function __construct($gpxFilename) {
$this->gpxReader = new XMLReader();
$this->gpxReader->open($gpxFilename);
}
public function getElements($elementType) {
while ($this->gpxReader->read()) {
if ($this->gpxReader->nodeType == XMLREADER::ELEMENT &&
$this->gpxReader->name == $elementType) {
$doc = new DOMDocument('1.0', 'UTF-8');
$xml = simplexml_import_dom($doc->importNode($this->gpxReader->expand(), true));
$gpxAttributes = $this->readAttributes($this->gpxReader);
$gpxElement = $this->readChildren($xml);
$gpxElement->position = $gpxAttributes;
yield $gpxElement->timestamp => $gpxElement;
}
}
}
}
A Functional Guide to Cat Herding with PHP Generators
// Create our initial Generator to read the gpx file
$gpxReader = new GpxReaderGpxHandler($gpxFilename);
// Iterate over the trackpoint set from the gpx file,
// displaying each point detail in turn
foreach ($gpxReader->getElements('trkpt') as $time => $element) {
printf(
'%s' . PHP_EOL . ' latitude: %7.4f longitude: %7.4f elevation: %d' . PHP_EOL,
$time->format('Y-m-d H:i:s'),
$element->position->latitude,
$element->position->longitude,
$element->elevation
);
}
A Functional Guide to Cat Herding with PHP Generators
2015-11-23 11:05:07
latitude: 53.5440 longitude: -2.7404 elevation: 146
2015-11-23 11:05:15
latitude: 53.5440 longitude: -2.7403 elevation: 141
2015-11-23 11:05:25
latitude: 53.5440 longitude: -2.7402 elevation: 140
...
2015-11-23 14:58:47
latitude: 53.5439 longitude: -2.7426 elevation: 103
2015-11-23 14:58:57
latitude: 53.5438 longitude: -2.7426 elevation: 110
A Functional Guide to Cat Herding with PHP Generators
Cat Herding with PHP Generators – Filter
• A filter selects only a subset of values from the Traversable.
• The rules for filtering are defined in a callback function.
• If no callback is provided, then only non-empty values are returned.
Cat Herding with PHP Generators – Filter
array_filter()
Filters elements of an array using a callback function.
array array_filter ( array $array [, callable $callback] )
Iterates over each value in the array passing them to the callback function. If the
callback function returns true, the current value from array is returned into the
result array, otherwise it is discarded. Array keys are preserved.
Cat Herding with PHP Generators – Filter
function notEmpty($value) {
return !empty($value);
}
/**
* Version of filter to use with versions of PHP prior to 5.6.0,
* without the `$flag` option
*
**/
function filter(Traversable $filter, Callable $callback = null) {
if ($callback === null) {
$callback = 'notEmpty';
}
foreach ($filter as $key => $value) {
if ($callback($value)) {
yield $key => $value;
}
}
}
Cat Herding with PHP Generators – Filter
array_filter()
Filters elements of an array using a callback function.
array array_filter ( array $array [, callable $callback] )
array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] )
Iterates over each value in the array passing them to the callback function. If the
callback function returns true, the current value from array is returned into the
result array, otherwise it is discarded. Array keys are preserved.
[PHP < 5.6.0]
[PHP >= 5.6.0]
Cat Herding with PHP Generators – Filter
/**
* The `$flag` option (and the constants ARRAY_FILTER_USE_KEY and ARRAY_FILTER_USE_BOTH)
* were introduced in PHP 5.6.0
*
**/
function filter(Traversable $filter, Callable $callback = null, $flag = 0) {
if ($callback === null) {
$callback = 'notEmpty';
}
foreach ($filter as $key => $value) {
switch($flag) {
case ARRAY_FILTER_USE_KEY:
...
case ARRAY_FILTER_USE_BOTH:
...
default:
...
}
}
}
Cat Herding with PHP Generators – Filter
• Time Range
Where was Roman between 11:30 and 12:00?
• Geo-Fencing (“Bounding Box”)
• Inside
Did Osiris go anywhere near the main road?
• Outside
Has Lexie left the house at all?
Cat Herding with PHP Generators – Filter
// Create our initial Generator to read the gpx file
$gpxReader = new GpxReaderGpxHandler($gpxFilename);
// Define the date/time filter parameters
$startTime = new DateTime('2015-03-02 13:20:00Z');
$endTime = new DateTime('2015-03-02 13:30:00Z');
// Create the filter callback with the date/time parameters we've just defined
$timeFilter = function($timestamp) use ($startTime, $endTime) {
return $timestamp >= $startTime && $timestamp <= $endTime;
};
Cat Herding with PHP Generators – Filter
// Iterate over the trackpoint set from the gpx file,
// displaying each point detail in turn
foreach (filter($gpxReader->getElements('trkpt'), $timeFilter, ARRAY_FILTER_USE_KEY)
as $time => $element) {
printf(
'%s' . PHP_EOL . ' latitude: %7.4f longitude: %7.4f elevation: %d' . PHP_EOL,
$time->format('Y-m-d H:i:s'),
$element->position->latitude,
$element->position->longitude,
$element->elevation
);
}
Cat Herding with PHP Generators – Filter
Cat Herding with PHP Generators – Filter
namespace GpxReaderHelpers;
class BoundingBox {
/**
* Identify whether a trackpoint falls inside the defined bounding box
*
* @param GpxReaderGpxElement The trackpoint
* @return boolean If the trackpoint falls outside (false)
* or inside (true) the bounding box
**/
public function inside(GpxReaderGpxElement $point) {
return (($point->position->longitude >= $this->left) &&
($point->position->longitude <= $this->right) &&
($point->position->latitude >= $this->bottom) &&
($point->position->latitude <= $this->top));
}
}
Cat Herding with PHP Generators – Filter
// Create our initial Generator to read the gpx file
$gpxReader = new GpxReaderGpxHandler($gpxFilename);
// Create a bounding box defining the coordinates we want to test each point against
// This bounding box is for inside the house/garden
$boundaries = new GpxReaderHelpersBoundingBox();
$boundaries->setLatitudes(53.54382, 53.54340);
$boundaries->setLongitudes(-2.74059, -2.74005);
// We want to set the filter to include only points inside the bounding box
$boundingBoxFilter = [$boundaries, 'inside'];
Cat Herding with PHP Generators – Filter
// Iterate over the trackpoint set from the gpx file,
// displaying each point detail in turn
foreach (filter($gpxReader->getElements('trkpt'), $boundingBoxFilter) as
$time => $element) {
printf(
'%s' . PHP_EOL . ' latitude: %7.4f longitude: %7.4f elevation: %d' . PHP_EOL,
$time->format('Y-m-d H:i:s'),
$element->position->latitude,
$element->position->longitude,
$element->elevation
);
}
Cat Herding with PHP Generators – Filter
// Iterate over the trackpoint set from the gpx file,
// displaying each point detail in turn
// applying both a time filter (12:00:00-12:20:00 on 2015-11-23)
// and a bounding box filter for inside the house/garden
foreach (filter(
filter(
$gpxReader->getElements('trkpt'), $timeFilter, ARRAY_FILTER_USE_KEY
),
$boundingBoxFilter
) as $time => $element) {
printf(
...
);
}
Cat Herding with PHP Generators
Osiris
Located
Achievement
Unlocked
Cat Herding with PHP Generators – Map
• A map is like a foreach loop that transforms each value in the
Traversable.
• Each input value is transformed into a new output value.
• The rules for the transformation are defined in a callback function.
Cat Herding with PHP Generators – Map
array_map()
Applies the callback to the elements of the given arrays.
array array_map ( callable $callback , array $array1 [, array $... ] )
array_map() returns an array containing all the elements of array1 after applying
the callback function to each one. The number of parameters that the callback
function accepts should match the number of arrays passed to the array_map().
Cat Herding with PHP Generators – Map
function map(Callable $callback, Traversable $iterator) {
foreach ($iterator as $key => $value) {
yield $key => $callback($value);
}
}
Cat Herding with PHP Generators – Map
namespace GpxReaderHelpers;
class DistanceCalculator {
public function setDistance(GpxReaderGpxElement $point) {
$point->distance = $this->calculateDistance($point);
return $point;
}
}
Cat Herding with PHP Generators – Map
// Create our initial Generator to read the gpx file
$gpxReader = new GpxReaderGpxHandler($gpxFilename);
// Set the mapper to calculate the distance between a trackpoint
// and the previous trackpoint
$distanceCalculator = new GpxReaderHelpersDistanceCalculator();
Cat Herding with PHP Generators – Map
// Iterate over the trackpoint set from the gpx file, mapping the distances as we go,
// displaying each point detail in turn
foreach (map([$distanceCalculator, 'setDistance'], $gpxReader->getElements('trkpt'))
as $time => $element) {
printf(
'%s' . PHP_EOL . ' latitude: %7.4f longitude: %7.4f elevation: %d' . PHP_EOL .
' distance from previous point: %5.2f m' . PHP_EOL,
$time->format('Y-m-d H:i:s'),
$element->position->latitude,
$element->position->longitude,
$element->elevation,
$element->distance
);
}
Cat Herding with PHP Generators – Map
function mmap(Callable $callback, Traversable ...$iterators) {
$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
foreach($iterators as $iterator) {
$mi->attachIterator($iterator);
}
foreach($mi as $values) {
yield $callback(...$values);
}
}
http://nl3.php.net/manual/en/function.array-slice.php
...
Splat Operator
PHP >= 5.6.0
Argument Packing/Unpacking
Cat Herding with PHP Generators
Lexie
Located
Achievement
Unlocked
Cat Herding with PHP Generators – Reduce
• A reduce aggregates all the values in the Traversable to a single value.
• A callback function determines the process for the aggregation.
Cat Herding with PHP Generators – Reduce
array_reduce()
Iteratively reduces the array to a single value using a callback function.
mixed array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] )
array_reduce() applies the callback function iteratively to the elements of the array,
so as to reduce the array to a single value.
Cat Herding with PHP Generators – Reduce
function reduce(Traversable $iterator, Callable $callback, $initial = null) {
$result = $initial;
foreach($iterator as $value) {
$result = $callback($result, $value);
}
return $result;
}
Cat Herding with PHP Generators – Reduce
• Bounding Box
What Coordinates should I use for the bounding box when displaying the track
on a map?
• Distance
How far has Roman walked while he’s been out?
What is the furthest distance that Osiris has travelled from home?
Cat Herding with PHP Generators – Reduce
// Iterate over our trackpoint set from the gpx file (mapping the distance as we go)
// and reducing the results to calculate the total distance travelled
$totalDistance = reduce(
map([$distanceCalculator, 'setDistance'], $gpxReader->getElements('trkpt')),
function($runningTotal, $value) {
$runningTotal += $value->distance;
return $runningTotal;
},
0.0
);
// Display the results of our reduce
printf(
'Total distance travelled is %5.2f km' . PHP_EOL,
$totalDistance / 1000
);
Cat Herding with PHP Generators – Reduce
Total distance travelled is 4.33 km
Cat Herding with PHP Generators – Reduce
namespace GpxReaderHelpers;
class BoundingBox {
function calculate($discard, GpxReaderGpxElement $point) {
$this->top = max($point->position->latitude, $this->top);
$this->bottom = min($point->position->latitude, $this->bottom);
$this->left = min($point->position->longitude, $this->left);
$this->right = max($point->position->longitude, $this->right);
return $this;
}
}
Cat Herding with PHP Generators – Reduce
// Create our initial Generator to read the gpx file
$gpxReader = new GpxReaderGpxHandler($gpxFilename);
// Set our bounding box callback
$boundaries = new GpxReaderHelpersBoundingBox();
// Reduce our trackpoint set from the gpx file against the bounding box callback
$boundingBox = reduce( $gpxReader->getElements('trkpt'), [$boundaries, 'calculate'] );
// Display the results of our reduce
printf(
'Top: %7.4f Bottom: %7.4f' . PHP_EOL . 'Left: %7.4f Right: %7.4f' . PHP_EOL,
$boundingBox->top,
$boundingBox->bottom,
$boundingBox->left,
$boundingBox->right
);
Cat Herding with PHP Generators – Reduce
Top: 53.5445 Bottom: 53.5426
Left: -2.7433 Right: -2.7393
Cat Herding with PHP Generators
Roman
Located
Achievement
Unlocked
Cat Herding with PHP Generators
iterator_apply()
Call a function for every element in an iterator.
int iterator_apply ( Traversable $iterator , callable $function [, array $args ] )
Cat Herding with PHP Generators
iterator_count()
Count the elements in an iterator.
int iterator_count ( Traversable $iterator )
Cat Herding with PHP Generators
iterator_to_array()
Copy all values from the iterator into an array.
array iterator_to_array ( Traversable $iterator [, bool $use_keys = true ] )
Cat Herding with PHP Generators
// Create an instance of the fluent Generator Helper and set our filters,
// mapper offset and limits
// and the display callback to "do" (or execute)
// In this case, the "do" is a display callback,
// but it could also be a "reduce" callback
withGenerator($trackPoints)
->filteredBy($boundingBoxFilter)
->filteredBy($timeFilter, ARRAY_FILTER_USE_KEY)
->map([$distanceCalculator, 'setDistance'])
->offset(1)
->limit(1)
->do($display);
A Functional Guide to Cat Herding with PHP Generators
https://github.com/lstrojny/functional-php
A Functional Guide to Cat Herding with PHP Generators
No cats were forced to walk anywhere that they didn't want to go
during the writing of this presentation.
A Functional Guide to Cat Herding with PHP Generators
?
Questions
Who am I?
Mark Baker
Design and Development Manager
InnovEd (Innovative Solutions for Education) Ltd
Coordinator and Developer of:
Open Source PHPOffice library
PHPExcel, PHPWord, PHPPresentation (formerly PHPPowerPoint), PHPProject, PHPVisio
Minor contributor to PHP core
@Mark_Baker
https://github.com/MarkBaker
http://uk.linkedin.com/pub/mark-baker/b/572/171
http://markbakeruk.net

More Related Content

What's hot

Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)
James Titcumb
 
Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
Mark Baker
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
jsmith92
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
PHP 8.1 - What's new and changed
PHP 8.1 - What's new and changedPHP 8.1 - What's new and changed
PHP 8.1 - What's new and changed
Ayesh Karunaratne
 
New in php 7
New in php 7New in php 7
New in php 7
Vic Metcalfe
 
Forget about loops
Forget about loopsForget about loops
Forget about loops
Dušan Kasan
 
Creating own language made easy
Creating own language made easyCreating own language made easy
Creating own language made easy
Ingvar Stepanyan
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
Hisateru Tanaka
 
PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
jsmith92
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
Kris Wallsmith
 
php 2 Function creating, calling, PHP built-in function
php 2 Function creating, calling,PHP built-in functionphp 2 Function creating, calling,PHP built-in function
php 2 Function creating, calling, PHP built-in function
tumetr1
 
Generated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 GeneratorsGenerated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 Generators
Mark Baker
 
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur..."How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
Fwdays
 
Zero to SOLID
Zero to SOLIDZero to SOLID
Zero to SOLID
Vic Metcalfe
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middleware
Kuan Yen Heng
 
Opaque Pointers Are Coming
Opaque Pointers Are ComingOpaque Pointers Are Coming
Opaque Pointers Are Coming
Nikita Popov
 
PHP Conference Asia 2016
PHP Conference Asia 2016PHP Conference Asia 2016
PHP Conference Asia 2016
Britta Alex
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
Andrew Shitov
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
Kris Wallsmith
 

What's hot (20)

Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)
 
Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
PHP 8.1 - What's new and changed
PHP 8.1 - What's new and changedPHP 8.1 - What's new and changed
PHP 8.1 - What's new and changed
 
New in php 7
New in php 7New in php 7
New in php 7
 
Forget about loops
Forget about loopsForget about loops
Forget about loops
 
Creating own language made easy
Creating own language made easyCreating own language made easy
Creating own language made easy
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
 
php 2 Function creating, calling, PHP built-in function
php 2 Function creating, calling,PHP built-in functionphp 2 Function creating, calling,PHP built-in function
php 2 Function creating, calling, PHP built-in function
 
Generated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 GeneratorsGenerated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 Generators
 
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur..."How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
 
Zero to SOLID
Zero to SOLIDZero to SOLID
Zero to SOLID
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middleware
 
Opaque Pointers Are Coming
Opaque Pointers Are ComingOpaque Pointers Are Coming
Opaque Pointers Are Coming
 
PHP Conference Asia 2016
PHP Conference Asia 2016PHP Conference Asia 2016
PHP Conference Asia 2016
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
 

Viewers also liked

Getting instantly up and running with Docker and Symfony
Getting instantly up and running with Docker and SymfonyGetting instantly up and running with Docker and Symfony
Getting instantly up and running with Docker and Symfony
André Rømcke
 
Giving birth to an ElePHPant
Giving birth to an ElePHPantGiving birth to an ElePHPant
Giving birth to an ElePHPant
Mark Baker
 
php[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Upphp[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Up
Joe Ferguson
 
Zend Framework Foundations
Zend Framework FoundationsZend Framework Foundations
Zend Framework Foundations
Chuck Reeves
 
Engineer - Mastering the Art of Software
Engineer - Mastering the Art of SoftwareEngineer - Mastering the Art of Software
Engineer - Mastering the Art of Software
Cristiano Diniz da Silva
 
Amp your site an intro to accelerated mobile pages
Amp your site  an intro to accelerated mobile pagesAmp your site  an intro to accelerated mobile pages
Amp your site an intro to accelerated mobile pages
Robert McFrazier
 
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
James Titcumb
 
Hack the Future
Hack the FutureHack the Future
Hack the Future
Jason McCreary
 
Create, test, secure, repeat
Create, test, secure, repeatCreate, test, secure, repeat
Create, test, secure, repeat
Michelangelo van Dam
 
Console Apps: php artisan forthe:win
Console Apps: php artisan forthe:win Console Apps: php artisan forthe:win
Console Apps: php artisan forthe:win
Joe Ferguson
 
Presentation Bulgaria PHP
Presentation Bulgaria PHPPresentation Bulgaria PHP
Presentation Bulgaria PHP
Alena Holligan
 
Dip Your Toes in the Sea of Security
Dip Your Toes in the Sea of SecurityDip Your Toes in the Sea of Security
Dip Your Toes in the Sea of Security
James Titcumb
 
Git Empowered
Git EmpoweredGit Empowered
Git Empowered
Jason McCreary
 
Code Coverage for Total Security in Application Migrations
Code Coverage for Total Security in Application MigrationsCode Coverage for Total Security in Application Migrations
Code Coverage for Total Security in Application Migrations
Dana Luther
 
Php extensions
Php extensionsPhp extensions
Php extensions
Elizabeth Smith
 
SunshinePHP 2017 - Making the most out of MySQL
SunshinePHP 2017 - Making the most out of MySQLSunshinePHP 2017 - Making the most out of MySQL
SunshinePHP 2017 - Making the most out of MySQL
Gabriela Ferrara
 
Conscious Coupling
Conscious CouplingConscious Coupling
Conscious Coupling
CiaranMcNulty
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
David Stockton
 
200K+ reasons security is a must
200K+ reasons security is a must200K+ reasons security is a must
200K+ reasons security is a must
Michelangelo van Dam
 
PHP World DC 2015 - What Can Go Wrong with Agile Development and How to Fix It
PHP World DC 2015 - What Can Go Wrong with Agile Development and How to Fix ItPHP World DC 2015 - What Can Go Wrong with Agile Development and How to Fix It
PHP World DC 2015 - What Can Go Wrong with Agile Development and How to Fix It
Matt Toigo
 

Viewers also liked (20)

Getting instantly up and running with Docker and Symfony
Getting instantly up and running with Docker and SymfonyGetting instantly up and running with Docker and Symfony
Getting instantly up and running with Docker and Symfony
 
Giving birth to an ElePHPant
Giving birth to an ElePHPantGiving birth to an ElePHPant
Giving birth to an ElePHPant
 
php[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Upphp[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Up
 
Zend Framework Foundations
Zend Framework FoundationsZend Framework Foundations
Zend Framework Foundations
 
Engineer - Mastering the Art of Software
Engineer - Mastering the Art of SoftwareEngineer - Mastering the Art of Software
Engineer - Mastering the Art of Software
 
Amp your site an intro to accelerated mobile pages
Amp your site  an intro to accelerated mobile pagesAmp your site  an intro to accelerated mobile pages
Amp your site an intro to accelerated mobile pages
 
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
 
Hack the Future
Hack the FutureHack the Future
Hack the Future
 
Create, test, secure, repeat
Create, test, secure, repeatCreate, test, secure, repeat
Create, test, secure, repeat
 
Console Apps: php artisan forthe:win
Console Apps: php artisan forthe:win Console Apps: php artisan forthe:win
Console Apps: php artisan forthe:win
 
Presentation Bulgaria PHP
Presentation Bulgaria PHPPresentation Bulgaria PHP
Presentation Bulgaria PHP
 
Dip Your Toes in the Sea of Security
Dip Your Toes in the Sea of SecurityDip Your Toes in the Sea of Security
Dip Your Toes in the Sea of Security
 
Git Empowered
Git EmpoweredGit Empowered
Git Empowered
 
Code Coverage for Total Security in Application Migrations
Code Coverage for Total Security in Application MigrationsCode Coverage for Total Security in Application Migrations
Code Coverage for Total Security in Application Migrations
 
Php extensions
Php extensionsPhp extensions
Php extensions
 
SunshinePHP 2017 - Making the most out of MySQL
SunshinePHP 2017 - Making the most out of MySQLSunshinePHP 2017 - Making the most out of MySQL
SunshinePHP 2017 - Making the most out of MySQL
 
Conscious Coupling
Conscious CouplingConscious Coupling
Conscious Coupling
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
 
200K+ reasons security is a must
200K+ reasons security is a must200K+ reasons security is a must
200K+ reasons security is a must
 
PHP World DC 2015 - What Can Go Wrong with Agile Development and How to Fix It
PHP World DC 2015 - What Can Go Wrong with Agile Development and How to Fix ItPHP World DC 2015 - What Can Go Wrong with Agile Development and How to Fix It
PHP World DC 2015 - What Can Go Wrong with Agile Development and How to Fix It
 

Similar to A Functional Guide to Cat Herding with PHP Generators

Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.net
Programmer Blog
 
Elements of Functional Programming in PHP
Elements of Functional Programming in PHPElements of Functional Programming in PHP
Elements of Functional Programming in PHP
Jarek Jakubowski
 
Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)
Damien Seguy
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
Jeff Carouth
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3
Nate Abele
 
php AND MYSQL _ppt.pdf
php AND MYSQL _ppt.pdfphp AND MYSQL _ppt.pdf
php AND MYSQL _ppt.pdf
SVN Polytechnic Kalan Sultanpur UP
 
Php Tutorials for Beginners
Php Tutorials for BeginnersPhp Tutorials for Beginners
Php Tutorials for Beginners
Vineet Kumar Saini
 
PHP traits, treat or threat?
PHP traits, treat or threat?PHP traits, treat or threat?
PHP traits, treat or threat?
Nick Belhomme
 
Phpspec tips&amp;tricks
Phpspec tips&amp;tricksPhpspec tips&amp;tricks
Phpspec tips&amp;tricks
Filip Golonka
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
chartjes
 
Functional php
Functional phpFunctional php
Functional php
Jean Carlo Machado
 
Slide
SlideSlide
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
Mark Baker
 
PHP7 - Scalar Type Hints & Return Types
PHP7 - Scalar Type Hints & Return TypesPHP7 - Scalar Type Hints & Return Types
PHP7 - Scalar Type Hints & Return Types
Eric Poe
 
Class 3 - PHP Functions
Class 3 - PHP FunctionsClass 3 - PHP Functions
Class 3 - PHP Functions
Ahmed Swilam
 
Meet up symfony 16 juin 2017 - Les PSR
Meet up symfony 16 juin 2017 -  Les PSRMeet up symfony 16 juin 2017 -  Les PSR
Meet up symfony 16 juin 2017 - Les PSR
Julien Vinber
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
Nate Abele
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
Wildan Maulana
 
Damien seguy php 5.6
Damien seguy php 5.6Damien seguy php 5.6
Damien seguy php 5.6
Damien Seguy
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
Jason Lotito
 

Similar to A Functional Guide to Cat Herding with PHP Generators (20)

Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.net
 
Elements of Functional Programming in PHP
Elements of Functional Programming in PHPElements of Functional Programming in PHP
Elements of Functional Programming in PHP
 
Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3
 
php AND MYSQL _ppt.pdf
php AND MYSQL _ppt.pdfphp AND MYSQL _ppt.pdf
php AND MYSQL _ppt.pdf
 
Php Tutorials for Beginners
Php Tutorials for BeginnersPhp Tutorials for Beginners
Php Tutorials for Beginners
 
PHP traits, treat or threat?
PHP traits, treat or threat?PHP traits, treat or threat?
PHP traits, treat or threat?
 
Phpspec tips&amp;tricks
Phpspec tips&amp;tricksPhpspec tips&amp;tricks
Phpspec tips&amp;tricks
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Functional php
Functional phpFunctional php
Functional php
 
Slide
SlideSlide
Slide
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
PHP7 - Scalar Type Hints & Return Types
PHP7 - Scalar Type Hints & Return TypesPHP7 - Scalar Type Hints & Return Types
PHP7 - Scalar Type Hints & Return Types
 
Class 3 - PHP Functions
Class 3 - PHP FunctionsClass 3 - PHP Functions
Class 3 - PHP Functions
 
Meet up symfony 16 juin 2017 - Les PSR
Meet up symfony 16 juin 2017 -  Les PSRMeet up symfony 16 juin 2017 -  Les PSR
Meet up symfony 16 juin 2017 - Les PSR
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
Damien seguy php 5.6
Damien seguy php 5.6Damien seguy php 5.6
Damien seguy php 5.6
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
 

More from Mark Baker

Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
Mark Baker
 
Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
Mark Baker
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to Production
Mark Baker
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to Production
Mark Baker
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to Production
Mark Baker
 
A Brief History of Elephpants
A Brief History of ElephpantsA Brief History of Elephpants
A Brief History of Elephpants
Mark Baker
 
Aspects of love slideshare
Aspects of love slideshareAspects of love slideshare
Aspects of love slideshare
Mark Baker
 
Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?
Mark Baker
 
A Brief History of ElePHPants
A Brief History of ElePHPantsA Brief History of ElePHPants
A Brief History of ElePHPants
Mark Baker
 
Coding Horrors
Coding HorrorsCoding Horrors
Coding Horrors
Mark Baker
 
Anonymous classes2
Anonymous classes2Anonymous classes2
Anonymous classes2
Mark Baker
 
Testing the Untestable
Testing the UntestableTesting the Untestable
Testing the Untestable
Mark Baker
 
Anonymous Classes: Behind the Mask
Anonymous Classes: Behind the MaskAnonymous Classes: Behind the Mask
Anonymous Classes: Behind the Mask
Mark Baker
 
Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?
Mark Baker
 
Coding Horrors
Coding HorrorsCoding Horrors
Coding Horrors
Mark Baker
 
Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?
Mark Baker
 
SPL - The Undiscovered Library - PHPBarcelona 2015
SPL - The Undiscovered Library - PHPBarcelona 2015SPL - The Undiscovered Library - PHPBarcelona 2015
SPL - The Undiscovered Library - PHPBarcelona 2015
Mark Baker
 
Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensions
Mark Baker
 
Flying under the radar
Flying under the radarFlying under the radar
Flying under the radar
Mark Baker
 
Php data structures – beyond spl (online version)
Php data structures – beyond spl (online version)Php data structures – beyond spl (online version)
Php data structures – beyond spl (online version)
Mark Baker
 

More from Mark Baker (20)

Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
 
Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to Production
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to Production
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to Production
 
A Brief History of Elephpants
A Brief History of ElephpantsA Brief History of Elephpants
A Brief History of Elephpants
 
Aspects of love slideshare
Aspects of love slideshareAspects of love slideshare
Aspects of love slideshare
 
Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?
 
A Brief History of ElePHPants
A Brief History of ElePHPantsA Brief History of ElePHPants
A Brief History of ElePHPants
 
Coding Horrors
Coding HorrorsCoding Horrors
Coding Horrors
 
Anonymous classes2
Anonymous classes2Anonymous classes2
Anonymous classes2
 
Testing the Untestable
Testing the UntestableTesting the Untestable
Testing the Untestable
 
Anonymous Classes: Behind the Mask
Anonymous Classes: Behind the MaskAnonymous Classes: Behind the Mask
Anonymous Classes: Behind the Mask
 
Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?
 
Coding Horrors
Coding HorrorsCoding Horrors
Coding Horrors
 
Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?Does the SPL still have any relevance in the Brave New World of PHP7?
Does the SPL still have any relevance in the Brave New World of PHP7?
 
SPL - The Undiscovered Library - PHPBarcelona 2015
SPL - The Undiscovered Library - PHPBarcelona 2015SPL - The Undiscovered Library - PHPBarcelona 2015
SPL - The Undiscovered Library - PHPBarcelona 2015
 
Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensions
 
Flying under the radar
Flying under the radarFlying under the radar
Flying under the radar
 
Php data structures – beyond spl (online version)
Php data structures – beyond spl (online version)Php data structures – beyond spl (online version)
Php data structures – beyond spl (online version)
 

Recently uploaded

办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
apvysm8
 
一比一原版(UO毕业证)渥太华大学毕业证如何办理
一比一原版(UO毕业证)渥太华大学毕业证如何办理一比一原版(UO毕业证)渥太华大学毕业证如何办理
一比一原版(UO毕业证)渥太华大学毕业证如何办理
aqzctr7x
 
A presentation that explain the Power BI Licensing
A presentation that explain the Power BI LicensingA presentation that explain the Power BI Licensing
A presentation that explain the Power BI Licensing
AlessioFois2
 
DSSML24_tspann_CodelessGenerativeAIPipelines
DSSML24_tspann_CodelessGenerativeAIPipelinesDSSML24_tspann_CodelessGenerativeAIPipelines
DSSML24_tspann_CodelessGenerativeAIPipelines
Timothy Spann
 
Experts live - Improving user adoption with AI
Experts live - Improving user adoption with AIExperts live - Improving user adoption with AI
Experts live - Improving user adoption with AI
jitskeb
 
Intelligence supported media monitoring in veterinary medicine
Intelligence supported media monitoring in veterinary medicineIntelligence supported media monitoring in veterinary medicine
Intelligence supported media monitoring in veterinary medicine
AndrzejJarynowski
 
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docxDATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
SaffaIbrahim1
 
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
Social Samosa
 
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
nyfuhyz
 
Udemy_2024_Global_Learning_Skills_Trends_Report (1).pdf
Udemy_2024_Global_Learning_Skills_Trends_Report (1).pdfUdemy_2024_Global_Learning_Skills_Trends_Report (1).pdf
Udemy_2024_Global_Learning_Skills_Trends_Report (1).pdf
Fernanda Palhano
 
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
Aggregage
 
The Ipsos - AI - Monitor 2024 Report.pdf
The  Ipsos - AI - Monitor 2024 Report.pdfThe  Ipsos - AI - Monitor 2024 Report.pdf
The Ipsos - AI - Monitor 2024 Report.pdf
Social Samosa
 
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data LakeViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
Walaa Eldin Moustafa
 
Predictably Improve Your B2B Tech Company's Performance by Leveraging Data
Predictably Improve Your B2B Tech Company's Performance by Leveraging DataPredictably Improve Your B2B Tech Company's Performance by Leveraging Data
Predictably Improve Your B2B Tech Company's Performance by Leveraging Data
Kiwi Creative
 
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
ihavuls
 
Learn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queriesLearn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queries
manishkhaire30
 
Palo Alto Cortex XDR presentation .......
Palo Alto Cortex XDR presentation .......Palo Alto Cortex XDR presentation .......
Palo Alto Cortex XDR presentation .......
Sachin Paul
 
Analysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performanceAnalysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performance
roli9797
 
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
nuttdpt
 
University of New South Wales degree offer diploma Transcript
University of New South Wales degree offer diploma TranscriptUniversity of New South Wales degree offer diploma Transcript
University of New South Wales degree offer diploma Transcript
soxrziqu
 

Recently uploaded (20)

办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
办(uts毕业证书)悉尼科技大学毕业证学历证书原版一模一样
 
一比一原版(UO毕业证)渥太华大学毕业证如何办理
一比一原版(UO毕业证)渥太华大学毕业证如何办理一比一原版(UO毕业证)渥太华大学毕业证如何办理
一比一原版(UO毕业证)渥太华大学毕业证如何办理
 
A presentation that explain the Power BI Licensing
A presentation that explain the Power BI LicensingA presentation that explain the Power BI Licensing
A presentation that explain the Power BI Licensing
 
DSSML24_tspann_CodelessGenerativeAIPipelines
DSSML24_tspann_CodelessGenerativeAIPipelinesDSSML24_tspann_CodelessGenerativeAIPipelines
DSSML24_tspann_CodelessGenerativeAIPipelines
 
Experts live - Improving user adoption with AI
Experts live - Improving user adoption with AIExperts live - Improving user adoption with AI
Experts live - Improving user adoption with AI
 
Intelligence supported media monitoring in veterinary medicine
Intelligence supported media monitoring in veterinary medicineIntelligence supported media monitoring in veterinary medicine
Intelligence supported media monitoring in veterinary medicine
 
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docxDATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
DATA COMMS-NETWORKS YR2 lecture 08 NAT & CLOUD.docx
 
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
4th Modern Marketing Reckoner by MMA Global India & Group M: 60+ experts on W...
 
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
一比一原版(UMN文凭证书)明尼苏达大学毕业证如何办理
 
Udemy_2024_Global_Learning_Skills_Trends_Report (1).pdf
Udemy_2024_Global_Learning_Skills_Trends_Report (1).pdfUdemy_2024_Global_Learning_Skills_Trends_Report (1).pdf
Udemy_2024_Global_Learning_Skills_Trends_Report (1).pdf
 
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
Beyond the Basics of A/B Tests: Highly Innovative Experimentation Tactics You...
 
The Ipsos - AI - Monitor 2024 Report.pdf
The  Ipsos - AI - Monitor 2024 Report.pdfThe  Ipsos - AI - Monitor 2024 Report.pdf
The Ipsos - AI - Monitor 2024 Report.pdf
 
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data LakeViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
ViewShift: Hassle-free Dynamic Policy Enforcement for Every Data Lake
 
Predictably Improve Your B2B Tech Company's Performance by Leveraging Data
Predictably Improve Your B2B Tech Company's Performance by Leveraging DataPredictably Improve Your B2B Tech Company's Performance by Leveraging Data
Predictably Improve Your B2B Tech Company's Performance by Leveraging Data
 
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
原版制作(unimelb毕业证书)墨尔本大学毕业证Offer一模一样
 
Learn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queriesLearn SQL from basic queries to Advance queries
Learn SQL from basic queries to Advance queries
 
Palo Alto Cortex XDR presentation .......
Palo Alto Cortex XDR presentation .......Palo Alto Cortex XDR presentation .......
Palo Alto Cortex XDR presentation .......
 
Analysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performanceAnalysis insight about a Flyball dog competition team's performance
Analysis insight about a Flyball dog competition team's performance
 
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
一比一原版(UCSB文凭证书)圣芭芭拉分校毕业证如何办理
 
University of New South Wales degree offer diploma Transcript
University of New South Wales degree offer diploma TranscriptUniversity of New South Wales degree offer diploma Transcript
University of New South Wales degree offer diploma Transcript
 

A Functional Guide to Cat Herding with PHP Generators

  • 1. A Functional Guide to Cat Herding with PHP Generators The Filter/Map/Reduce Pattern for PHP Generators
  • 2. A Functional Guide to Cat Herding with PHP Generators • Blog Post http://markbakeruk.net/2016/01/19/a-functional-guide-to-cat-herding-with- php-generators/ • Code Examples https://github.com/MarkBaker/GeneratorFunctionExamples
  • 3. A Functional Guide to Cat Herding with PHP Generators
  • 4. A Functional Guide to Cat Herding with PHP Generators
  • 5. A Functional Guide to Cat Herding with PHP Generators <?xml version="1.0" encoding="UTF-8" standalone="no" ?> <gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"> <trk> <name>Roman 2015-11-23</name> <trkseg> <trkpt lat="53.54398800" lon="-2.7403680000"> <ele>146.100</ele><time>2015-11-23T11:05:07Z</time> </trkpt> <trkpt lat="53.54401600" lon="-2.7402620000"> <ele>141.300</ele><time>2015-11-23T11:05:15Z</time> </trkpt> ... <trkpt lat="53.54384500" lon="-2.7426130000"> <ele>110.500</ele><time>2015-11-23T14:58:57Z</time> </trkpt> </trkseg> </trk> </gpx>
  • 6. A Functional Guide to Cat Herding with PHP Generators namespace GpxReader; class GpxHandler { protected $gpxReader; public function __construct($gpxFilename) { $this->gpxReader = new XMLReader(); $this->gpxReader->open($gpxFilename); } public function getElements($elementType) { while ($this->gpxReader->read()) { if ($this->gpxReader->nodeType == XMLREADER::ELEMENT && $this->gpxReader->name == $elementType) { $doc = new DOMDocument('1.0', 'UTF-8'); $xml = simplexml_import_dom($doc->importNode($this->gpxReader->expand(), true)); $gpxAttributes = $this->readAttributes($this->gpxReader); $gpxElement = $this->readChildren($xml); $gpxElement->position = $gpxAttributes; yield $gpxElement->timestamp => $gpxElement; } } } }
  • 7. A Functional Guide to Cat Herding with PHP Generators // Create our initial Generator to read the gpx file $gpxReader = new GpxReaderGpxHandler($gpxFilename); // Iterate over the trackpoint set from the gpx file, // displaying each point detail in turn foreach ($gpxReader->getElements('trkpt') as $time => $element) { printf( '%s' . PHP_EOL . ' latitude: %7.4f longitude: %7.4f elevation: %d' . PHP_EOL, $time->format('Y-m-d H:i:s'), $element->position->latitude, $element->position->longitude, $element->elevation ); }
  • 8. A Functional Guide to Cat Herding with PHP Generators 2015-11-23 11:05:07 latitude: 53.5440 longitude: -2.7404 elevation: 146 2015-11-23 11:05:15 latitude: 53.5440 longitude: -2.7403 elevation: 141 2015-11-23 11:05:25 latitude: 53.5440 longitude: -2.7402 elevation: 140 ... 2015-11-23 14:58:47 latitude: 53.5439 longitude: -2.7426 elevation: 103 2015-11-23 14:58:57 latitude: 53.5438 longitude: -2.7426 elevation: 110
  • 9. A Functional Guide to Cat Herding with PHP Generators
  • 10. Cat Herding with PHP Generators – Filter • A filter selects only a subset of values from the Traversable. • The rules for filtering are defined in a callback function. • If no callback is provided, then only non-empty values are returned.
  • 11. Cat Herding with PHP Generators – Filter array_filter() Filters elements of an array using a callback function. array array_filter ( array $array [, callable $callback] ) Iterates over each value in the array passing them to the callback function. If the callback function returns true, the current value from array is returned into the result array, otherwise it is discarded. Array keys are preserved.
  • 12. Cat Herding with PHP Generators – Filter function notEmpty($value) { return !empty($value); } /** * Version of filter to use with versions of PHP prior to 5.6.0, * without the `$flag` option * **/ function filter(Traversable $filter, Callable $callback = null) { if ($callback === null) { $callback = 'notEmpty'; } foreach ($filter as $key => $value) { if ($callback($value)) { yield $key => $value; } } }
  • 13. Cat Herding with PHP Generators – Filter array_filter() Filters elements of an array using a callback function. array array_filter ( array $array [, callable $callback] ) array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] ) Iterates over each value in the array passing them to the callback function. If the callback function returns true, the current value from array is returned into the result array, otherwise it is discarded. Array keys are preserved. [PHP < 5.6.0] [PHP >= 5.6.0]
  • 14. Cat Herding with PHP Generators – Filter /** * The `$flag` option (and the constants ARRAY_FILTER_USE_KEY and ARRAY_FILTER_USE_BOTH) * were introduced in PHP 5.6.0 * **/ function filter(Traversable $filter, Callable $callback = null, $flag = 0) { if ($callback === null) { $callback = 'notEmpty'; } foreach ($filter as $key => $value) { switch($flag) { case ARRAY_FILTER_USE_KEY: ... case ARRAY_FILTER_USE_BOTH: ... default: ... } } }
  • 15. Cat Herding with PHP Generators – Filter • Time Range Where was Roman between 11:30 and 12:00? • Geo-Fencing (“Bounding Box”) • Inside Did Osiris go anywhere near the main road? • Outside Has Lexie left the house at all?
  • 16. Cat Herding with PHP Generators – Filter // Create our initial Generator to read the gpx file $gpxReader = new GpxReaderGpxHandler($gpxFilename); // Define the date/time filter parameters $startTime = new DateTime('2015-03-02 13:20:00Z'); $endTime = new DateTime('2015-03-02 13:30:00Z'); // Create the filter callback with the date/time parameters we've just defined $timeFilter = function($timestamp) use ($startTime, $endTime) { return $timestamp >= $startTime && $timestamp <= $endTime; };
  • 17. Cat Herding with PHP Generators – Filter // Iterate over the trackpoint set from the gpx file, // displaying each point detail in turn foreach (filter($gpxReader->getElements('trkpt'), $timeFilter, ARRAY_FILTER_USE_KEY) as $time => $element) { printf( '%s' . PHP_EOL . ' latitude: %7.4f longitude: %7.4f elevation: %d' . PHP_EOL, $time->format('Y-m-d H:i:s'), $element->position->latitude, $element->position->longitude, $element->elevation ); }
  • 18. Cat Herding with PHP Generators – Filter
  • 19. Cat Herding with PHP Generators – Filter namespace GpxReaderHelpers; class BoundingBox { /** * Identify whether a trackpoint falls inside the defined bounding box * * @param GpxReaderGpxElement The trackpoint * @return boolean If the trackpoint falls outside (false) * or inside (true) the bounding box **/ public function inside(GpxReaderGpxElement $point) { return (($point->position->longitude >= $this->left) && ($point->position->longitude <= $this->right) && ($point->position->latitude >= $this->bottom) && ($point->position->latitude <= $this->top)); } }
  • 20. Cat Herding with PHP Generators – Filter // Create our initial Generator to read the gpx file $gpxReader = new GpxReaderGpxHandler($gpxFilename); // Create a bounding box defining the coordinates we want to test each point against // This bounding box is for inside the house/garden $boundaries = new GpxReaderHelpersBoundingBox(); $boundaries->setLatitudes(53.54382, 53.54340); $boundaries->setLongitudes(-2.74059, -2.74005); // We want to set the filter to include only points inside the bounding box $boundingBoxFilter = [$boundaries, 'inside'];
  • 21. Cat Herding with PHP Generators – Filter // Iterate over the trackpoint set from the gpx file, // displaying each point detail in turn foreach (filter($gpxReader->getElements('trkpt'), $boundingBoxFilter) as $time => $element) { printf( '%s' . PHP_EOL . ' latitude: %7.4f longitude: %7.4f elevation: %d' . PHP_EOL, $time->format('Y-m-d H:i:s'), $element->position->latitude, $element->position->longitude, $element->elevation ); }
  • 22. Cat Herding with PHP Generators – Filter // Iterate over the trackpoint set from the gpx file, // displaying each point detail in turn // applying both a time filter (12:00:00-12:20:00 on 2015-11-23) // and a bounding box filter for inside the house/garden foreach (filter( filter( $gpxReader->getElements('trkpt'), $timeFilter, ARRAY_FILTER_USE_KEY ), $boundingBoxFilter ) as $time => $element) { printf( ... ); }
  • 23. Cat Herding with PHP Generators Osiris Located Achievement Unlocked
  • 24. Cat Herding with PHP Generators – Map • A map is like a foreach loop that transforms each value in the Traversable. • Each input value is transformed into a new output value. • The rules for the transformation are defined in a callback function.
  • 25. Cat Herding with PHP Generators – Map array_map() Applies the callback to the elements of the given arrays. array array_map ( callable $callback , array $array1 [, array $... ] ) array_map() returns an array containing all the elements of array1 after applying the callback function to each one. The number of parameters that the callback function accepts should match the number of arrays passed to the array_map().
  • 26. Cat Herding with PHP Generators – Map function map(Callable $callback, Traversable $iterator) { foreach ($iterator as $key => $value) { yield $key => $callback($value); } }
  • 27. Cat Herding with PHP Generators – Map namespace GpxReaderHelpers; class DistanceCalculator { public function setDistance(GpxReaderGpxElement $point) { $point->distance = $this->calculateDistance($point); return $point; } }
  • 28. Cat Herding with PHP Generators – Map // Create our initial Generator to read the gpx file $gpxReader = new GpxReaderGpxHandler($gpxFilename); // Set the mapper to calculate the distance between a trackpoint // and the previous trackpoint $distanceCalculator = new GpxReaderHelpersDistanceCalculator();
  • 29. Cat Herding with PHP Generators – Map // Iterate over the trackpoint set from the gpx file, mapping the distances as we go, // displaying each point detail in turn foreach (map([$distanceCalculator, 'setDistance'], $gpxReader->getElements('trkpt')) as $time => $element) { printf( '%s' . PHP_EOL . ' latitude: %7.4f longitude: %7.4f elevation: %d' . PHP_EOL . ' distance from previous point: %5.2f m' . PHP_EOL, $time->format('Y-m-d H:i:s'), $element->position->latitude, $element->position->longitude, $element->elevation, $element->distance ); }
  • 30. Cat Herding with PHP Generators – Map function mmap(Callable $callback, Traversable ...$iterators) { $mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY); foreach($iterators as $iterator) { $mi->attachIterator($iterator); } foreach($mi as $values) { yield $callback(...$values); } } http://nl3.php.net/manual/en/function.array-slice.php ... Splat Operator PHP >= 5.6.0 Argument Packing/Unpacking
  • 31. Cat Herding with PHP Generators Lexie Located Achievement Unlocked
  • 32. Cat Herding with PHP Generators – Reduce • A reduce aggregates all the values in the Traversable to a single value. • A callback function determines the process for the aggregation.
  • 33. Cat Herding with PHP Generators – Reduce array_reduce() Iteratively reduces the array to a single value using a callback function. mixed array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] ) array_reduce() applies the callback function iteratively to the elements of the array, so as to reduce the array to a single value.
  • 34. Cat Herding with PHP Generators – Reduce function reduce(Traversable $iterator, Callable $callback, $initial = null) { $result = $initial; foreach($iterator as $value) { $result = $callback($result, $value); } return $result; }
  • 35. Cat Herding with PHP Generators – Reduce • Bounding Box What Coordinates should I use for the bounding box when displaying the track on a map? • Distance How far has Roman walked while he’s been out? What is the furthest distance that Osiris has travelled from home?
  • 36. Cat Herding with PHP Generators – Reduce // Iterate over our trackpoint set from the gpx file (mapping the distance as we go) // and reducing the results to calculate the total distance travelled $totalDistance = reduce( map([$distanceCalculator, 'setDistance'], $gpxReader->getElements('trkpt')), function($runningTotal, $value) { $runningTotal += $value->distance; return $runningTotal; }, 0.0 ); // Display the results of our reduce printf( 'Total distance travelled is %5.2f km' . PHP_EOL, $totalDistance / 1000 );
  • 37. Cat Herding with PHP Generators – Reduce Total distance travelled is 4.33 km
  • 38. Cat Herding with PHP Generators – Reduce namespace GpxReaderHelpers; class BoundingBox { function calculate($discard, GpxReaderGpxElement $point) { $this->top = max($point->position->latitude, $this->top); $this->bottom = min($point->position->latitude, $this->bottom); $this->left = min($point->position->longitude, $this->left); $this->right = max($point->position->longitude, $this->right); return $this; } }
  • 39. Cat Herding with PHP Generators – Reduce // Create our initial Generator to read the gpx file $gpxReader = new GpxReaderGpxHandler($gpxFilename); // Set our bounding box callback $boundaries = new GpxReaderHelpersBoundingBox(); // Reduce our trackpoint set from the gpx file against the bounding box callback $boundingBox = reduce( $gpxReader->getElements('trkpt'), [$boundaries, 'calculate'] ); // Display the results of our reduce printf( 'Top: %7.4f Bottom: %7.4f' . PHP_EOL . 'Left: %7.4f Right: %7.4f' . PHP_EOL, $boundingBox->top, $boundingBox->bottom, $boundingBox->left, $boundingBox->right );
  • 40. Cat Herding with PHP Generators – Reduce Top: 53.5445 Bottom: 53.5426 Left: -2.7433 Right: -2.7393
  • 41. Cat Herding with PHP Generators Roman Located Achievement Unlocked
  • 42. Cat Herding with PHP Generators iterator_apply() Call a function for every element in an iterator. int iterator_apply ( Traversable $iterator , callable $function [, array $args ] )
  • 43. Cat Herding with PHP Generators iterator_count() Count the elements in an iterator. int iterator_count ( Traversable $iterator )
  • 44. Cat Herding with PHP Generators iterator_to_array() Copy all values from the iterator into an array. array iterator_to_array ( Traversable $iterator [, bool $use_keys = true ] )
  • 45. Cat Herding with PHP Generators // Create an instance of the fluent Generator Helper and set our filters, // mapper offset and limits // and the display callback to "do" (or execute) // In this case, the "do" is a display callback, // but it could also be a "reduce" callback withGenerator($trackPoints) ->filteredBy($boundingBoxFilter) ->filteredBy($timeFilter, ARRAY_FILTER_USE_KEY) ->map([$distanceCalculator, 'setDistance']) ->offset(1) ->limit(1) ->do($display);
  • 46. A Functional Guide to Cat Herding with PHP Generators https://github.com/lstrojny/functional-php
  • 47. A Functional Guide to Cat Herding with PHP Generators No cats were forced to walk anywhere that they didn't want to go during the writing of this presentation.
  • 48. A Functional Guide to Cat Herding with PHP Generators ? Questions
  • 49. Who am I? Mark Baker Design and Development Manager InnovEd (Innovative Solutions for Education) Ltd Coordinator and Developer of: Open Source PHPOffice library PHPExcel, PHPWord, PHPPresentation (formerly PHPPowerPoint), PHPProject, PHPVisio Minor contributor to PHP core @Mark_Baker https://github.com/MarkBaker http://uk.linkedin.com/pub/mark-baker/b/572/171 http://markbakeruk.net