SlideShare a Scribd company logo
1 of 49
Download to read offline
Electrify your
Code with
PHP Generators
PHP Generators
• http://www.slideshare.net/MarkBakerUK/generators-49071693
PHP Generators
Wikipedia defines a Generator as:
A generator is very similar to a function that returns an array, in that
a generator has parameters, can be called, and generates a
sequence of values. However, instead of building an array containing
all the values and returning them all at once, a generator yields the
values one at a time, which requires less memory and allows the
caller to get started processing the first few values immediately. In
short, a generator looks like a function but behaves like an iterator.
PHP Generators
• Introduced in PHP 5.5
• Iterable (Traversable) Objects
• Can return a series of values, one at a time
• Maintain state between iterations
• Can accept values when sent to the generator
• Similar to enumerators in Ruby, or Sequence Expressions in F#
PHP Generators
• Don’t
• Add anything to PHP that couldn’t be done before
• Do
• Allow you to perform iterative operations without an array to iterate
• Potentially reduce memory use
• Potentially faster than iterating over an array
• Can be type-hinted in function/method definitions
• Potentially cleaner and shorter code
• Add semantics to your code
PHP Generators
• Automatically created when PHP identifies a function or method
containing the “yield” keyword
function myGeneration() {
yield 1;
}
$generator = myGeneration();
var_dump($generator);
object(Generator)#1 (0) { }
PHP Generators
• Implemented as an Object
final class Generator implements Iterator {
mixed current( void );
mixed key( void );
void next( void );
void rewind( void );
mixed send( mixed $value );
mixed throw( Exception $exception );
bool valid( void );
public void __wakeup ( void )
}
• Can’t be extended
PHP Generators
function xrange($lower, $upper) {
for ($i = $lower; $i <= $upper; ++$i) {
yield $i;
}
}
$rangeGenerator = xrange(0,10);
while ($rangeGenerator->valid()) {
$key = $rangeGenerator->key();
$value = $rangeGenerator->current();
echo $key , ' -> ' , $value, PHP_EOL;
$rangeGenerator->next();
}
PHP Generators
function xrange($lower, $upper) {
for ($i = $lower; $i <= $upper; ++$i) {
yield $i;
}
}
foreach (xrange(0,10) as $key => $value) {
echo $key , ' -> ' , $value, PHP_EOL;
}
PHP Generators
foreach (range(0,65535) as $i => $value) {
echo $i , ' -> ' , $value, PHP_EOL;
}
function xrange($lower, $upper) {
for ($i = $lower; $i <= $upper; ++$i) {
yield $i;
}
}
foreach (xrange(0, 65535) as $i => $value) {
echo $i , ' -> ' , $value, PHP_EOL;
}
for($i = 0; $i <= 65535; ++$i) {
echo $i , ' -> ' , $value, PHP_EOL;
}
Time: 0.0183 s
Current Memory: 123.44 k
Peak Memory: 5500.11 k
Time: 0.0135 s
Current Memory: 124.33 k
Peak Memory: 126.84 k
Time: 0.0042 s
Current Memory: 122.92 k
Peak Memory: 124.49 k
PHP Generators
function xlColumnRange($lower, $upper) {
++$upper;
for ($i = $lower; $i != $upper; ++$i) {
yield $i;
}
}
foreach (xlColumnRange('A', 'CQ') as $i => $value) {
printf('%3d -> %2s', $i, $value);
echo (($i > 0) && ($i+1 % 5 == 0)) ?
PHP_EOL :
"t";
}
0 -> A 1 -> B 2 -> C 3 -> D 4 -> E
5 -> F 6 -> G 7 -> H 8 -> I 9 -> J
10 -> K 11 -> L 12 -> M 13 -> N 14 -> O
15 -> P 16 -> Q 17 -> R 18 -> S 19 -> T
20 -> U 21 -> V 22 -> W 23 -> X 24 -> Y
25 -> Z 26 -> AA 27 -> AB 28 -> AC 29 -> AD
30 -> AE 31 -> AF 32 -> AG 33 -> AH 34 -> AI
35 -> AJ 36 -> AK 37 -> AL 38 -> AM 39 -> AN
40 -> AO 41 -> AP 42 -> AQ 43 -> AR 44 -> AS
45 -> AT 46 -> AU 47 -> AV 48 -> AW 49 -> AX
50 -> AY 51 -> AZ 52 -> BA 53 -> BB 54 -> BC
55 -> BD 56 -> BE 57 -> BF 58 -> BG 59 -> BH
60 -> BI 61 -> BJ 62 -> BK 63 -> BL 64 -> BM
65 -> BN 66 -> BO 67 -> BP 68 -> BQ 69 -> BR
70 -> BS 71 -> BT 72 -> BU 73 -> BV 74 -> BW
75 -> BX 76 -> BY 77 -> BZ 78 -> CA 79 -> CB
80 -> CC 81 -> CD 82 -> CE 83 -> CF 84 -> CG
85 -> CH 86 -> CI 87 -> CJ 88 -> CK 89 -> CL
90 -> CM 91 -> CN 92 -> CO 93 -> CP 94 -> CQ
PHP Generators
$isEven = function ($value) {
return !($value & 1);
};
$isOdd = function ($value) {
return $value & 1;
};
function xFilter(callable $callback, array $args=array()) {
foreach ($args as $arg)
if (call_user_func($callback, $arg))
yield $arg;
}
PHP Generators
$data = range(1,10);
echo 'xFilter for Odd Numbers', PHP_EOL;
foreach (xFilter($isOdd, $data) as $i)
echo('num is: '.$i.PHP_EOL);
echo 'xFilter for Even Numbers', PHP_EOL;
foreach (xFilter($isEven, $data) as $i)
echo('num is: '.$i.PHP_EOL);
xFilter for Odd Numbers
num is: 1
num is: 3
num is: 5
num is: 7
num is: 9
xFilter for Even Numbers
num is: 2
num is: 4
num is: 6
num is: 8
num is: 10
PHP Generators
• Can return both a value and a “pseudo” key
• By default
• The key is an integer value
• Starting with 0 for the first iteration
• Incrementing by 1 each iteration
• Accessed from foreach() as:
foreach(generator() as $key => $value) {}
• or using
$key = $generatorObject->key();
PHP Generators
• Default key behaviour can be changed
• Syntax is:
yield $key => $value;
• Unlike array keys:
• “Pseudo” keys can be any PHP datatype
• “Pseudo” key values can be duplicated
PHP Generators
function xrange($lower, $upper) {
$k = $upper;
for ($i = $lower; $i <= $upper; ++$i) {
yield $k-- => $i;
}
}
foreach (xrange(0, 8) as $i => $value) {
echo $i, ' -> ', $value, PHP_EOL;
}
8 -> 0
7 -> 1
6 -> 2
5 -> 3
4 -> 4
3 -> 5
2 -> 6
1 -> 7
0 -> 8
PHP Generators
function duplicateKeys($lower, $upper) {
for ($i = $lower; $i <= $upper; ++$i) {
yield (($i-1) % 3) + 1 => $i;
}
}
foreach (duplicateKeys(1,15) as $i => $value){
echo $i , ' -> ' , $value, PHP_EOL;
}
1 -> 1
2 -> 2
3 -> 3
1 -> 4
2 -> 5
3 -> 6
1 -> 7
2 -> 8
3 -> 9
1 -> 10
2 -> 11
3 -> 12
1 -> 13
2 -> 14
3 -> 15
PHP Generators
function duplicateKeys($string) {
$string = strtolower($string);
$length = strlen($string);
for ($i = 0; $i < $length; ++$i) {
yield strtoupper($string[$i]) => $string[$i];
}
}
foreach (duplicateKeys('badass') as $key => $value) {
echo $key , ' -> ' , $value, PHP_EOL;
}
B -> b
A -> a
D -> d
A -> a
S -> s
S -> s
PHP Generators
function floatKeys($lower, $upper) {
for ($i = $lower; $i <= $upper; ++$i) {
yield ($i / 5) => $i;
}
}
foreach (floatKeys(1,16) as $i => $value) {
printf(
'%0.2f -> %2d' . PHP_EOL,
$i,
$value
);
}
0.20 -> 1
0.40 -> 2
0.60 -> 3
0.80 -> 4
1.00 -> 5
1.20 -> 6
1.40 -> 7
1.60 -> 8
1.80 -> 9
2.00 -> 10
2.20 -> 11
2.40 -> 12
2.60 -> 13
2.80 -> 14
3.00 -> 15
3.20 -> 16
PHP Generators
• It is possible to access generated values “by reference”
• The generator must be declared “by reference”
• The yielded value must be a variable, and cannot be an expression
PHP Generators
function &byReference2($size) {
for($val=1, $key=1; $key <= $size; ++$val, ++$key) {
yield $key => $val;
}
}
$size = 10;
foreach (byReference2($size) as $key => &$value) {
echo $key, ' => ', $value, ' => ',
($value += $value - 1), PHP_EOL;
}
echo PHP_EOL;
1 => 1 => 1
2 => 2 => 3
3 => 4 => 7
4 => 8 => 15
5 => 16 => 31
6 => 32 => 63
7 => 64 => 127
8 => 128 => 255
9 => 256 => 511
10 => 512 => 1023
PHP Generators
• Data can be passed to the generator
• Sometimes called a “Coroutine” when used in this way
• Not strictly accurate, they are more strictly a “Semicoroutine”
• They can form the basis for a “Coroutine” with the addition of a top-level
dispatcher routine
• Syntax is:
$value = yield;
• Calling script uses the “send()” method:
$generatorObject->send($value);
PHP Generators
$data = array(
'Squirtle',
'Jigglypuff',
'Charmander',
'Bulbasaur',
'White DPC Elephpant',
);
function generatorSend() {
while (true) {
$cityName = yield;
echo $cityName, PHP_EOL;
}
}
$generatorObject = generatorSend();
foreach($data as $value) {
$generatorObject->send($value);
}
echo PHP_EOL, 'Gotta Collect 'em all', PHP_EOL;
Squirtle
Jigglypuff
Charmander
Bulbasaur
White DPC Elephpant
Gotta Collect 'em All
PHP Generators
$logFileName = __DIR__ . '/error.log';
function logger($logFileName) {
$f = fopen($logFileName, 'a');
while ($logentry = yield) {
fwrite(
$f,
(new DateTime())->format('Y-m-d H:i:s ') .
$logentry .
PHP_EOL
);
}
}
$logger = logger($logFileName);
for($i = 0; $i < 12; ++$i) {
$logger->send('Message #' . $i );
}
PHP Generators
• It is possible to combine a Generator
to both send and accept data
PHP Generators
function generatorSend($limit) {
for ($i = 1; $i <= $limit; ++$i) {
yield $i => pow($i, $i);
$continue = yield;
if (!$continue)
break;
}
}
$generatorObject = generatorSend(100);
while ($generatorObject->valid()) {
$key = $generatorObject->key();
$value = $generatorObject->current();
$generatorObject->next();
$generatorObject->send($key >= 10);
echo $key, ' -> ', $value, PHP_EOL;
}
1 -> 1
2 -> 4
3 -> 27
4 -> 256
5 -> 3125
6 -> 46656
7 -> 823543
8 -> 16777216
9 -> 387420489
10 -> 10000000000
PHP Generators (Gotcha)
function generatorSend($limit) {
for ($i = 1; $i <= $limit; ++$i) {
yield pow($i, $i);
$continue = yield;
if (!$continue)
break;
}
}
$generatorObject = generatorSend(100);
while ($generatorObject->valid()) {
$key = $generatorObject->key();
$value = $generatorObject->current();
$generatorObject->next();
$generatorObject->send($key >= 10);
echo $key, ' -> ', $value, PHP_EOL;
}
0 -> 1
2 -> 4
4 -> 27
6 -> 256
8 -> 3125
10 -> 46656
PHP Generators
function generatorSend($limit) {
for ($i = 1; $i <= $limit; ++$i) {
$continue = (yield pow($i, $i));
if (!$continue)
break;
}
}
$generatorObject = generatorSend(100);
while($generatorObject->valid()) {
$key = $generatorObject->key();
$value = $generatorObject->current();
echo $key, ' -> ', $value, PHP_EOL;
$generatorObject->send($key >= 10);
}
0 -> 1
1 -> 4
2 -> 27
3 -> 256
4 -> 3125
5 -> 46656
6 -> 823543
7 -> 16777216
8 -> 387420489
9 -> 10000000000
PHP Generators (Gotcha)
function generatorSend($limit) {
for ($i = 1; $i <= $limit; ++$i) {
$continue = (yield pow($i, $i));
if (!$continue)
break;
}
}
$generatorObject = generatorSend(100);
foreach($generatorObject as $key => $value) {
echo $key, ' -> ', $value, PHP_EOL;
$generatorObject->send($key >= 10);
}
0 -> 1
PHP Generators (Gotcha)
function generatorSend($limit) {
for ($i = 1; $i <= $limit; ++$i) {
$continue = (yield pow($i, $i));
if (!$continue && $continue !== null)
break;
}
}
$generatorObject = generatorSend(100);
foreach($generatorObject as $key => $value) {
echo $key, ' -> ', $value, PHP_EOL;
$generatorObject->send($key >= 10);
}
1 -> 1
3 -> 27
5 -> 3125
7 -> 823543
9 -> 387420489
11 -> 285311670611
PHP Generators (Gotcha)
function generatorSend($limit) {
for ($i = 1; $i <= $limit; ++$i) {
$continue = (yield pow($i, $i));
if (!$continue && $continue !== null)
break;
elseif (!$continue && $continue === null)
--$i;
}
}
$generatorObject = generatorSend(100);
foreach($generatorObject as $key => $value) {
echo $key, ' -> ', $value, PHP_EOL;
$generatorObject->send($key >= 10);
}
1 -> 1
2 -> 4
3 -> 27
4 -> 256
5 -> 3125
6 -> 46656
7 -> 823543
8 -> 16777216
9 -> 387420489
10 -> 10000000000
PHP Generators
• By sending data into a Generator
it is possible to change its behaviour
PHP Generators
function diamond($size) {
$i = $key = 1;
do {
$ascending = (yield $key => str_repeat(' ', $size - $i) .
str_repeat('*', $i*2-1) . str_repeat(' ', $size - $i));
if ($ascending !== null) {
($ascending) ? ++$i : --$i;
++$key;
}
} while($i > 0);
}
$size = 5;
$diamond = diamond($size);
foreach ($diamond as $key => $value) {
echo sprintf('%2d', $key), ' => ', $value, PHP_EOL;
$diamond->send($key < $size);
}
1 => *
2 => ***
3 => *****
4 => *******
5 => *********
6 => *******
7 => *****
8 => ***
9 => *
PHP Generators
function adjustableIncrementor($value = 1, $increment = 1) {
do {
$increment = (yield $value);
$value += $increment;
} while ($value <= PHP_INT_MAX);
}
$incrementor = adjustableIncrementor();
foreach ($incrementor as $increment) {
echo number_format($increment), PHP_EOL;
$incrementor->send($increment);
}
1
2
4
8
16
32
64
128
256
512
1,024
...
268,435,456
536,870,912
1,073,741,824
PHP Generators
function adjustableIncrementor($value = 1, $increment = 1) {
do {
$increment = (yield $value);
$value += $increment;
} while ($value <= PHP_INT_MAX);
}
$incrementor = adjustableIncrementor();
foreach ($incrementor as $increment) {
echo number_format($increment), PHP_EOL;
$incrementor->send(pow(10, strlen($increment)-1));
}
1
2
3
...
9
10
20
30
...
90
100
200
300
...
900
1,000
...
PHP Generators
• We can also throw an Exception into a Generator
• A Try/Catch block should be defined in the Generator
• We use the Generator’s “throw()” method from the calling code
$generatorObject->throw(new Exception(‘xyz’));
• Useful for terminating a Generator loop if we don’t want to code a
send() in every iteration
PHP Generators
function filteredNumbers(Callable $filter) {
$i = 1;
try {
do {
if (call_user_func($filter, $i)) {
yield $i;
}
} while ($i++ <= PHP_INT_MAX);
} catch (Exception $e) {
echo $e->getMessage(), PHP_EOL;
}
}
PHP Generators
$primes = filteredNumbers($isPrime);
foreach ($primes as $counter => $prime) {
if ($prime > 50) {
$primes->throw(
new Exception('Enough already')
);
continue;
}
echo $prime, PHP_EOL;
}
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
Enough already
PHP Generators
• You can’t pass Generators as arguments to array functions
So you can’t call array_map() or array_reduce()with a
Generator instead of an array argument
• But by passing a Generator as an argument to another
Generator, we can chain Generators
Allowing us to simulate array_map() or array_reduce()
PHP Generators
function filteredNumbers(Callable $filter) {
$i = 1;
do {
if (call_user_func($filter, $i)) {
yield $i;
}
} while ($i++ <= PHP_INT_MAX);
}
PHP Generators
function filteredValueLimit(Traversable $filter, $limit) {
foreach ($filter as $value) {
if ($value > $limit) {
break;
}
yield $value;
}
}
PHP Generators
function mappedFilterList(Traversable $filter, Callable $callback) {
foreach ($filter as $value) {
yield $value => call_user_func($callback, $value);
}
}
PHP Generators
$primes = filteredNumbers($isPrime);
$primes64 = filteredValueLimit($primes, 64);
$primesSquared = mappedFilterList(
$primes64,
function($value) {
return $value * $value;
}
);
foreach ($primesSquared as $primeSquared) {
echo $prime, ' => ', $primeSquared, PHP_EOL;
}
2 => 4
3 => 9
5 => 25
7 => 49
11 => 121
13 => 169
17 => 289
19 => 361
23 => 529
29 => 841
31 => 961
37 => 1369
41 => 1681
43 => 1849
47 => 2209
53 => 2809
59 => 3481
61 => 3721
PHP Generators
function reduceFilterList(Traversable $filter, Callable $callback, $initial) {
$result = $initial;
foreach($filter as $value) {
$result = call_user_func($callback, $value, $result);
}
yield $result;
}
PHP Generators
$primes = filteredNumbers2($isPrime);
$primes64 = filteredValueLimit($primes, 64);
$sumPrimes = reduceFilterList(
$primes64,
function($value, $initial) {
return $value + $initial;
},
0
);
$sumPrime = $sumPrimes->current();
echo $sumPrime, PHP_EOL;
501
PHP Generators
• Limitations
• Can’t be Extended
• Can’t be Serialized
• Can’t be “Rewound”
PHP Generators
• Additional Reading:
• http://blog.ircmaxell.com/2012/07/what-generators-can-do-for-you.html
• http://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html
• https://markbakeruk.net/2016/01/19/a-functional-guide-to-cat-herding-with-php-
generators/
Electrify your code with
PHP Generators
?
Questions
Who am I?
Mark Baker
Design and Development Manager
InnovEd (Innovative Solutions for Education) Learning Ltd
Coordinator and Developer of:
Open Source PHPOffice library
PHPExcel, PHPWord, PHPPowerPoint, PHPProject, PHPVisio
Minor contributor to PHP core
Other small open source libraries available on github
@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

Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony TechniquesKris Wallsmith
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)James Titcumb
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2Hugo Hamon
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8PrinceGuru MS
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Nikita Popov
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolveXSolve
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8XSolve
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128PrinceGuru MS
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)Nikita Popov
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsMark Baker
 

