SlideShare a Scribd company logo
Another PHP
By Max Gopey
1
Another PHP
•   Chapter 1. Coding standards
•   Chapter 2. OOP
•   Chapter 3. Everything Else
•   Chapter 4.
2
•   PSR
•   Zend
•   PEAR
•   Wordpress
•   Symphony
•   Mediawiki
•   FuelPHP
•   CakePHP
•   CodeIgniter
•   Laravel
•   ...
•   Are
•   you
•   guys
•   MAD?
Chapter 1
Coding standards
3
Chapter 2
OOP
Why do we need objects and classes?
4
Chapter 3
Everything Else
5
Chapter 3
Gitlab Composer
Click me
6
$fetch_refs = function($project) use ($fetch_ref, $repos) {
$datas = array();
try {
foreach (array_merge($repos->branches($project['id']),
$repos->tags($project['id'])) as $ref) {
foreach ($fetch_ref($project, $ref) as $version => $data) {
$datas[$version] = $data;
}
}
} catch (RuntimeException $e) {
// The repo has no commits — skipping it.
}
return $datas;
};
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
7
•   array_column
•   array_map
•   array_search
•   array_reduce
•   array_filter
•   array_walk
•   every / some
Chapter 3
Array Traversing
8
$users = [
['id' => 123, 'first_name' => 'Max', 'last_name' => 'Gopey'],
['id' => 456, 'first_name' => 'Bob', 'last_name' => 'Doe'],
['id' => 789, 'first_name' => 'Alice', 'last_name' => 'Doe'],
];
$lastNames = array_column($users, 'last_name', 'id');
print_r($lastNames);
Array
(
[123] => Max
[456] => Bob
[789] => Alice
)
01.
02.
03.
04.
05.
06.
07.
01.
02.
03.
04.
05.
06.
9
$users = [
['id' => 123, 'first_name' => 'Max', 'last_name' => 'Gopey'],
['id' => 456, 'first_name' => 'Bob', 'last_name' => 'Doe'],
['id' => 789, 'first_name' => 'Alice', 'last_name' => 'Doe'],
];
$fullNames = array_map(function($user) {
return $user['first_name'] . ' ' . $user['last_name'];
}, $users);
print_r($fullNames);
Array
(
[0] => Max Gopey
[1] => Bob Doe
[2] => Alice Doe
)
01.
02.
03.
04.
05.
06.
07.
08.
09.
01.
02.
03.
04.
05.
06.
10
$users = [
['id' => 123, 'first_name' => 'Max', 'last_name' => 'Gopey'],
['id' => 456, 'first_name' => 'Bob', 'last_name' => 'Doe'],
['id' => 789, 'first_name' => 'Alice', 'last_name' => 'Doe'],
];
$index = array_search('Alice Doe', array_map(function($user) {
return $user['first_name'] . ' ' . $user['last_name'];
}, $users));
print_r($index);
2
01.
02.
03.
04.
05.
06.
07.
08.
09.
11
$users = [
['first_name' => 'Max', 'last_name' => 'Gopey', 'company' => 'CGI'],
['first_name' => 'Bob', 'last_name' => 'Doe', 'company' => 'Google'],
['first_name' => 'Alice', 'last_name' => 'Doe', 'company' => 'Google'],
];
 
$byCompany = array_reduce($users, function($result, $user) {
@$result[$user['company']][] = $user['first_name'] . ' ' . $user['last_name'];
return $result;
}, []);
print_r($byCompany);
Array (
[CGI] => Array (
[0] => Max Gopey
)
[Google] => Array (
[0] => Bob Doe
[1] => Alice Doe
)
)
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
01.
02.
03.
04.
05.
06.
07.
08.
09.
12
$users = [
['first_name' => 'Max', 'last_name' => 'Gopey', 'company' => 'CGI'],
['first_name' => 'Bob', 'last_name' => 'Doe', 'company' => 'Google'],
['first_name' => 'Alice', 'last_name' => 'Doe', 'company' => 'Google'],
];
 
