SlideShare une entreprise Scribd logo
1  sur  49
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

Contenu connexe

Tendances

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
 

Tendances (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
 

En vedette

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
 

En vedette (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
 

Similaire à 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
 

Similaire à 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
 

Plus de 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
 

Plus de 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
 

Dernier

Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...Akihiro Suda
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 

Dernier (20)

Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 

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