What's hot (20)

Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8
 
New in php 7
New in php 7New in php 7
New in php 7
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 

Viewers also liked

Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages webJean-Pierre Vincent
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsDavey Shafik
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phingRajat Pandit
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)Matthias Noback
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performanceafup Paris
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Marcello Duarte
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!tlrx
 
Writing infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLWriting infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLGabriele Bartolini
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Bruno Boucard
 
L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)Arnauld Loyer
 
Performance serveur et apache
Performance serveur et apachePerformance serveur et apache
Performance serveur et apacheafup Paris
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016CiaranMcNulty
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsRyan Weaver
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersKacper Gunia
 

Viewers also liked (20)

Diving deep into twig
Diving deep into twigDiving deep into twig
Diving deep into twig
 
Elastic Searching With PHP
Elastic Searching With PHPElastic Searching With PHP
Elastic Searching With PHP
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages web
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP Streams
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phing
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performance
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!
 
Writing infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLWriting infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQL
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
 
L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)
 
Performance serveur et apache
Performance serveur et apachePerformance serveur et apache
Performance serveur et apache
 
Behat 3.0 meetup (March)
Behat 3.0 meetup (March)Behat 3.0 meetup (March)
Behat 3.0 meetup (March)
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony Components
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 

Similar to Electrify your code with PHP Generators