$CgiUsers = array_filter($users, function($user) {
return $user['company'] === 'CGI';
});
print_r($CgiUsers);
Array (
[0] => Array (
[first_name] => Max
[last_name] => Gopey
[company] => CGI
)
)
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
01.
02.
03.
04.
05.
06.
07.
13
$users = [
['first_name' => 'Max', 'last_name' => 'Gopey', 'company' => 'CGI'],
['first_name' => 'Bob', 'last_name' => 'Doe', 'company' => 'Google'],
['first_name' => 'Alice', 'last_name' => 'Doe', 'company' => 'Google'],
];
array_walk($users, function(&$user, $index) {
unset($user['last_name'], $user['company']);
$user['first_name'] .= ' ❤';
});
print_r($users);
Array (
[0] => Array (
[first_name] => Max ❤
)
[1] => Array (
[first_name] => Bob ❤
)
[2] => Array(
[first_name] => Alice ❤
)
)
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11. 14
function some($array, $callback) {
foreach ($array as $item) {
if ($callback($item)) {
return true;
}
}
return false;
}
function every($array, $callback) {
return !some($array, function($item) use ($callback) {
return !$callback($item);
});
}
var_dump(every([1, 2, 3], function ($item) {return $item > 0;}));
var_dump(every([1, -2, 3], function ($item) {return $item > 0;}));
bool(true)
bool(false)
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
01.
02.
15
function getBobsAndAlicesWithD($users) {
return array_reduce(
array_filter(
array_map(function($user) {
return $user['last_name'] . ', ' . $user['first_name'];
}, $users),
function($name) {
return stripos($name, 'd') === 0;
}
),
function($result, $value) {
$target = stripos($value, 'bob') !== false ? 'bobs' : 'alices';
$result[$target][] = $value;
return $result;
},
['bobs' => [], 'alices' => []]
);
}
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
16
$users = [
['first_name' => 'Max', 'last_name' => 'Gopey', 'company' => 'CGI'],
['first_name' => 'Bob', 'last_name' => 'Doe', 'company' => 'Google'],
['first_name' => 'Alice', 'last_name' => 'Doe', 'company' => 'Google'],
];
 
print_r(getBobsAndAlicesWithD($users));
Array
(
[bobs] => Array (
[0] => Doe, Bob
)
[alices] => Array (
[0] => Doe, Alice
)
)
01.
02.
03.
04.
05.
06.
07.
17
Chapter 3
Generators
Traversable (Interface)
├── Iterator (Interface)
│ └── Generator (Class)
└── IteratorAggregate (Interface)
18
function garbageGenerator() {
$n = rand(1, 10);
while ($n--) {
yield md5(rand());
}
}
$garbage = garbageGenerator();
foreach ($garbage as $trash) {
echo $trash, PHP_EOL;
}
6e620c902c7088ace3ebf6c96f5dedd5
1340dcc6f3e0e39b4c48f480f5a92d52
c264962d537032be6c3a8a94eda811d4
0bfa2efb3909c105473a4fcaa71b697b
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
19
function readFileLines($path) {
$handle = fopen($path, 'r');
while ($line = fgets($handle)) {
yield $line;
}
fclose($handle);
}
 
$lines = readFileLines(__FILE__);
foreach($lines as $line) {
echo $line;
};
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
20
SymfonyComponentProcessInputStream
Click me
21
function writer(InputStream $stream) {
$stream->write('Message 1');
$stream->write('Message 2');
yield '2 messages written';
$stream->write('Message 3');
$stream->write('Message 4');
yield '2 messages written';
$stream->write('Message 5');
$stream->write('Message 6');
yield '2 messages written';
}
 
function reader(InputStream $stream) {
foreach ($stream as $line) {
if (strlen($line)) {
yield $line;
} else {
$stream->close();
}
}
}
$stream = new InputStream();
$queue[] = writer($stream);
$queue[] = reader($stream);
 
while (true) {
$continue = array_reduce(
$queue,
function($result, Iterator $queueItem) {
if ($valid = $queueItem->valid()) {
echo $queueItem->current(), "n";
$queueItem->next();
}
return $result || $valid;
},
false);
if (!$continue) {
break;
}
}
2 messages written
Message 1
2 messages written
Message 2
2 messages written
Message 3
Message 4
Message 5
Message 6
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
22
Chapter 3
Functional programming
23
function getBobsAndAlicesWithD($users) {
return array_reduce(
array_filter(
array_map(function($user) {
return $user['last_name'] . ', ' . $user['first_name'];
}, $users),
function($name) {
return stripos($name, 'd') === 0;
}
),
function($result, $value) {
$target = stripos($value, 'bob') !== false ? 'bobs' : 'alices';
$result[$target][] = $value;
return $result;
},
['bobs' => [], 'alices' => []]
);
}
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
24
Chapter 3
Non-standard PHP library (NSPL)
Click me
25
$startsWith = function ($string, $substing) {
return stripos($string, $substing) === 0;
};
$contains = function($string, $substing) {
return stripos($string, $substing) !== false;
};
$getFullName = function ($firstName, $lastName) {
return $lastName . ', ' . $firstName;
};
 
