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
KEY
Introduction à CoffeeScript pour ParisRB
KEY
テストデータどうしてますか?
PDF
[WLDN] Supercharging word press development in 2018
PDF
PHPUnit でよりよくテストを書くために
KEY
Introducing CakeEntity
KEY
Introducing CakeEntity
PDF
Doctrine For Beginners
50 Laravel Tricks in 50 Minutes
Introduction à CoffeeScript pour ParisRB
テストデータどうしてますか?
[WLDN] Supercharging word press development in 2018
PHPUnit でよりよくテストを書くために
Introducing CakeEntity
Introducing CakeEntity
Doctrine For Beginners

What's hot (20)

PDF
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
PDF
Transparent Object Persistence with FLOW3
PDF
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
PPTX
Comparing 30 MongoDB operations with Oracle SQL statements
PDF
The History of PHPersistence
KEY
(Ab)Using the MetaCPAN API for Fun and Profit
PDF
CakeFest 2013 keynote
PDF
Developing applications for performance
PDF
The Zen of Lithium
PDF
PHP 5.3 and Lithium: the most rad php framework
PPTX
Database performance 101
PDF
Advanced Querying with CakePHP 3
PDF
The Origin of Lithium
PDF
Doctrine MongoDB ODM (PDXPHP)
PDF
Lithium: The Framework for People Who Hate Frameworks
KEY
The Query the Whole Query and Nothing but the Query
PPTX
PyCon APAC - Django Test Driven Development
PPTX
PHP performance 101: so you need to use a database
PDF
Doctrine fixtures
PDF
jQuery%20on%20Rails%20Presentation
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Transparent Object Persistence with FLOW3
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
Comparing 30 MongoDB operations with Oracle SQL statements
The History of PHPersistence
(Ab)Using the MetaCPAN API for Fun and Profit
CakeFest 2013 keynote
Developing applications for performance
The Zen of Lithium
PHP 5.3 and Lithium: the most rad php framework
Database performance 101
Advanced Querying with CakePHP 3
The Origin of Lithium
Doctrine MongoDB ODM (PDXPHP)
Lithium: The Framework for People Who Hate Frameworks
The Query the Whole Query and Nothing but the Query
PyCon APAC - Django Test Driven Development
PHP performance 101: so you need to use a database
Doctrine fixtures
jQuery%20on%20Rails%20Presentation
Ad

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

KEY
Spl Not A Bridge Too Far phpNW09
PDF
How to write code you won't hate tomorrow
PPTX
Arrays in PHP
PDF
The Art of Transduction
DOCX
PHP record- with all programs and output
PDF
lab4_php
PDF
lab4_php
PDF
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PDF
Object Oriented Programming with PHP 5 - More OOP
PDF
Building scalable products with WordPress - WordCamp London 2018
KEY
Can't Miss Features of PHP 5.3 and 5.4
PPT
Class 4 - PHP Arrays
PPTX
Professional-grade software design
PPTX
PHP Functions & Arrays
PDF
New in cakephp3
PDF
Php tips-and-tricks4128
PDF
PHP tips and tricks
PDF
Advanced Php - Macq Electronique 2010
PDF
Banishing Loops with Functional Programming in PHP
PPT
Introduction to Template::Toolkit
Spl Not A Bridge Too Far phpNW09
How to write code you won't hate tomorrow
Arrays in PHP
The Art of Transduction
PHP record- with all programs and output
lab4_php
lab4_php
PHPCon 2016: PHP7 by Witek Adamus / XSolve
Object Oriented Programming with PHP 5 - More OOP
Building scalable products with WordPress - WordCamp London 2018
Can't Miss Features of PHP 5.3 and 5.4
Class 4 - PHP Arrays
Professional-grade software design
PHP Functions & Arrays
New in cakephp3
Php tips-and-tricks4128
PHP tips and tricks
Advanced Php - Macq Electronique 2010
Banishing Loops with Functional Programming in PHP
Introduction to Template::Toolkit
Ad

Recently uploaded (20)

PPTX
history of c programming in notes for students .pptx
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PPTX
Embracing Complexity in Serverless! GOTO Serverless Bengaluru
PDF
Digital Systems & Binary Numbers (comprehensive )
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PPTX
Transform Your Business with a Software ERP System
PPTX
Computer Software and OS of computer science of grade 11.pptx
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
Reimagine Home Health with the Power of Agentic AI​
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Softaken Excel to vCard Converter Software.pdf
history of c programming in notes for students .pptx
Wondershare Filmora 15 Crack With Activation Key [2025
Which alternative to Crystal Reports is best for small or large businesses.pdf
Embracing Complexity in Serverless! GOTO Serverless Bengaluru
Digital Systems & Binary Numbers (comprehensive )
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Navsoft: AI-Powered Business Solutions & Custom Software Development
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Transform Your Business with a Software ERP System
Computer Software and OS of computer science of grade 11.pptx
Upgrade and Innovation Strategies for SAP ERP Customers
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Reimagine Home Health with the Power of Agentic AI​
CHAPTER 2 - PM Management and IT Context
How to Migrate SBCGlobal Email to Yahoo Easily
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
2025 Textile ERP Trends: SAP, Odoo & Oracle
Softaken Excel to vCard Converter Software.pdf

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