関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHPprabhatjon
 
Iterators & generators: practical uses in memory management
Iterators & generators: practical uses in memory managementIterators & generators: practical uses in memory management
Iterators & generators: practical uses in memory managementAdrian Cardenas
 
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.netProgrammer Blog
 
[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?Radek Benkel
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHPBradley Holt
 
2014 database - course 2 - php
2014 database - course 2 - php2014 database - course 2 - php
2014 database - course 2 - phpHung-yu Lin
 
Php basic for vit university
Php basic for vit universityPhp basic for vit university
Php basic for vit universityMandakini Kumari
 
php programming.pptx
php programming.pptxphp programming.pptx
php programming.pptxrani marri
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Anatoly Sharifulin
 
PHP Basics and Demo HackU
PHP Basics and Demo HackUPHP Basics and Demo HackU
PHP Basics and Demo HackUAnshu Prateek
 
GettingStartedWithPHP
GettingStartedWithPHPGettingStartedWithPHP
GettingStartedWithPHPNat Weerawan
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
 
07 Introduction to PHP #burningkeyboards
07 Introduction to PHP #burningkeyboards07 Introduction to PHP #burningkeyboards
07 Introduction to PHP #burningkeyboardsDenis Ristic
 

Similar to Electrify your code with PHP Generators (20)

関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
 
Iterators & generators: practical uses in memory management
Iterators & generators: practical uses in memory managementIterators & generators: practical uses in memory management
Iterators & generators: practical uses in memory management
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
 
Web Technology_10.ppt
Web Technology_10.pptWeb Technology_10.ppt
Web Technology_10.ppt
 
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 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
PHP Basics
PHP BasicsPHP Basics
PHP Basics
 
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
 
[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
 
2014 database - course 2 - php
2014 database - course 2 - php2014 database - course 2 - php
2014 database - course 2 - php
 
Php basic for vit university
Php basic for vit universityPhp basic for vit university
Php basic for vit university
 
php programming.pptx
php programming.pptxphp programming.pptx
php programming.pptx
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!
 
PHP Basics and Demo HackU
PHP Basics and Demo HackUPHP Basics and Demo HackU
PHP Basics and Demo HackU
 
GettingStartedWithPHP
GettingStartedWithPHPGettingStartedWithPHP
GettingStartedWithPHP
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 
07 Introduction to PHP #burningkeyboards
07 Introduction to PHP #burningkeyboards07 Introduction to PHP #burningkeyboards
07 Introduction to PHP #burningkeyboards
 

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 IteratorsMark Baker
 
Looping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsMark Baker
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to ProductionMark Baker
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to ProductionMark Baker
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to ProductionMark Baker
 
A Brief History of Elephpants
A Brief History of ElephpantsA Brief History of Elephpants
A Brief History of ElephpantsMark Baker
 
Aspects of love slideshare
Aspects of love slideshareAspects of love slideshare
Aspects of love slideshareMark 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 ElePHPantsMark Baker
 
Coding Horrors
Coding HorrorsCoding Horrors
Coding HorrorsMark Baker
 
Anonymous classes2
Anonymous classes2Anonymous classes2
Anonymous classes2Mark Baker
 
Testing the Untestable
Testing the UntestableTesting the Untestable
Testing the UntestableMark Baker
 
Anonymous Classes: Behind the Mask
Anonymous Classes: Behind the MaskAnonymous Classes: Behind the Mask
Anonymous Classes: Behind the MaskMark 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 HorrorsMark 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
 
Giving birth to an ElePHPant
Giving birth to an ElePHPantGiving birth to an ElePHPant
Giving birth to an ElePHPantMark Baker
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsMark Baker
 
SPL - The Undiscovered Library - PHPBarcelona 2015
SPL - The Undiscovered Library - PHPBarcelona 2015SPL - The Undiscovered Library - PHPBarcelona 2015
SPL - The Undiscovered Library - PHPBarcelona 2015Mark 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 extensionsMark 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?
 
Giving birth to an ElePHPant
Giving birth to an ElePHPantGiving birth to an ElePHPant
Giving birth to an ElePHPant
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
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
 

Recently uploaded

Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfmaor17
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingShane Coughlan
 
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfPros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfkalichargn70th171
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shardsChristopher Curtin
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecturerahul_net
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jNeo4j
 
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...kalichargn70th171
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonApplitools
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsJean Silva
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesVictoriaMetrics
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptxVinzoCenzo
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
Mastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxMastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxAS Design & AST.
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
Advantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptxAdvantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptxRTS corp
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 
Understanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptxUnderstanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptxSasikiranMarri
 

Recently uploaded (20)

Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdf
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
 
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdfPros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
Pros and Cons of Selenium In Automation Testing_ A Comprehensive Assessment.pdf
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecture
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
 
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...
The Ultimate Guide to Performance Testing in Low-Code, No-Code Environments (...
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero results
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 Updates
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptx
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
Mastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptxMastering Project Planning with Microsoft Project 2016.pptx
Mastering Project Planning with Microsoft Project 2016.pptx
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
Advantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptxAdvantages of Cargo Cloud Solutions.pptx
Advantages of Cargo Cloud Solutions.pptx
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 
Understanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptxUnderstanding Plagiarism: Causes, Consequences and Prevention.pptx
Understanding Plagiarism: Causes, Consequences and Prevention.pptx
 

Electrify your code with PHP Generators

  • 3. PHP Generators Wikipedia defines a Generator as: A generator is very similar to a function that returns an array, in that a generator has parameters, can be called, and generates a sequence of values. However, instead of building an array containing all the values and returning them all at once, a generator yields the values one at a time, which requires less memory and allows the caller to get started processing the first few values immediately. In short, a generator looks like a function but behaves like an iterator.
  • 4. PHP Generators • Introduced in PHP 5.5 • Iterable (Traversable) Objects • Can return a series of values, one at a time • Maintain state between iterations • Can accept values when sent to the generator • Similar to enumerators in Ruby, or Sequence Expressions in F#
  • 5. PHP Generators • Don’t • Add anything to PHP that couldn’t be done before • Do • Allow you to perform iterative operations without an array to iterate • Potentially reduce memory use • Potentially faster than iterating over an array • Can be type-hinted in function/method definitions • Potentially cleaner and shorter code • Add semantics to your code
  • 6. PHP Generators • Automatically created when PHP identifies a function or method containing the “yield” keyword function myGeneration() { yield 1; } $generator = myGeneration(); var_dump($generator); object(Generator)#1 (0) { }
  • 7. PHP Generators • Implemented as an Object final class Generator implements Iterator { mixed current( void ); mixed key( void ); void next( void ); void rewind( void ); mixed send( mixed $value ); mixed throw( Exception $exception ); bool valid( void ); public void __wakeup ( void ) } • Can’t be extended
  • 8. PHP Generators function xrange($lower, $upper) { for ($i = $lower; $i <= $upper; ++$i) { yield $i; } } $rangeGenerator = xrange(0,10); while ($rangeGenerator->valid()) { $key = $rangeGenerator->key(); $value = $rangeGenerator->current(); echo $key , ' -> ' , $value, PHP_EOL; $rangeGenerator->next(); }
  • 9. PHP Generators function xrange($lower, $upper) { for ($i = $lower; $i <= $upper; ++$i) { yield $i; } } foreach (xrange(0,10) as $key => $value) { echo $key , ' -> ' , $value, PHP_EOL; }
  • 10. PHP Generators foreach (range(0,65535) as $i => $value) { echo $i , ' -> ' , $value, PHP_EOL; } function xrange($lower, $upper) { for ($i = $lower; $i <= $upper; ++$i) { yield $i; } } foreach (xrange(0, 65535) as $i => $value) { echo $i , ' -> ' , $value, PHP_EOL; } for($i = 0; $i <= 65535; ++$i) { echo $i , ' -> ' , $value, PHP_EOL; } Time: 0.0183 s Current Memory: 123.44 k Peak Memory: 5500.11 k Time: 0.0135 s Current Memory: 124.33 k Peak Memory: 126.84 k Time: 0.0042 s Current Memory: 122.92 k Peak Memory: 124.49 k
  • 11. PHP Generators function xlColumnRange($lower, $upper) { ++$upper; for ($i = $lower; $i != $upper; ++$i) { yield $i; } } foreach (xlColumnRange('A', 'CQ') as $i => $value) { printf('%3d -> %2s', $i, $value); echo (($i > 0) && ($i+1 % 5 == 0)) ? PHP_EOL : "t"; } 0 -> A 1 -> B 2 -> C 3 -> D 4 -> E 5 -> F 6 -> G 7 -> H 8 -> I 9 -> J 10 -> K 11 -> L 12 -> M 13 -> N 14 -> O 15 -> P 16 -> Q 17 -> R 18 -> S 19 -> T 20 -> U 21 -> V 22 -> W 23 -> X 24 -> Y 25 -> Z 26 -> AA 27 -> AB 28 -> AC 29 -> AD 30 -> AE 31 -> AF 32 -> AG 33 -> AH 34 -> AI 35 -> AJ 36 -> AK 37 -> AL 38 -> AM 39 -> AN 40 -> AO 41 -> AP 42 -> AQ 43 -> AR 44 -> AS 45 -> AT 46 -> AU 47 -> AV 48 -> AW 49 -> AX 50 -> AY 51 -> AZ 52 -> BA 53 -> BB 54 -> BC 55 -> BD 56 -> BE 57 -> BF 58 -> BG 59 -> BH 60 -> BI 61 -> BJ 62 -> BK 63 -> BL 64 -> BM 65 -> BN 66 -> BO 67 -> BP 68 -> BQ 69 -> BR 70 -> BS 71 -> BT 72 -> BU 73 -> BV 74 -> BW 75 -> BX 76 -> BY 77 -> BZ 78 -> CA 79 -> CB 80 -> CC 81 -> CD 82 -> CE 83 -> CF 84 -> CG 85 -> CH 86 -> CI 87 -> CJ 88 -> CK 89 -> CL 90 -> CM 91 -> CN 92 -> CO 93 -> CP 94 -> CQ
  • 12. PHP Generators $isEven = function ($value) { return !($value & 1); }; $isOdd = function ($value) { return $value & 1; }; function xFilter(callable $callback, array $args=array()) { foreach ($args as $arg) if (call_user_func($callback, $arg)) yield $arg; }
  • 13. PHP Generators $data = range(1,10); echo 'xFilter for Odd Numbers', PHP_EOL; foreach (xFilter($isOdd, $data) as $i) echo('num is: '.$i.PHP_EOL); echo 'xFilter for Even Numbers', PHP_EOL; foreach (xFilter($isEven, $data) as $i) echo('num is: '.$i.PHP_EOL); xFilter for Odd Numbers num is: 1 num is: 3 num is: 5 num is: 7 num is: 9 xFilter for Even Numbers num is: 2 num is: 4 num is: 6 num is: 8 num is: 10
  • 14. PHP Generators • Can return both a value and a “pseudo” key • By default • The key is an integer value • Starting with 0 for the first iteration • Incrementing by 1 each iteration • Accessed from foreach() as: foreach(generator() as $key => $value) {} • or using $key = $generatorObject->key();
  • 15. PHP Generators • Default key behaviour can be changed • Syntax is: yield $key => $value; • Unlike array keys: • “Pseudo” keys can be any PHP datatype • “Pseudo” key values can be duplicated
  • 16. PHP Generators function xrange($lower, $upper) { $k = $upper; for ($i = $lower; $i <= $upper; ++$i) { yield $k-- => $i; } } foreach (xrange(0, 8) as $i => $value) { echo $i, ' -> ', $value, PHP_EOL; } 8 -> 0 7 -> 1 6 -> 2 5 -> 3 4 -> 4 3 -> 5 2 -> 6 1 -> 7 0 -> 8
  • 17. PHP Generators function duplicateKeys($lower, $upper) { for ($i = $lower; $i <= $upper; ++$i) { yield (($i-1) % 3) + 1 => $i; } } foreach (duplicateKeys(1,15) as $i => $value){ echo $i , ' -> ' , $value, PHP_EOL; } 1 -> 1 2 -> 2 3 -> 3 1 -> 4 2 -> 5 3 -> 6 1 -> 7 2 -> 8 3 -> 9 1 -> 10 2 -> 11 3 -> 12 1 -> 13 2 -> 14 3 -> 15
  • 18. PHP Generators function duplicateKeys($string) { $string = strtolower($string); $length = strlen($string); for ($i = 0; $i < $length; ++$i) { yield strtoupper($string[$i]) => $string[$i]; } } foreach (duplicateKeys('badass') as $key => $value) { echo $key , ' -> ' , $value, PHP_EOL; } B -> b A -> a D -> d A -> a S -> s S -> s
  • 19. PHP Generators function floatKeys($lower, $upper) { for ($i = $lower; $i <= $upper; ++$i) { yield ($i / 5) => $i; } } foreach (floatKeys(1,16) as $i => $value) { printf( '%0.2f -> %2d' . PHP_EOL, $i, $value ); } 0.20 -> 1 0.40 -> 2 0.60 -> 3 0.80 -> 4 1.00 -> 5 1.20 -> 6 1.40 -> 7 1.60 -> 8 1.80 -> 9 2.00 -> 10 2.20 -> 11 2.40 -> 12 2.60 -> 13 2.80 -> 14 3.00 -> 15 3.20 -> 16
  • 20. PHP Generators • It is possible to access generated values “by reference” • The generator must be declared “by reference” • The yielded value must be a variable, and cannot be an expression
  • 21. PHP Generators function &byReference2($size) { for($val=1, $key=1; $key <= $size; ++$val, ++$key) { yield $key => $val; } } $size = 10; foreach (byReference2($size) as $key => &$value) { echo $key, ' => ', $value, ' => ', ($value += $value - 1), PHP_EOL; } echo PHP_EOL; 1 => 1 => 1 2 => 2 => 3 3 => 4 => 7 4 => 8 => 15 5 => 16 => 31 6 => 32 => 63 7 => 64 => 127 8 => 128 => 255 9 => 256 => 511 10 => 512 => 1023
  • 22. PHP Generators • Data can be passed to the generator • Sometimes called a “Coroutine” when used in this way • Not strictly accurate, they are more strictly a “Semicoroutine” • They can form the basis for a “Coroutine” with the addition of a top-level dispatcher routine • Syntax is: $value = yield; • Calling script uses the “send()” method: $generatorObject->send($value);
  • 23. PHP Generators $data = array( 'Squirtle', 'Jigglypuff', 'Charmander', 'Bulbasaur', 'White DPC Elephpant', ); function generatorSend() { while (true) { $cityName = yield; echo $cityName, PHP_EOL; } } $generatorObject = generatorSend(); foreach($data as $value) { $generatorObject->send($value); } echo PHP_EOL, 'Gotta Collect 'em all', PHP_EOL; Squirtle Jigglypuff Charmander Bulbasaur White DPC Elephpant Gotta Collect 'em All
  • 24. PHP Generators $logFileName = __DIR__ . '/error.log'; function logger($logFileName) { $f = fopen($logFileName, 'a'); while ($logentry = yield) { fwrite( $f, (new DateTime())->format('Y-m-d H:i:s ') . $logentry . PHP_EOL ); } } $logger = logger($logFileName); for($i = 0; $i < 12; ++$i) { $logger->send('Message #' . $i ); }
  • 25. PHP Generators • It is possible to combine a Generator to both send and accept data
  • 26. PHP Generators function generatorSend($limit) { for ($i = 1; $i <= $limit; ++$i) { yield $i => pow($i, $i); $continue = yield; if (!$continue) break; } } $generatorObject = generatorSend(100); while ($generatorObject->valid()) { $key = $generatorObject->key(); $value = $generatorObject->current(); $generatorObject->next(); $generatorObject->send($key >= 10); echo $key, ' -> ', $value, PHP_EOL; } 1 -> 1 2 -> 4 3 -> 27 4 -> 256 5 -> 3125 6 -> 46656 7 -> 823543 8 -> 16777216 9 -> 387420489 10 -> 10000000000
  • 27. PHP Generators (Gotcha) function generatorSend($limit) { for ($i = 1; $i <= $limit; ++$i) { yield pow($i, $i); $continue = yield; if (!$continue) break; } } $generatorObject = generatorSend(100); while ($generatorObject->valid()) { $key = $generatorObject->key(); $value = $generatorObject->current(); $generatorObject->next(); $generatorObject->send($key >= 10); echo $key, ' -> ', $value, PHP_EOL; } 0 -> 1 2 -> 4 4 -> 27 6 -> 256 8 -> 3125 10 -> 46656
  • 28. PHP Generators function generatorSend($limit) { for ($i = 1; $i <= $limit; ++$i) { $continue = (yield pow($i, $i)); if (!$continue) break; } } $generatorObject = generatorSend(100); while($generatorObject->valid()) { $key = $generatorObject->key(); $value = $generatorObject->current(); echo $key, ' -> ', $value, PHP_EOL; $generatorObject->send($key >= 10); } 0 -> 1 1 -> 4 2 -> 27 3 -> 256 4 -> 3125 5 -> 46656 6 -> 823543 7 -> 16777216 8 -> 387420489 9 -> 10000000000
  • 29. PHP Generators (Gotcha) function generatorSend($limit) { for ($i = 1; $i <= $limit; ++$i) { $continue = (yield pow($i, $i)); if (!$continue) break; } } $generatorObject = generatorSend(100); foreach($generatorObject as $key => $value) { echo $key, ' -> ', $value, PHP_EOL; $generatorObject->send($key >= 10); } 0 -> 1
  • 30. PHP Generators (Gotcha) function generatorSend($limit) { for ($i = 1; $i <= $limit; ++$i) { $continue = (yield pow($i, $i)); if (!$continue && $continue !== null) break; } } $generatorObject = generatorSend(100); foreach($generatorObject as $key => $value) { echo $key, ' -> ', $value, PHP_EOL; $generatorObject->send($key >= 10); } 1 -> 1 3 -> 27 5 -> 3125 7 -> 823543 9 -> 387420489 11 -> 285311670611
  • 31. PHP Generators (Gotcha) function generatorSend($limit) { for ($i = 1; $i <= $limit; ++$i) { $continue = (yield pow($i, $i)); if (!$continue && $continue !== null) break; elseif (!$continue && $continue === null) --$i; } } $generatorObject = generatorSend(100); foreach($generatorObject as $key => $value) { echo $key, ' -> ', $value, PHP_EOL; $generatorObject->send($key >= 10); } 1 -> 1 2 -> 4 3 -> 27 4 -> 256 5 -> 3125 6 -> 46656 7 -> 823543 8 -> 16777216 9 -> 387420489 10 -> 10000000000
  • 32. PHP Generators • By sending data into a Generator it is possible to change its behaviour
  • 33. PHP Generators function diamond($size) { $i = $key = 1; do { $ascending = (yield $key => str_repeat(' ', $size - $i) . str_repeat('*', $i*2-1) . str_repeat(' ', $size - $i)); if ($ascending !== null) { ($ascending) ? ++$i : --$i; ++$key; } } while($i > 0); } $size = 5; $diamond = diamond($size); foreach ($diamond as $key => $value) { echo sprintf('%2d', $key), ' => ', $value, PHP_EOL; $diamond->send($key < $size); } 1 => * 2 => *** 3 => ***** 4 => ******* 5 => ********* 6 => ******* 7 => ***** 8 => *** 9 => *
  • 34. PHP Generators function adjustableIncrementor($value = 1, $increment = 1) { do { $increment = (yield $value); $value += $increment; } while ($value <= PHP_INT_MAX); } $incrementor = adjustableIncrementor(); foreach ($incrementor as $increment) { echo number_format($increment), PHP_EOL; $incrementor->send($increment); } 1 2 4 8 16 32 64 128 256 512 1,024 ... 268,435,456 536,870,912 1,073,741,824
  • 35. PHP Generators function adjustableIncrementor($value = 1, $increment = 1) { do { $increment = (yield $value); $value += $increment; } while ($value <= PHP_INT_MAX); } $incrementor = adjustableIncrementor(); foreach ($incrementor as $increment) { echo number_format($increment), PHP_EOL; $incrementor->send(pow(10, strlen($increment)-1)); } 1 2 3 ... 9 10 20 30 ... 90 100 200 300 ... 900 1,000 ...
  • 36. PHP Generators • We can also throw an Exception into a Generator • A Try/Catch block should be defined in the Generator • We use the Generator’s “throw()” method from the calling code $generatorObject->throw(new Exception(‘xyz’)); • Useful for terminating a Generator loop if we don’t want to code a send() in every iteration
  • 37. PHP Generators function filteredNumbers(Callable $filter) { $i = 1; try { do { if (call_user_func($filter, $i)) { yield $i; } } while ($i++ <= PHP_INT_MAX); } catch (Exception $e) { echo $e->getMessage(), PHP_EOL; } }
  • 38. PHP Generators $primes = filteredNumbers($isPrime); foreach ($primes as $counter => $prime) { if ($prime > 50) { $primes->throw( new Exception('Enough already') ); continue; } echo $prime, PHP_EOL; } 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 Enough already
  • 39. PHP Generators • You can’t pass Generators as arguments to array functions So you can’t call array_map() or array_reduce()with a Generator instead of an array argument • But by passing a Generator as an argument to another Generator, we can chain Generators Allowing us to simulate array_map() or array_reduce()
  • 40. PHP Generators function filteredNumbers(Callable $filter) { $i = 1; do { if (call_user_func($filter, $i)) { yield $i; } } while ($i++ <= PHP_INT_MAX); }
  • 41. PHP Generators function filteredValueLimit(Traversable $filter, $limit) { foreach ($filter as $value) { if ($value > $limit) { break; } yield $value; } }
  • 42. PHP Generators function mappedFilterList(Traversable $filter, Callable $callback) { foreach ($filter as $value) { yield $value => call_user_func($callback, $value); } }
  • 43. PHP Generators $primes = filteredNumbers($isPrime); $primes64 = filteredValueLimit($primes, 64); $primesSquared = mappedFilterList( $primes64, function($value) { return $value * $value; } ); foreach ($primesSquared as $primeSquared) { echo $prime, ' => ', $primeSquared, PHP_EOL; } 2 => 4 3 => 9 5 => 25 7 => 49 11 => 121 13 => 169 17 => 289 19 => 361 23 => 529 29 => 841 31 => 961 37 => 1369 41 => 1681 43 => 1849 47 => 2209 53 => 2809 59 => 3481 61 => 3721
  • 44. PHP Generators function reduceFilterList(Traversable $filter, Callable $callback, $initial) { $result = $initial; foreach($filter as $value) { $result = call_user_func($callback, $value, $result); } yield $result; }
  • 45. PHP Generators $primes = filteredNumbers2($isPrime); $primes64 = filteredValueLimit($primes, 64); $sumPrimes = reduceFilterList( $primes64, function($value, $initial) { return $value + $initial; }, 0 ); $sumPrime = $sumPrimes->current(); echo $sumPrime, PHP_EOL; 501
  • 46. PHP Generators • Limitations • Can’t be Extended • Can’t be Serialized • Can’t be “Rewound”
  • 47. PHP Generators • Additional Reading: • http://blog.ircmaxell.com/2012/07/what-generators-can-do-for-you.html • http://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html • https://markbakeruk.net/2016/01/19/a-functional-guide-to-cat-herding-with-php- generators/
  • 48. Electrify your code with PHP Generators ? Questions
  • 49. Who am I? Mark Baker Design and Development Manager InnovEd (Innovative Solutions for Education) Learning Ltd Coordinator and Developer of: Open Source PHPOffice library PHPExcel, PHPWord, PHPPowerPoint, PHPProject, PHPVisio Minor contributor to PHP core Other small open source libraries available on github @Mark_Baker https://github.com/MarkBaker http://uk.linkedin.com/pub/mark-baker/b/572/171 http://markbakeruk.net