$startsWithD = frpartial($startsWith, 'd');
$isBob = frpartial($contains, 'bob');
 
$getFullNameFromUser = function ($user) use ($getFullName) {
return $getFullName($user['first_name'], $user['last_name']);
};
$getStackKey = function($name) use ($isBob) {
return $isBob($name) ? 'bobs' : 'alices';
};
$putToCorrectStack = function($stacks, $value) use ($getStackKey) {
$stacks[$getStackKey($value)][] = $value;
return $stacks;
};
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
26
$getBobsAndAlicesWithD = function ($users)
use ($startsWithD, $getFullNameFromUser, $putToCorrectStack) {
return fpipe(
$users,
fpartial(amap, $getFullNameFromUser),
fpartial(afilter, $startsWithD),
fppartial(areduce, [
0 => $putToCorrectStack,
2 => ['bobs' => [], 'alices' => []]
])
);
};
 
print_r($getBobsAndAlicesWithD($users));
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
27
Chapter 3
Obvious logical operations
28
if (anyOf([1, 3, 5])->is(5)) {
// do something
}
if (anyOf([$name, $surname])->matches('/^w+$/') {
// do something
}
if (allOf([1, 3, 5])->areNot(6)) {
// do something
}
if (either($condition1)->or($condition2)) {
// do something
}
if (neither($x)->nor($y)) {
// do something
}
if (the($x)->isNeither(5)->nor(10)) {
// do something
}
if (the($x)->isGreaterThan(5)->butLessThan(10)) {
// do something
}
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
29
Chapter 3
Obvious regexp
____ _____ ____ _ _ _ ____ _ _ ____
| _  ___ __ _| ____|_ ___ __ | __ ) _ _(_) | __| | ___ _ __| _ | | | | _ 
| |_) / _ / _` | _|  / / '_ | _ | | | | | |/ _` |/ _  '__| |_) | |_| | |_) |
| _ < __/ (_| | |___ > <| |_) | |_) | |_| | | | (_| | __/ | | __/| _ | __/
|_| ____|__, |_____/_/_ .__/|____/ __,_|_|_|__,_|___|_| |_| |_| |_|_|
|___/ |_|
30
$regExp = $builder
->startOfInput()
->exactly(4)->digits()
->then("_")
->exactly(2)->digits()
->then("_")
->min(3)->max(10)->letters()
->then(".")
->anyOf(array("png", "jpg", "gif"))
->endOfInput()
->getRegExp();
 
//true
$regExp->matches("2020_10_hund.jpg");
$regExp->matches("2030_11_katze.png");
$regExp->matches("4000_99_maus.gif");
 
//false
$regExp->matches("123_00_nein.gif");
$regExp->matches("4000_0_nein.pdf");
$regExp->matches("201505_nein.jpg");
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
31
Useful links
Generators and Coroutines
•   Хабр: Coroutines в PHP и работа с неблокирующими функциями
•   Github: Asynchronous coroutines for PHP 7.
•   A Curious Course on Coroutines and Concurrency
•   Symfony/Component/Process/InputStream.php
Functional programming
•   Github: Non-standard PHP library (NSPL) - compact functional programming oriented code
Human-readable regular expressions
•   Github: RegexpBuilderPHP
•   Github: PHPVerbalExpressions
Kittens
•   Youtube: The funniest kitten in the world
32

More Related Content

PDF
50 Laravel Tricks in 50 Minutes
Azim Kurt
 
KEY
Introduction à CoffeeScript pour ParisRB
jhchabran
 
KEY
テストデータどうしてますか?
Yuki Shibazaki
 
PDF
[WLDN] Supercharging word press development in 2018
Adam Tomat
 
PDF
PHPUnit でよりよくテストを書くために
Yuya Takeyama
 
KEY
Introducing CakeEntity
Basuke Suzuki
 
KEY
Introducing CakeEntity
Basuke Suzuki
 
PDF
Doctrine For Beginners
Jonathan Wage
 
50 Laravel Tricks in 50 Minutes
Azim Kurt
 
Introduction à CoffeeScript pour ParisRB
jhchabran
 
テストデータどうしてますか?
Yuki Shibazaki
 
[WLDN] Supercharging word press development in 2018
Adam Tomat
 
PHPUnit でよりよくテストを書くために
Yuya Takeyama
 
Introducing CakeEntity
Basuke Suzuki
 
Introducing CakeEntity
Basuke Suzuki
 
Doctrine For Beginners
Jonathan Wage
 

What's hot (20)

PDF
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
ichikaway
 
PDF
Transparent Object Persistence with FLOW3
Karsten Dambekalns
 
PDF
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
Rafael Dohms
 
PPTX
Comparing 30 MongoDB operations with Oracle SQL statements
Lucas Jellema
 
PDF
The History of PHPersistence
Hugo Hamon
 
KEY
(Ab)Using the MetaCPAN API for Fun and Profit
Olaf Alders
 
PDF
CakeFest 2013 keynote
José Lorenzo Rodríguez Urdaneta
 
PDF
Developing applications for performance
Leon Fayer
 
PDF
The Zen of Lithium
Nate Abele
 
PDF
PHP 5.3 and Lithium: the most rad php framework
G Woo
 
PPTX
Database performance 101
Leon Fayer
 
PDF
Advanced Querying with CakePHP 3
José Lorenzo Rodríguez Urdaneta
 
PDF
The Origin of Lithium
Nate Abele
 
PDF
Doctrine MongoDB ODM (PDXPHP)
Kris Wallsmith
 
PDF
Lithium: The Framework for People Who Hate Frameworks
Nate Abele
 
KEY
The Query the Whole Query and Nothing but the Query
Chris Olbekson
 
PPTX
PyCon APAC - Django Test Driven Development
Tudor Munteanu
 
PPTX
PHP performance 101: so you need to use a database
Leon Fayer
 
PDF
Doctrine fixtures
Bill Chang
 
PDF
jQuery%20on%20Rails%20Presentation
guestcf600a
 
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
ichikaway
 
Transparent Object Persistence with FLOW3
Karsten Dambekalns
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
Rafael Dohms
 
Comparing 30 MongoDB operations with Oracle SQL statements
Lucas Jellema
 
The History of PHPersistence
Hugo Hamon
 
(Ab)Using the MetaCPAN API for Fun and Profit
Olaf Alders
 
CakeFest 2013 keynote
José Lorenzo Rodríguez Urdaneta
 
Developing applications for performance
Leon Fayer
 
The Zen of Lithium
Nate Abele
 
PHP 5.3 and Lithium: the most rad php framework
G Woo
 
Database performance 101
Leon Fayer
 
Advanced Querying with CakePHP 3
José Lorenzo Rodríguez Urdaneta
 
The Origin of Lithium
Nate Abele
 
Doctrine MongoDB ODM (PDXPHP)
Kris Wallsmith
 
Lithium: The Framework for People Who Hate Frameworks
Nate Abele
 
The Query the Whole Query and Nothing but the Query
Chris Olbekson
 
PyCon APAC - Django Test Driven Development
Tudor Munteanu
 
PHP performance 101: so you need to use a database
Leon Fayer
 
Doctrine fixtures
Bill Chang
 
jQuery%20on%20Rails%20Presentation
guestcf600a
 
Ad

Similar to How else can you write the code in PHP? (20)

KEY
Spl Not A Bridge Too Far phpNW09
Michelangelo van Dam
 
PDF
How to write code you won't hate tomorrow
Pete McFarlane
 
PPTX
Arrays in PHP
davidahaskins
 
PDF
The Art of Transduction
David Stockton
 
DOCX
PHP record- with all programs and output
KavithaK23
 
PDF
lab4_php
tutorialsruby
 
PDF
lab4_php
tutorialsruby
 
PDF
PHPCon 2016: PHP7 by Witek Adamus / XSolve
XSolve
 
PDF
Object Oriented Programming with PHP 5 - More OOP
Wildan Maulana
 
PDF
Building scalable products with WordPress - WordCamp London 2018
Elliot Taylor
 
KEY
Can't Miss Features of PHP 5.3 and 5.4
Jeff Carouth
 
PPT
Class 4 - PHP Arrays
Ahmed Swilam
 
PPTX
Professional-grade software design
Brian Fenton
 
PPTX
PHP Functions & Arrays
Henry Osborne
 
PDF
New in cakephp3
markstory
 
PDF
Php tips-and-tricks4128
PrinceGuru MS
 
PDF
PHP tips and tricks
Damien Seguy
 
PDF
Advanced Php - Macq Electronique 2010
Michelangelo van Dam
 
PDF
Banishing Loops with Functional Programming in PHP
David Hayes
 
PPT
Introduction to Template::Toolkit
duncanmg
 
Spl Not A Bridge Too Far phpNW09
Michelangelo van Dam
 
How to write code you won't hate tomorrow
Pete McFarlane
 
Arrays in PHP
davidahaskins
 
The Art of Transduction
David Stockton
 
PHP record- with all programs and output
KavithaK23
 
lab4_php
tutorialsruby
 
lab4_php
tutorialsruby
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
XSolve
 
Object Oriented Programming with PHP 5 - More OOP
Wildan Maulana
 
Building scalable products with WordPress - WordCamp London 2018
Elliot Taylor
 
Can't Miss Features of PHP 5.3 and 5.4
Jeff Carouth
 
Class 4 - PHP Arrays
Ahmed Swilam
 
Professional-grade software design
Brian Fenton
 
PHP Functions & Arrays
Henry Osborne
 
New in cakephp3
markstory
 
Php tips-and-tricks4128
PrinceGuru MS
 
PHP tips and tricks
Damien Seguy
 
Advanced Php - Macq Electronique 2010
Michelangelo van Dam
 
Banishing Loops with Functional Programming in PHP
David Hayes
 
Introduction to Template::Toolkit
duncanmg
 
Ad

Recently uploaded (20)

PDF
Micromaid: A simple Mermaid-like chart generator for Pharo
ESUG
 
PPTX
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
PDF
Teaching Reproducibility and Embracing Variability: From Floating-Point Exper...
University of Rennes, INSA Rennes, Inria/IRISA, CNRS
 
PDF
Appium Automation Testing Tutorial PDF: Learn Mobile Testing in 7 Days
jamescantor38
 
PDF
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
PDF
Jenkins: An open-source automation server powering CI/CD Automation
SaikatBasu37
 
PDF
Solar Panel Installation Guide – Step By Step Process 2025.pdf
CRMLeaf
 
PDF
Build Multi-agent using Agent Development Kit
FadyIbrahim23
 
PDF
Why Use Open Source Reporting Tools for Business Intelligence.pdf
Varsha Nayak
 
PDF
Protecting the Digital World Cyber Securit
dnthakkar16
 
PPTX
Why Use Open Source Reporting Tools for Business Intelligence.pptx
Varsha Nayak
 
PDF
Exploring AI Agents in Process Industries
amoreira6
 
PDF
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
ESUG
 
PDF
Bandai Playdia The Book - David Glotz
BluePanther6
 
PDF
Become an Agentblazer Champion Challenge Kickoff
Dele Amefo
 
PPTX
Presentation about variables and constant.pptx
kr2589474
 
PDF
Community & News Update Q2 Meet Up 2025
VictoriaMetrics
 
PDF
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
Hironori Washizaki
 
PDF
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 
PPTX
The-Dawn-of-AI-Reshaping-Our-World.pptxx
parthbhanushali307
 
Micromaid: A simple Mermaid-like chart generator for Pharo
ESUG
 
ASSIGNMENT_1[1][1][1][1][1] (1) variables.pptx
kr2589474
 
Teaching Reproducibility and Embracing Variability: From Floating-Point Exper...
University of Rennes, INSA Rennes, Inria/IRISA, CNRS
 
Appium Automation Testing Tutorial PDF: Learn Mobile Testing in 7 Days
jamescantor38
 
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
Jenkins: An open-source automation server powering CI/CD Automation
SaikatBasu37
 
Solar Panel Installation Guide – Step By Step Process 2025.pdf
CRMLeaf
 
Build Multi-agent using Agent Development Kit
FadyIbrahim23
 
Why Use Open Source Reporting Tools for Business Intelligence.pdf
Varsha Nayak
 
Protecting the Digital World Cyber Securit
dnthakkar16
 
Why Use Open Source Reporting Tools for Business Intelligence.pptx
Varsha Nayak
 
Exploring AI Agents in Process Industries
amoreira6
 
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
ESUG
 
Bandai Playdia The Book - David Glotz
BluePanther6
 
Become an Agentblazer Champion Challenge Kickoff
Dele Amefo
 
Presentation about variables and constant.pptx
kr2589474
 
Community & News Update Q2 Meet Up 2025
VictoriaMetrics
 
IEEE-CS Tech Predictions, SWEBOK and Quantum Software: Towards Q-SWEBOK
Hironori Washizaki
 
On Software Engineers' Productivity - Beyond Misleading Metrics
Romén Rodríguez-Gil
 
The-Dawn-of-AI-Reshaping-Our-World.pptxx
parthbhanushali307
 

How else can you write the code in PHP?

  • 2. Another PHP •   Chapter 1. Coding standards •   Chapter 2. OOP •   Chapter 3. Everything Else •   Chapter 4. 2
  • 3. •   PSR •   Zend •   PEAR •   Wordpress •   Symphony •   Mediawiki •   FuelPHP •   CakePHP •   CodeIgniter •   Laravel •   ... •   Are •   you •   guys •   MAD? Chapter 1 Coding standards 3
  • 4. Chapter 2 OOP Why do we need objects and classes? 4
  • 7. $fetch_refs = function($project) use ($fetch_ref, $repos) { $datas = array(); try { foreach (array_merge($repos->branches($project['id']), $repos->tags($project['id'])) as $ref) { foreach ($fetch_ref($project, $ref) as $version => $data) { $datas[$version] = $data; } } } catch (RuntimeException $e) { // The repo has no commits — skipping it. } return $datas; }; 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 7
  • 8. •   array_column •   array_map •   array_search •   array_reduce •   array_filter •   array_walk •   every / some Chapter 3 Array Traversing 8
  • 9. $users = [ ['id' => 123, 'first_name' => 'Max', 'last_name' => 'Gopey'], ['id' => 456, 'first_name' => 'Bob', 'last_name' => 'Doe'], ['id' => 789, 'first_name' => 'Alice', 'last_name' => 'Doe'], ]; $lastNames = array_column($users, 'last_name', 'id'); print_r($lastNames); Array ( [123] => Max [456] => Bob [789] => Alice ) 01. 02. 03. 04. 05. 06. 07. 01. 02. 03. 04. 05. 06. 9
  • 10. $users = [ ['id' => 123, 'first_name' => 'Max', 'last_name' => 'Gopey'], ['id' => 456, 'first_name' => 'Bob', 'last_name' => 'Doe'], ['id' => 789, 'first_name' => 'Alice', 'last_name' => 'Doe'], ]; $fullNames = array_map(function($user) { return $user['first_name'] . ' ' . $user['last_name']; }, $users); print_r($fullNames); Array ( [0] => Max Gopey [1] => Bob Doe [2] => Alice Doe ) 01. 02. 03. 04. 05. 06. 07. 08. 09. 01. 02. 03. 04. 05. 06. 10
  • 11. $users = [ ['id' => 123, 'first_name' => 'Max', 'last_name' => 'Gopey'], ['id' => 456, 'first_name' => 'Bob', 'last_name' => 'Doe'], ['id' => 789, 'first_name' => 'Alice', 'last_name' => 'Doe'], ]; $index = array_search('Alice Doe', array_map(function($user) { return $user['first_name'] . ' ' . $user['last_name']; }, $users)); print_r($index); 2 01. 02. 03. 04. 05. 06. 07. 08. 09. 11
  • 12. $users = [ ['first_name' => 'Max', 'last_name' => 'Gopey', 'company' => 'CGI'], ['first_name' => 'Bob', 'last_name' => 'Doe', 'company' => 'Google'], ['first_name' => 'Alice', 'last_name' => 'Doe', 'company' => 'Google'], ];   $byCompany = array_reduce($users, function($result, $user) { @$result[$user['company']][] = $user['first_name'] . ' ' . $user['last_name']; return $result; }, []); print_r($byCompany); Array ( [CGI] => Array ( [0] => Max Gopey ) [Google] => Array ( [0] => Bob Doe [1] => Alice Doe ) ) 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 01. 02. 03. 04. 05. 06. 07. 08. 09. 12
  • 13. $users = [ ['first_name' => 'Max', 'last_name' => 'Gopey', 'company' => 'CGI'], ['first_name' => 'Bob', 'last_name' => 'Doe', 'company' => 'Google'], ['first_name' => 'Alice', 'last_name' => 'Doe', 'company' => 'Google'], ];   $CgiUsers = array_filter($users, function($user) { return $user['company'] === 'CGI'; }); print_r($CgiUsers); Array ( [0] => Array ( [first_name] => Max [last_name] => Gopey [company] => CGI ) ) 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 01. 02. 03. 04. 05. 06. 07. 13
  • 14. $users = [ ['first_name' => 'Max', 'last_name' => 'Gopey', 'company' => 'CGI'], ['first_name' => 'Bob', 'last_name' => 'Doe', 'company' => 'Google'], ['first_name' => 'Alice', 'last_name' => 'Doe', 'company' => 'Google'], ]; array_walk($users, function(&$user, $index) { unset($user['last_name'], $user['company']); $user['first_name'] .= ' ❤'; }); print_r($users); Array ( [0] => Array ( [first_name] => Max ❤ ) [1] => Array ( [first_name] => Bob ❤ ) [2] => Array( [first_name] => Alice ❤ ) ) 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 14
  • 15. function some($array, $callback) { foreach ($array as $item) { if ($callback($item)) { return true; } } return false; } function every($array, $callback) { return !some($array, function($item) use ($callback) { return !$callback($item); }); } var_dump(every([1, 2, 3], function ($item) {return $item > 0;})); var_dump(every([1, -2, 3], function ($item) {return $item > 0;})); bool(true) bool(false) 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 01. 02. 15
  • 16. function getBobsAndAlicesWithD($users) { return array_reduce( array_filter( array_map(function($user) { return $user['last_name'] . ', ' . $user['first_name']; }, $users), function($name) { return stripos($name, 'd') === 0; } ), function($result, $value) { $target = stripos($value, 'bob') !== false ? 'bobs' : 'alices'; $result[$target][] = $value; return $result; }, ['bobs' => [], 'alices' => []] ); } 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 16
  • 17. $users = [ ['first_name' => 'Max', 'last_name' => 'Gopey', 'company' => 'CGI'], ['first_name' => 'Bob', 'last_name' => 'Doe', 'company' => 'Google'], ['first_name' => 'Alice', 'last_name' => 'Doe', 'company' => 'Google'], ];   print_r(getBobsAndAlicesWithD($users)); Array ( [bobs] => Array ( [0] => Doe, Bob ) [alices] => Array ( [0] => Doe, Alice ) ) 01. 02. 03. 04. 05. 06. 07. 17
  • 18. Chapter 3 Generators Traversable (Interface) ├── Iterator (Interface) │ └── Generator (Class) └── IteratorAggregate (Interface) 18
  • 19. function garbageGenerator() { $n = rand(1, 10); while ($n--) { yield md5(rand()); } } $garbage = garbageGenerator(); foreach ($garbage as $trash) { echo $trash, PHP_EOL; } 6e620c902c7088ace3ebf6c96f5dedd5 1340dcc6f3e0e39b4c48f480f5a92d52 c264962d537032be6c3a8a94eda811d4 0bfa2efb3909c105473a4fcaa71b697b 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 19
  • 20. function readFileLines($path) { $handle = fopen($path, 'r'); while ($line = fgets($handle)) { yield $line; } fclose($handle); }   $lines = readFileLines(__FILE__); foreach($lines as $line) { echo $line; }; 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 20
  • 22. function writer(InputStream $stream) { $stream->write('Message 1'); $stream->write('Message 2'); yield '2 messages written'; $stream->write('Message 3'); $stream->write('Message 4'); yield '2 messages written'; $stream->write('Message 5'); $stream->write('Message 6'); yield '2 messages written'; }   function reader(InputStream $stream) { foreach ($stream as $line) { if (strlen($line)) { yield $line; } else { $stream->close(); } } } $stream = new InputStream(); $queue[] = writer($stream); $queue[] = reader($stream);   while (true) { $continue = array_reduce( $queue, function($result, Iterator $queueItem) { if ($valid = $queueItem->valid()) { echo $queueItem->current(), "n"; $queueItem->next(); } return $result || $valid; }, false); if (!$continue) { break; } } 2 messages written Message 1 2 messages written Message 2 2 messages written Message 3 Message 4 Message 5 Message 6 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 22
  • 24. function getBobsAndAlicesWithD($users) { return array_reduce( array_filter( array_map(function($user) { return $user['last_name'] . ', ' . $user['first_name']; }, $users), function($name) { return stripos($name, 'd') === 0; } ), function($result, $value) { $target = stripos($value, 'bob') !== false ? 'bobs' : 'alices'; $result[$target][] = $value; return $result; }, ['bobs' => [], 'alices' => []] ); } 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 24
  • 25. Chapter 3 Non-standard PHP library (NSPL) Click me 25
  • 26. $startsWith = function ($string, $substing) { return stripos($string, $substing) === 0; }; $contains = function($string, $substing) { return stripos($string, $substing) !== false; }; $getFullName = function ($firstName, $lastName) { return $lastName . ', ' . $firstName; };   $startsWithD = frpartial($startsWith, 'd'); $isBob = frpartial($contains, 'bob');   $getFullNameFromUser = function ($user) use ($getFullName) { return $getFullName($user['first_name'], $user['last_name']); }; $getStackKey = function($name) use ($isBob) { return $isBob($name) ? 'bobs' : 'alices'; }; $putToCorrectStack = function($stacks, $value) use ($getStackKey) { $stacks[$getStackKey($value)][] = $value; return $stacks; }; 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 26
  • 27. $getBobsAndAlicesWithD = function ($users) use ($startsWithD, $getFullNameFromUser, $putToCorrectStack) { return fpipe( $users, fpartial(amap, $getFullNameFromUser), fpartial(afilter, $startsWithD), fppartial(areduce, [ 0 => $putToCorrectStack, 2 => ['bobs' => [], 'alices' => []] ]) ); };   print_r($getBobsAndAlicesWithD($users)); 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 27
  • 28. Chapter 3 Obvious logical operations 28
  • 29. if (anyOf([1, 3, 5])->is(5)) { // do something } if (anyOf([$name, $surname])->matches('/^w+$/') { // do something } if (allOf([1, 3, 5])->areNot(6)) { // do something } if (either($condition1)->or($condition2)) { // do something } if (neither($x)->nor($y)) { // do something } if (the($x)->isNeither(5)->nor(10)) { // do something } if (the($x)->isGreaterThan(5)->butLessThan(10)) { // do something } 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 29
  • 30. Chapter 3 Obvious regexp ____ _____ ____ _ _ _ ____ _ _ ____ | _ ___ __ _| ____|_ ___ __ | __ ) _ _(_) | __| | ___ _ __| _ | | | | _ | |_) / _ / _` | _| / / '_ | _ | | | | | |/ _` |/ _ '__| |_) | |_| | |_) | | _ < __/ (_| | |___ > <| |_) | |_) | |_| | | | (_| | __/ | | __/| _ | __/ |_| ____|__, |_____/_/_ .__/|____/ __,_|_|_|__,_|___|_| |_| |_| |_|_| |___/ |_| 30
  • 31. $regExp = $builder ->startOfInput() ->exactly(4)->digits() ->then("_") ->exactly(2)->digits() ->then("_") ->min(3)->max(10)->letters() ->then(".") ->anyOf(array("png", "jpg", "gif")) ->endOfInput() ->getRegExp();   //true $regExp->matches("2020_10_hund.jpg"); $regExp->matches("2030_11_katze.png"); $regExp->matches("4000_99_maus.gif");   //false $regExp->matches("123_00_nein.gif"); $regExp->matches("4000_0_nein.pdf"); $regExp->matches("201505_nein.jpg"); 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 31
  • 32. Useful links Generators and Coroutines •   Хабр: Coroutines в PHP и работа с неблокирующими функциями •   Github: Asynchronous coroutines for PHP 7. •   A Curious Course on Coroutines and Concurrency •   Symfony/Component/Process/InputStream.php Functional programming •   Github: Non-standard PHP library (NSPL) - compact functional programming oriented code Human-readable regular expressions •   Github: RegexpBuilderPHP •   Github: PHPVerbalExpressions Kittens •   Youtube: The funniest kitten in the world 32