Pro Functional PHP Programming Application Development Strategies For Performance Optimization Concurrency Testability and Code Brevity Rob Aley Instant Download
Pro Functional PHP Programming Application Development Strategies For Performance Optimization Concurrency Testability and Code Brevity Rob Aley Instant Download
https://ebookbell.com/product/pro-functional-php-programming-rob-
aley-6723920
https://ebookbell.com/product/excel-2024-from-beginner-to-pro-a-
comprehensive-guide-to-excels-power-and-potential-functions-
calculations-charts-pivot-tables-with-3-bonus-robert-knowless-55513484
Excel 2022 From Basic To Advanced The Most Exhaustive Guide To Become
A Pro In Less Than 7 Days And Master All The Functions Formulas
Includes Practical Examples And Stepbystep Instructions George
Wahlberg
https://ebookbell.com/product/excel-2022-from-basic-to-advanced-the-
most-exhaustive-guide-to-become-a-pro-in-less-than-7-days-and-master-
all-the-functions-formulas-includes-practical-examples-and-stepbystep-
instructions-george-wahlberg-45108596
Pro Data Mashup For Power Bi Powering Up With Power Query And The M
Language To Find Load And Transform Data 1st Edition Adam Aspin
https://ebookbell.com/product/pro-data-mashup-for-power-bi-powering-
up-with-power-query-and-the-m-language-to-find-load-and-transform-
data-1st-edition-adam-aspin-44868580
Pro Php Refactoring Francesco Trucchia Jacopo Romei
https://ebookbell.com/product/pro-php-refactoring-francesco-trucchia-
jacopo-romei-46096178
https://ebookbell.com/product/pro-django-marty-alchin-46553836
https://ebookbell.com/product/pro-cryptography-and-cryptanalysis-
with-c20-marius-iulian-mihailescu-46619890
https://ebookbell.com/product/pro-power-bi-theme-creation-json-
stylesheets-for-automated-dashboard-formatting-converted-adam-
aspin-46745534
Pro Sql Server 2022 Administration A Guide For The Modern Dba 3rd
Edition Peter A Carter
https://ebookbell.com/product/pro-sql-server-2022-administration-a-
guide-for-the-modern-dba-3rd-edition-peter-a-carter-47331394
Pro Functional
PHP Programming
Application Development Strategies for
Performance Optimization, Concurrency,
Testability, and Code Brevity
—
Rob Aley
www.allitebooks.com
Pro Functional PHP
Programming
Application Development Strategies for
Performance Optimization, Concurrency,
Testability, and Code Brevity
Rob Aley
www.allitebooks.com
Pro Functional PHP Programming: Application Development Strategies for Performance Optimization,
Concurrency, Testability, and Code Brevity
Rob Aley
Oxford, United Kingdom
ISBN-13 (pbk): 978-1-4842-2957-6 ISBN-13 (electronic): 978-1-4842-2958-3
DOI 10.1007/978-1-4842-2958-3
Library of Congress Control Number: 2017954985
Copyright © 2017 by Rob Aley
This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with
every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an
editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are
not identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Cover image by Freepik (www.freepik.com)
Managing Director: Welmoed Spahr
Editorial Director: Todd Green
Acquisitions Editor: Steve Anglin
Development Editor: Matthew Moodie
Technical Reviewer: Christopher Pitt
Coordinating Editor: Mark Powers
Copy Editor: Kim Wimpsett
Distributed to the book trade worldwide by Springer Science+Business Media New York,
233 Spring Street, 6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail
[email protected], or visit www.springeronline.com. Apress Media, LLC is a California LLC
and the sole member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc).
SSBM Finance Inc is a Delaware corporation.
For information on translations, please e-mail [email protected], or visit www.apress.com/
rights-permissions.
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and
licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales
web page at www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to
readers on GitHub via the book’s product page, located at www.apress.com/9781484229576. For more
detailed information, please visit www.apress.com/source-code.
Printed on acid-free paper
www.allitebooks.com
Contents at a Glance
■
■Part I: Functional Programming in PHP 7������������������������������������������� 1
■
■Chapter 1: Introduction����������������������������������������������������������������������������������������� 3
■
■Chapter 2: Functional Programming: Key Concepts�������������������������������������������� 11
■
■Chapter 3: Getting Started with Functional Patterns������������������������������������������� 45
■
■Chapter 4: Advanced Functional Techniques������������������������������������������������������� 69
■
■Part II: Application Development Strategies����������������������������������� 101
■
■Chapter 5: Strategies for High-Performance Applications�������������������������������� 103
■
■Chapter 6: Managing Business Logic with Functions���������������������������������������� 147
■■Chapter 7: Using Functional Programming in Objected-Oriented and
Procedural Applications������������������������������������������������������������������������������������ 165
■
■Chapter 8: Using Helper Libraries in Your Application�������������������������������������� 189
■
■Chapter 9: Processing Big Data with Functional PHP��������������������������������������� 213
■
■Chapter 10: Afterword��������������������������������������������������������������������������������������� 229
■
■Appendix A: Installing PHP and Libraries���������������������������������������������������������� 231
■
■Appendix B: Command-Line PHP����������������������������������������������������������������������� 247
■
■Appendix C: Functional Programming Resources��������������������������������������������� 269
Index��������������������������������������������������������������������������������������������������������������������� 289
iii
www.allitebooks.com
Contents
■
■Part I: Functional Programming in PHP 7������������������������������������������� 1
■
■Chapter 1: Introduction����������������������������������������������������������������������������������������� 3
Who Is This Book For?������������������������������������������������������������������������������������������������������ 3
What Is Functional Programming?����������������������������������������������������������������������������������� 3
Functional Programming Is SOLID���������������������������������������������������������������������������������������������������������� 6
What Are the Benefits of Functional Programming?������������������������������������������������������������������������������� 7
Who Uses Functional Programming, and Why?�������������������������������������������������������������������������������������� 7
Is Functional Programming “All or Nothing”?����������������������������������������������������������������������������������������� 8
Further Reading�������������������������������������������������������������������������������������������������������������������������������������� 8
What Is a Function?�������������������������������������������������������������������������������������������������������� 17
www.allitebooks.com
■ Contents
Named Functions����������������������������������������������������������������������������������������������������������� 17
Variable Functions���������������������������������������������������������������������������������������������������������� 23
Language Constructs����������������������������������������������������������������������������������������������������� 24
Return Values����������������������������������������������������������������������������������������������������������������� 25
Lambda/Anonymous Functions�������������������������������������������������������������������������������������� 27
Higher-Order Functions�������������������������������������������������������������������������������������������������� 31
Scope����������������������������������������������������������������������������������������������������������������������������� 35
Further Reading������������������������������������������������������������������������������������������������������������������������������������ 37
State������������������������������������������������������������������������������������������������������������������������������� 37
Parameters/Arguments/Operands, Arity, and Variadic Functions����������������������������������� 38
Further Reading������������������������������������������������������������������������������������������������������������������������������������ 40
Closures������������������������������������������������������������������������������������������������������������������������� 40
Side Effects�������������������������������������������������������������������������������������������������������������������� 42
Referential Transparency������������������������������������������������������������������������������������������������ 42
Pure Functions��������������������������������������������������������������������������������������������������������������� 44
Lists and Collections������������������������������������������������������������������������������������������������������ 44
Further Reading������������������������������������������������������������������������������������������������������������������������������������ 44
Conclusion���������������������������������������������������������������������������������������������������������������������� 44
■
■Chapter 3: Getting Started with Functional Patterns������������������������������������������� 45
Map, Filter, and Reduce�������������������������������������������������������������������������������������������������� 45
Recursive Functions������������������������������������������������������������������������������������������������������� 48
Basic Recursion������������������������������������������������������������������������������������������������������������������������������������ 48
vi
www.allitebooks.com
■ Contents
■
■Chapter 4: Advanced Functional Techniques������������������������������������������������������� 69
Currying Functions��������������������������������������������������������������������������������������������������������� 69
The Mysterious Monad��������������������������������������������������������������������������������������������������� 72
What Is a Monad?����������������������������������������������������������������������������������������������������������� 72
The Maybe Monad�������������������������������������������������������������������������������������������������������������������������������� 76
Monad Axioms���������������������������������������������������������������������������������������������������������������� 79
Monad Axiom 1������������������������������������������������������������������������������������������������������������������������������������� 79
Monad Axiom 2������������������������������������������������������������������������������������������������������������������������������������� 79
Monad Axiom 3������������������������������������������������������������������������������������������������������������������������������������� 80
Summary������������������������������������������������������������������������������������������������������������������������ 99
■
■Part II: Application Development Strategies����������������������������������� 101
■
■Chapter 5: Strategies for High-Performance Applications�������������������������������� 103
Understanding and Measuring Performance���������������������������������������������������������������� 103
Measuring Performance: Profiling�������������������������������������������������������������������������������� 103
Manual Profiling����������������������������������������������������������������������������������������������������������� 104
Profiling Tools��������������������������������������������������������������������������������������������������������������� 106
Further Reading and Tools������������������������������������������������������������������������������������������������������������������ 107
vii
www.allitebooks.com
■ Contents
Memoization����������������������������������������������������������������������������������������������������������������� 108
Further Reading���������������������������������������������������������������������������������������������������������������������������������� 120
The Downsides of Memoization���������������������������������������������������������������������������������������������������������� 120
Generators�������������������������������������������������������������������������������������������������������������������� 122
Further Reading���������������������������������������������������������������������������������������������������������������������������������� 130
The Downsides of Lazy Evaluation����������������������������������������������������������������������������������������������������� 130
Conclusion�������������������������������������������������������������������������������������������������������������������� 145
■
■Chapter 6: Managing Business Logic with Functions���������������������������������������� 147
Managing Business Logic�������������������������������������������������������������������������������������������� 147
Event-Based Programming������������������������������������������������������������������������������������������ 154
Further Reading���������������������������������������������������������������������������������������������������������������������������������� 156
viii
www.allitebooks.com
■ Contents
ix
www.allitebooks.com
■ Contents
■
■chapter 10: Afterword��������������������������������������������������������������������������������������� 229
Where to Now?������������������������������������������������������������������������������������������������������������� 229
Giving Feedback and Getting Help and Support����������������������������������������������������������� 230
■
■Appendix A: Installing PHP and Libraries���������������������������������������������������������� 231
Compiling and Installing PHP��������������������������������������������������������������������������������������� 231
Microsoft Windows����������������������������������������������������������������������������������������������������������������������������� 232
macOS/OS X��������������������������������������������������������������������������������������������������������������������������������������� 232
Linux/Unix������������������������������������������������������������������������������������������������������������������������������������������� 233
www.allitebooks.com
■ Contents
■
■Appendix B: Command-Line PHP����������������������������������������������������������������������� 247
PHP Without a Web Server������������������������������������������������������������������������������������������� 247
What’s Different About the CLI SAPI?��������������������������������������������������������������������������� 248
Further Reading���������������������������������������������������������������������������������������������������������������������������������� 249
xi
■ Contents
■
■Appendix C: Functional Programming Resources��������������������������������������������� 269
Other Programming Languages����������������������������������������������������������������������������������� 269
Functional Programming and Other Paradigms����������������������������������������������������������� 269
Articles����������������������������������������������������������������������������������������������������������������������������������������������� 269
Online Books��������������������������������������������������������������������������������������������������������������������������������������� 270
Videos������������������������������������������������������������������������������������������������������������������������������������������������� 270
xii
■ Contents
Index��������������������������������������������������������������������������������������������������������������������� 289
xiii
About the Author
Rob Aley I’ve been programming in PHP since late 2000. Initially it
wasn’t by choice because my preferred languages at the time were Perl
and Delphi (also known as Object Pascal). Things began to change after I
graduated from the University of Leeds with a degree in computer science
in 1999 and started out in a career as a freelance web developer. After only
a couple of months I was offered the opportunity to take over a (relatively
speaking) substantial government web site contract from a friend who
was exiting the freelance world for the safer and saner world of full-time
employment. The only catch was that several thousand lines of code had
already been written, and they were written in a relatively new language
called PHP. Oh, and the only other catch was that I had about a week to
learn it before taking over the site. So, as was the way at the time, I popped
down to the local Waterstones bookshop. (For the younger among you
that’s where we used to get books. And we had to go out and get them.
Or order online and wait many days for them to be delivered.) With my
paper copies of The Generic Beginner’s Complete Guide to PHP and MySQL
for Dummies Compendium (I may not have recalled the titles completely
correctly), I settled down with a pint of ale (I’m in Yorkshire at this point, remember) and set about reading
them. A few days later I was coding like a pro (well, stuff was working), and 17 years later I haven’t looked
back. Over those 17 years PHP has changed vastly (the source code for the government web site I mentioned
was littered with comments like “# Would have used a foreach here, if PHP had one…”) and so have I. I like to
think that both I and PHP have only improved and matured over the years.
After a varied career as a freelancer and starting up a couple of, er, startups (IT related and not) with
varying (usually dismal) success, I spent the past ten years as a programmer at the University of Oxford.
My day job involved performing medium-scale data acquisition and management, doing statistical analysis,
and providing user interfaces for researchers and the public. The majority of my development work was
done in PHP, either developing new projects or gluing together other people’s software, systems, and
databases. I’ve recently left the university to concentrate on writing books like this and providing consulting
and training (in PHP, information governance, and related areas). But I’m still programming in PHP!
Throughout my career I’ve always used PHP for web development, but for desktop GUI work I initially
used Delphi (and then Free-Pascal/Lazarus), complemented with Bash shell scripting for CLI-based
tasks. This was mainly because I learned them while at university. However, as PHP has matured, I’ve
increasingly used it beyond the Web, and now I rarely use anything else for any programming or scripting
task I encounter. Having been immersed in other languages such as C++, JavaScript, Fortran, and Lisp
(and probably others that my brain has chosen deliberately not to remember) by necessity during university
and in some of my freelance jobs, I can honestly say that PHP is now my language of choice, rather than of
necessity. At university (in the late 1990s) I took a couple of classes that involved functional programming,
but at the time I really didn’t “get the point.” It’s only in recent years that I’ve picked up functional-style
programming again, partly because of the “buzz” that’s developed around it and partly because as my
programming styles have “matured,” I’ve seen the advantages to functional coding.
xv
■ About the Author
When I’m not tied to a computer, I would like to say I have lots of varied and interesting hobbies. I used
to have. I could write a whole book (which wouldn’t sell well) about where I’ve been and what I’ve done,
and I’d like to think it’s made me a well-rounded person. But these days I don’t have any. In large part, this
is because of the demands of my three gorgeous young daughters, Ellie, Izzy, and Indy; my gorgeous wife,
Parv; and my even more gorgeous cat, Mia. And I wouldn’t have it any other way. That’s what I tell myself,
anyway….
—Rob Aley
xvi
About the Technical Reviewer
Christopher Pitt is a developer and writer, working at SilverStripe. He usually works on application
architecture, though sometimes you’ll find him building compilers or robots. He is also the author of several
web development books and is a contributor on various open source projects like AdonisJs.
xvii
Acknowledgments
Isaac Newton said, “If I have seen further, it is by standing on the shoulders of giants.” This book builds on,
and I hope adds to, the work of many others, the most notable of whom I would like to acknowledge here.
• The authors of, and contributors to, the official PHP Manual: This is an invaluable
reference for PHP functions and syntax, to which I referred frequently during writing
this book, both for fact checking and as an aide-mémoir. Thanks!
• The collective PHP and functional programming wisdom of the Internet: For more
than 17 years I’ve used you for learning, research, play, and profit. There are too
many sites and too many people to list here; if you’ve written about PHP on the Web,
then you may well be one of them. Thanks!
• My family: Thanks for allowing me a modicum of time to write this book and
supporting me unconditionally in everything I do. Usually. If I ask first. And there’s
not something more important going on. And usually with conditions. Thanks!
xix
PART I
Functional Programming
in PHP 7
CHAPTER 1
Introduction
Functional programming isn’t something that is often associated with PHP. Yet for quite a while PHP has had
all the features necessary to create software using the functional paradigm. In this book, you’ll take a look
at what functional programming is, how to do it in PHP, and the different ways in which you can use it to
improve your PHP software.
That is my definition of functional programming. Ask five other functional programmers to define functional
programming and you’ll get four more answers (two just copied the same answer from Wikipedia). There’s
no “standard” definition; different people and different programming languages implement functional
programming elements differently. These differences are partly because of the practicalities of the language
in question and sometimes because of the target platforms, data, and usage scenarios, but often they come
down to what I call “programming religion”: a fixed, sometimes irrational, but often deeply held belief of
how a particular paradigm should be. Even within the small community of PHP functional programmers,
you won’t find an exact consensus. In PHP, functional programming is not a core concept, but even in
languages where it is (e.g., Lisp, Scala, etc.), there are many “related” understandings of what constitutes true
functional programming. While that may sound problematic, you’ll still “know it when you see it,” and when
it gets woolly around the edges, you can choose to define it in any way you see fit!
© Rob Aley 2017 3
R. Aley, Pro Functional PHP Programming, DOI 10.1007/978-1-4842-2958-3_1
Chapter 1 ■ Introduction
PHP isn’t a pure functional programming language, but you can still use it for functional programming
(which is good; otherwise this book wouldn’t be very long). A few elements of what some purists consider to
be essential functional programming concepts are harder to implement with PHP’s standard syntax, so it’s
perhaps slightly more accurate to say that you can program in a functional programming “style” in PHP.
Let’s now look a little more in depth at what functional programming actually is in practice. Functional
programming is a “declarative” style of programming, which means you specify what you want it to do rather
than how you want to do it. It’s a higher level of abstraction than you may be used to with OO or procedural
programming. However, you almost certainly use declarative programming on a day-to-day basis when using
SQL, HTML, regular expressions, and similar languages. Consider the SQL snippet shown in Listing 1-1.
Surname
FROM users
WHERE username = 'rob'
This is telling your database server what you want it to do (select the real name based on super-secret
security credentials), but you don’t tell it how to do it. You don’t tell it the following:
• Where to look on disk for the data
• How to parse or search the data for matching records
• How to determine whether a record matches your criteria
• How to extract the relevant fields from the record
And so on. You simply tell it what you want it to achieve for you.
Now obviously, at some point, you need to tell the computer how to do something. With the SQL example
in Listing 1-1, you do that by getting some rather clever people to write database management software
(DBMS) for you. In functional programming, you’ll tend to need to write the implementation code yourself,
but to make it a manageable task, you break that down into the smallest possible chunks and then use a
hierarchical chain of declarative function calls to tell the computer what to do with that code. If you use the
Composer dependency management system, you will already be using a similar paradigm: there are many
libraries of code available that abstract away the tasks that you need to do; you simply “compose” a list of
libraries together to do what you want. In functional programming, you do exactly the same; you take functions
that do something (like the libraries Composer provides) and compose them together into a program.
Having a program that is essentially a list of what you want to achieve sounds very good on paper,
and indeed it makes it easy to understand and reason about your program. To make the idea a little more
concrete, let’s take a look at a small functional-style program (Listing 1-2).
require_once('image_functions.php');
require_once('stats_functions.php');
4
Chapter 1 ■ Introduction
require_once('data_functions.php');
$csv_data = file_get_contents('my_data.csv');
$chart = make_chart_image (
generate_stats (
data_to_array (
$csv_data
)
)
);
file_put_contents('my_chart.png', $chart);
This is clearly some code that has been abstracted into a set of functions that set out what it does (draw
a chart based on some stats prepared from some data that is read in). You can also probably see that the
how is hidden away in the required files at the top, but it is still clear as to what the program does. Should
your requirements change and instead of drawing a chart you want to print a table, you can simply swap
out draw_chart() for print_table() and it is clear what will happen. This is a (very loose) example of a
functional program.
That all sounds great. But without even considering the code hidden away in the required files, your
programmer instincts are probably telling you that chaining random functions together, and swapping out
one for another, is a risky proposition particularly when you can’t see how they’re implemented. For instance,
how do you know that read_data() will return data in the correct format for prepare_stats() to work on?
And how can you be sure that you can swap out draw_chart() for prepare_stats() and it will all still work
as you expect? Clearly, functional programming involves a little more than “chuck it all in a function with a
descriptive name,” and as you go through the book, you’ll look at the various ways to structure functions so
that you can use them as “little black boxes” of code that can be easily and reliably strung together.
Functional programming revolves around functions, as the name implies. However, functions in the
functional programming sense aren’t quite the same as functions in the PHP syntax sense, although you will
use PHP’s implementation of functions to implement FP functions. A functional programming function is
often referred to as a pure function and has several important characteristics that can be mimicked with, but
aren’t enforced by, PHP’s syntax. A pure function has the following traits:
• Is referentially transparent
• Is devoid of side effects
• Has no external dependencies
I’ll talk more in detail about what these features mean in the next couple of chapters, but they boil down
to a function being a small self-contained “black box” that takes well-defined inputs, produces well-defined
outputs, and given the same inputs always produces the same outputs. In particular, the function only
acts on the inputs it is given (it doesn’t take into account any external state or data and relies only on the
parameters it is called with), and the only effect it has is to return some output (which will be the same each
time you give it the same input); thus, it doesn’t alter the state of the program or system outside of itself.
5
Chapter 1 ■ Introduction
In the example program in Listing 1-2, if you give exactly the same CSV file to read_data() each time,
and assuming you have properly used functional programming, you can be sure that draw_chart() will
produce exactly the same chart each time, regardless of anything else going on elsewhere in the program or
on your system. This ability to be sure of, and reason about, the program flow leads to a number of benefits
for the functional programming paradigm that you’ll discover as you learn more about implementing
functional programming programs.
6
Chapter 1 ■ Introduction
Further Reading
• The SOLID principles on Wikipedia
• https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
7
Chapter 1 ■ Introduction
Functional programming has been gaining more and more traction over the past few years. Modern
functional languages like Racket, Clojure, and F# are building steam, and even PHP is getting in on the act
with an ever-growing range of functional programming libraries becoming available on GitHub and through
Composer.
But while it’s currently a hot topic in modern computing, functional programming’s history in
computing stretches back to Lisp in the 1950s, while lambda calculus (the mathematical abstraction on
which functional programming is based) and the more abstract field of combinatory logic began life in the
1920s and 1930s. Both directly in languages like Lisp and Scheme and indirectly in functional-style code
written in most programming languages, functional programming has had an influence in many fields of
computing over the years. Many companies write functional programming code and rely on functional
programming software on a day-to-day basis (whether they realize it or not!).
Further Reading
• A comparison of programming paradigms on Wikipedia
• https://en.wikipedia.org/wiki/Comparison_of_programming_paradigms
8
Chapter 1 ■ Introduction
9
Chapter 1 ■ Introduction
PHP Versions
At the time of writing, the current stable release of PHP is 7.1.2, and it would be lovely if that was the version
that everyone is running. However, it isn’t; indeed, PHP versions all the way back to 5.2 can be found in
mainstream use across hosting providers and inside companies. Tales of people using even older versions
abound in the darker corners of the Internet, and with security updates available only for 5.6 and higher,
such tales are the stuff nightmares are made of. So, which version should you choose (if indeed you have the
choice) for functional programming?
All the code in this book was developed and tested on the current release of version 7.1 of PHP. However,
most of the code will run with minor changes on any version from 5.4 onward. Versions older than 5.4 lack
the language support for anonymous functions and closures, which means that functional programming
isn’t practical. I’ll point out any differences between version support throughout the book, the most notable
of which will be the lack of support for type declarations (also known as type hints) for scalar variables in the
series 5 versions. Do note that “Active Support” for the last 5.x version, 5.6, has now ended, and “Security Fixes
Only” support is due to be withdrawn in late 2018, so using a 7.x version is highly recommended if possible.
As well as continued support from the PHP maintainers, you’ll find that the lower resource requirements of
PHP 7 will help in some areas of functional programming with PHP such as recursion. That said, you can do
functional programming in PHP 5, and the inevitable upgrade lag in many workplaces may mean that you
have no choice to use a 5.x version, so I’ll do my best to cover the differences as I go along.
Conclusion
In this chapter, you started looking at what functional programming is and why it can be useful in your PHP
development. Functional programming can be hard to grasp from such an abstract discussion, so don’t
worry if you don’t “get it” yet. As you go through the next few chapters, you’ll get a better feel for it as you see
the programming concepts behind it and examples of functional code.
10
CHAPTER 2
Functional Programming:
Key Concepts
In this chapter, you’ll look at the key concepts, building blocks, and vocabulary that you’ll need to understand
before getting started on some actual functional programming. Although you are already likely to be using
functions and closures in your everyday programming, it’s worth taking the time to read the following sections
that describe them from first principles as some of the details that you take for granted when using them
in object-oriented or plain procedural programming can trip you up when applying them in the functional
paradigm. As functional programming is rooted in math, you’ll also take a look some language that you may
be unfamiliar with and see it in terms that are easy to understand for a regular programmer.
The concepts presented in this chapter, taken individually, may paint a confusing picture about what
functional programming is and what benefits it can bring. For instance, I’ll talk about immutability, which is
essentially the inability to change a value. That seems like a drawback at first rather than a benefit, but when
you draw all of these concepts together over the next couple of chapters, you will see that immutability plays
a key part in the flexible recipe-like nature of functional programming and is one of the factors that allows
you to easily reason about your functional code.
So, for now, try to focus on understanding the individual concepts as presented and don’t worry too
much about how they all fit together. Learning functional programming is much like writing functional
programming code—lots of small independent functions/ideas composed into an over-arching scheme that
eventually does something!
Examining State
As you go through the book, particularly when you look at types, there may be times when you do not feel
confident about the state of a variable, object, or function in your code. State includes the current contents
of the thing you are examining and its current type. PHP provides a couple of handy functions, print_r and
var_dump, to help you “look” at what’s happening in your code. See Listing 2-1.
define('MY_CONSTANT', 'banana');
$my_array = [1,2,'apple',MY_CONSTANT,$my_function];
print_r($my_array);
var_dump($my_array);
Running the script in Listing 2-1 gives the output shown in Listing 2-2.
Array
(
[0] => 1
[1] => 2
[2] => apple
[3] => banana
[4] => Closure Object
(
[parameter] => Array
(
[$data] => <required>
)
)
var_dump output :
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
string(5) "apple"
[3]=>
string(6) "banana"
[4]=>
object(Closure)#1 (1) {
["parameter"]=>
array(1) {
["$data"]=>
string(10) "<required>"
}
}
}
12
Chapter 2 ■ Functional Programming: Key Concepts
As you can see, the functions produce similar output. print_r is formatted for easier reading by humans,
and var_dump provides slightly more information about basic types. I usually use var_dump, reverting to
print_r when I have a particularly dense data structure to look through as the formatting can make it easier.
Another function that’s particularly useful in functional programming is debug_print_backtrace().
Functional programming usually involves composing many single-purpose functions together into stacks
of functions that represent your program. When an error does occur, it can be hard to track down exactly
which of the many functions you have used in your stack is causing the error. A backtrace shows where you
are in the function call stack at that moment and is commonly displayed by debuggers and code profilers.
The debug_print_backtrace() function can allow you to print the call stack from within your code, as the
contrived example in Listing 2-3 demonstrates (Listing 2-4 shows the output).
function prepare_text($text) {
return make_headline($text);
function make_headline($text) {
function upper_case($text) {
return strtoupper($text);
function add_h_tags($text) {
debug_print_backtrace();
return '<h1>'.$text.'</h1>';
$title = prepare_text('testing');
echo $title;
13
Chapter 2 ■ Functional Programming: Key Concepts
The top of the list has the most recent function called (in this case, add_h_tags()), all the way down to
the initiating function (prepare_text()). Note that although the make_headline() function calls the upper_
case() function, it is not in the backtrace. This is because it has completed its execution and is not waiting
for the output of the next function in the chain before it returns its own output (as is the case for the other
three functions, which are still in the stack).
The three functions mentioned are most useful when you’re learning and experimenting with code,
particularly if you use a read-eval-print-loop (REPL; see Appendix B for more information) to test and hack
on code. In proper development and production code, you should use debuggers, profilers, and secure
logging to keep track of what your code is doing; using print_r and var_dump can accidentally spill internal
data to the outside world and cause various security issues.
var_dump($a);
$a = 2;
var_dump($a);
$a = "Banana";
var_dump($a);
First, $a is set to 1. Then, because it is mutable, you can “mutate” (change) it to be equal to 2. Finally,
you mutate it again to Banana. Note that in the last change, you not only mutate the variable but also the
type, from int to string.
In functional programming, you want values (represented by functions) to be immutable. This is
important in helping you to reason about your program and to allow you to loosely couple functions
together. You’ll look at this more in detail later.
PHP has limited support for immutability, mainly in the form of “constants” defined using either the
define() function or the const keyword. There are a few differences between how and what you can declare
constant when using define() versus const, but once declared, the constants created by either method are
the same. One thing they both have in common is that only scalars or arrays can be constants. Listing 2-7
tries to create a constant from a variable holding an anonymous function. Listing 2-8 shows the output.
14
www.allitebooks.com
Chapter 2 ■ Functional Programming: Key Concepts
define('DOUBLE',$double);
Here you can see that you get a warning when trying to use the variable holding the function in
define(), and when you try to use the DOUBLE constant, you get confirmation (via a fatal error) that it did
indeed fail to be defined.
So, without much help from PHP, you will need to ensure immutability yourself through discipline
when coding. One of the key ways to help achieve this is to avoid using assignment, and you’ll look at
ways to do this as you go through the book. The lack of support for immutability in PHP (compared to
other languages) is one of the main things people will point out when you tell them you are using PHP for
functional programming. However, it does not in any way stop you from writing functional programs in PHP;
you simply need to keep it in mind as you code.
As well as watching what you do yourself, you need to keep half an eye on what PHP is doing. A key
thing to think about is how PHP’s own functions operate on your variables. For instance, the function sort()
mutates (i.e., sorts) the array it is passed, rather than returning a new array that is a sorted version of the old
array (and leaving the old array unmutated). However, you can make your own immutable version of sort()
quite easily (see Listing 2-9 and Listing 2-10).
function immutable_sort($array) {
sort($array);
return $array;
15
Chapter 2 ■ Functional Programming: Key Concepts
print_r( $ordered );
print_r( $vegetables );
sort( $vegetables );
print_r( $vegetables );
This works because by default PHP function parameters are passed by value and not by reference. This
means that when you call a function, it gets a copy of any variables that you give as parameters, rather than a
reference to the variable itself. Anything the function does to that copy does not affect the original variable.
PHP does allow you to pass in a parameter by reference (which is what sort() uses to mutate the original
array), but this is not the default. When you pass in an object or resource, you are passing in an object or
resource variable, which is a pointer to that object or resource. The variable is still passed by value; however,
the new copy of the variable is still pointing to the original object or resource, so it acts in a similar manner to
passing by value. You’ll look at that issue in depth in Chapter 7.
16
Chapter 2 ■ Functional Programming: Key Concepts
In most cases, it is obvious which functions will mutate their parameters; they usually don’t supply their
output as a return value, but some take a mixture of by value and by reference parameters, so always check
the PHP Manual if you’re not sure.
Further Reading
• Constants in the PHP Manual
• http://php.net/manual/en/language.constants.php
• A comprehensive synopsis of the differences between define() and const
• http://stackoverflow.com/a/3193704
What Is a Function?
You probably have a reasonable idea about what a function is, and you probably use them regularly in your
PHP code. However, I’ll cover functions from scratch because a good understanding of the fundamentals of
how PHP implements functions, and the different ways of handling them, is necessary to understand how to
implement functional programming in PHP.
You’ll develop a better feeling for exactly what a function is, in terms of functional programming, over
the course of this chapter. But here’s a good starting definition:
PHP lets you work with several different invocations of functions, which you’ll look at in turn next.
Named Functions
A standard named function is the basic way to use functions in PHP. A named function looks something like
the my_function() function in Listing 2-11 (the output is shown in Listing 2-12).
return $sum;
$value1 = my_function(10,20);
var_dump( $value1 );
$value2 = my_function(6,9)
var_dump( $value2 );
17
Chapter 2 ■ Functional Programming: Key Concepts
The function is created using the “function” language construct. It has a name (my_function), which is
used to call it later. It has parameters (in this case two), which allow you to pass values to the code inside the
function. It carries out some useful work (in this case adding the parameters together and returning them).
It has a return statement that sets the value of the function. As you can see from this example, the function’s
value is often dependent on external values, in this case by changing the parameters given as input. The
return value, however, can depend on external sources of state not directly passed in by parameters, as
demonstrated by Listing 2-13 and Listing 2-14.
$oranges = 3;
global $oranges;
return $num_fruit;
function get_date() {
var_dump( count_fruit(6,7) );
var_dump( get_date() );
count_fruit() uses the global variable $orange, the value of which is set outside of the function, in its
calculation of the return value. get_date() doesn’t ask for any parameters at all and calculates its return value
based on an external shell command. In both cases, these are potential causes of “side effects,” which you will
look at later, and show that functions in PHP aren’t restricted to operating on only the parameters supplied.
This is a key difference with mathematical functions. The functional in functional programming refers to the
mathematical concept of a function and not the programming concept of a function. Mathematical functions are
pure functions, which you’ll look at shortly.
18
Chapter 2 ■ Functional Programming: Key Concepts
function list_fruit($item) {
return ['apple','orange','mango'][$item];
function list_meat($item) {
return ['pork','beef','human'][$item];
$the_list = 'list_fruit';
var_dump( call_user_func($the_list, 2) );
$the_list = 'list_meat';
var_dump( call_user_func($the_list, 1) );
As you can see, you can pass call_user_func() the name (as a string) of a function (plus any
parameters you want to supply the function), and call_user_func() will return the return value from the
function you called as its own return value. And as you can see, you can change the name of the function in
$the_list (as it is a string variable) and run call_user_func() again, this time running a different function.
This allows you a little dynamism but is quite limited. A similar method is called a variable function, which
you’ll look at in the next section. Since PHP 7.0, you can also use the fromCallable static method of PHP’s
closure object to wrap a named function into something called a closure, which you’ll look at later.
The scope of named functions is also unintuitive. As you’ll see in the section “Scope” later in this chapter,
when you create a variable within a function, by default it isn’t available to code outside of that function. However,
when a named function is instantiated within another function, it is created in the global scope, such that it can
be called from anywhere, and thus it also needs to have a globally unique name. Consider the demonstration in
Listing 2-17 of nested functions, which return a string to illustrate their nesting (Listing 2-18 shows the output).
19
Chapter 2 ■ Functional Programming: Key Concepts
function a() {
function b() {
}
return "a";
function c() {
function d() {
function e() {
}
}
return "c";
var_dump( a() );
var_dump( b() );
var_dump( c() );
var_dump( d() );
var_dump( e() );
20
Chapter 2 ■ Functional Programming: Key Concepts
Note that you are defining the functions b(), d(), and e() within the scope of other functions, but when
you call them with var_dump, you are calling them from outside their “parent” functions. You can alter this
script to show another property of named functions; they are not created until the scope within which they
are defined is created. In Listing 2-19, you swap the order in which you call c() and d() in the var_dump()
section (with the output shown in Listing 2-20).
function a() {
function b() {
}
return "a";
function c() {
function d() {
function e() {
}
}
return "c";
var_dump( a() );
var_dump( b() );
var_dump( d() );
var_dump( c() );
var_dump( e() );
21
Chapter 2 ■ Functional Programming: Key Concepts
Because you haven’t yet called c(), d() doesn’t exist, and so you get a fatal error. b() could be accessed
fine, as you had already called a(), even though you were in the main program scope when you called it. As
a final demonstration of the problems of named functions, let’s look at the need for a globally unique name.
With a normal variable, you can use the same variable name for different variables, as long as they are in a
different scope (e.g., in different functions). With a named function, that won’t work, as you can see from
Listing 2-21 and Listing 2-22.
function f() {
function g() {
};
return "f()";
function h() {
function g() {
};
return "h()";
var_dump( f() );
var_dump( g() );
var_dump( h() );
22
Chapter 2 ■ Functional Programming: Key Concepts
As you can see, you’ve defined g() twice, once inside f() and once inside h(). Despite this, things run
smoothly at first when you call f() and g(), but as soon as you try to call h(), the second instance of g() tries
to declare itself, leading to a fatal error.
Using unique names for functions doesn’t seem like too much of a terrible restriction, until you
consider that if you start including external code libraries with include() or require() or via an autoloader,
those become part of the scope in which your function name must be unique, and it’s harder to ensure that
other people won’t tread on your functional toes! PHP does allow you to “namespace” functions, which
mitigates this issue somewhat; however, that can be considered a somewhat inelegant solution (depending
on who you talk to).
Variable Functions
PHP supports the concept of “variable” functions. This is a dynamic way of calling named functions with a
slightly more succinct syntax than the call_user_func() example you looked at in the previous section. In
essence, if you put parentheses (round brackets) at the end of a variable, PHP will call the named function
stored in the value of that variable (with any parameters you put in the parentheses). See Listing 2-23 and
Listing 2-24.
return $types[$index];
return $types[$index];
var_dump( $get_thing );
$get_thing = 'people';
var_dump( $get_thing(2) );
As you can see, the variable $get_thing is just a string holding the name of the function you want to
call, and you can change that name whenever you want. However, the actual functions operate just like
named functions (because that is what they are).
Language Constructs
strtoupper()—that’s a function, right? Yup. How about echo()? It’s got the parentheses like strtoupper(),
and it takes parameters, so it must be a function, right? Sorry, nope! Some PHP “functions” are not actually
functions at all but “language constructs,” built-in parts of the language syntax. You can usually spot these
because even though they accept parameters in parentheses, you don’t have to use parentheses. You
can also read the relevant page in the PHP Manual to discover which they are. Examples of function-like
constructs include echo(), print(), unset(), isset(), empty(), include(), and require(). The distinction
between language constructs and functions matters sometimes. Variable functions, described in the
previous section, will not work with language constructs. See Listing 2-25 and Listing 2-26.
24
Chapter 2 ■ Functional Programming: Key Concepts
$var_func = 'echo';
$var_func('hello world!');
However, if you do need to treat a construct like a function, then all you need to do is to wrap it up in
your own function, as shown in Listing 2-27 and Listing 2-28.
function my_echo($string) {
echo $string;
$var_func = 'my_echo';
$var_func('hello world!');
Return Values
As you saw in the “Named Functions” section, you can use a return statement to assign a value (or return
value) to your functions. There are several properties of return values that you need to understand to get a
good handle on functions.
If you don’t put a return statement in your function or if the execution path on a particular run doesn’t
hit a return statement, then your function will return NULL. See Listing 2-29 and Listing 2-30.
function reverse($string) {
$string = strrev($string);
}
25
Chapter 2 ■ Functional Programming: Key Concepts
function capitals($string) {
$string = strtoupper($string);
return $string;
}
# no return statement
var_dump( reverse('hello') );
# returns a value
var_dump( capitals('peaches') );
In the reverse() function, you forgot to return any value at all, so the reversed string didn’t make it
back outside the function. Captials() capitalized the peaches fine, but the bananas didn’t pass through a
code path with a return statement, so you just got a NULL back for your troubles.
In a similar manner, the return statement without a parameter also returns NULL, as shown in
Listing 2-31 and Listing 2-32.
function fruits($type) {
return 'Yummy!';
} else {
return;
}
26
Chapter 2 ■ Functional Programming: Key Concepts
var_dump( fruits('kiwi') );
var_dump( fruits('pomegranate') );
var_dump( fruits('mango') );
Calling fruits() on kiwi and pomegranate hits the second return statement without a parameter, so
NULL is returned for them. Mango, possibly the greatest fruit of all time, causes the fruits() function code
path to hit the first return statement, which has the Yummy! string as a parameter, so fruit() returns that
string in this case.
The other point to note about the return statement is that it can occur at any point in the function and
immediately terminates the function execution at that point. See Listing 2-33 and Listing 2-34.
function my_funct() {
$a = 23;
return $a;
$a = 45;
return $a;
var_dump( my_funct() );
As you can see, the function returns after the first return statement, and the code that sets $a equal to
45 (and the subsequent second return call) is never executed.
To sum up, you need to ensure you’ve done all the processing you need to do before you call return and
make sure all of your code paths hit a return statement before the function finishes.
Lambda/Anonymous Functions
You’ve looked at “traditional” named functions and seen some of their drawbacks. Luckily, from PHP 5.4
onward, you can use anonymous functions in PHP. These are also known as anonymous function literals
or lambda functions in other languages. They are called anonymous functions because, unlike named
27
Chapter 2 ■ Functional Programming: Key Concepts
functions, they don’t have a function name. Your first question is probably, “Well, how do you call them
then?” There are a number of different ways to do that, but it’s helpful first to take a look at how PHP
implements anonymous functions “under the hood.” See Listing 2-35 and Listing 2-36.
var_dump(
);
You can see that the function definition is the same as for a named function, but sans the name. Looking
at the var_dump output, you can see that the function is in fact an object (of class Closure, something you’ll
look at later in this chapter).
So, what does that mean? It means you can treat it like any other object in PHP. You can assign it to a
variable, and you can pass it around, destroy it, copy it, and more. But how do you actually call it to get it to
something useful? The straightforward way is to assign it to a variable and then use the methods you learned
about earlier (variable functions and call_user_func) to execute it. PHP can tell from the type of the
variable (a closure object rather than a string) that it is an anonymous function rather than a named function
and knows what to do with it. Let’s look at some examples. See Listing 2-37 and Listing 2-38.
var_dump( $double );
var_dump( call_user_func($double, 8) );
$two_times = $double;
28
Chapter 2 ■ Functional Programming: Key Concepts
$numbers = [1,2,3,4];
# redefine it
var_dump( $double(10) );
var_dump( $two_times(10) );
# destroy it
unset($double);
var_dump( $double(9) );
You don’t always need to assign anonymous functions to a variable to be useful. You can define them as
parameters to other functions, for instance. See Listing 2-39 and Listing 2-40.
$function($parameter);
};
function double($a) {
$function_caller('double', 4);
# It's not only our own functions that can accept inline definitions
# of anonymous functions ...
var_dump(
array_map( function($a) { return $a * 2; }, [1,2,3,4])
);
30
Chapter 2 ■ Functional Programming: Key Concepts
Higher-Order Functions
A higher-order function is a function that can take one or more functions as input and/or return one or more
functions as output, and I touched on them in at the end of the previous section. Higher-order functions
are functions that work on other functions. In functional programming, you’ll look at using higher-order
functions for program control (rather than imperative control statements like for and while).
I’ve covered the building blocks you need for higher-order functions in the previous sections of
this chapter, but if it hasn’t quite clicked with you yet, then consider that you’ve already discovered that
anonymous functions are in fact objects internally in PHP. You’re probably familiar with passing around
traditional objects in PHP, and you can do the same with function objects. They can be used as parameters to
a function and returned as the result of a function. Let’s look at an example; see Listing 2-41 and Listing 2-42.
31
Chapter 2 ■ Functional Programming: Key Concepts
});
};
print_r( $letter_filter($fruits,'a') );
print_r( $letter_filter($meats,'b') );
print_r( $letter_filter($cheeses,'c') );
print_r(
array_map( $letter_filter, [$fruits, $meats, $cheeses], ['a', 'b', 'c'])
);
32
Chapter 2 ■ Functional Programming: Key Concepts
The last array_map clause may give you some hints as to how you can replace loops and other
imperative program control structures using functions.
You may also have spotted that in the anonymous function you used as the last parameter to array_
filter, there was a use ($letter) clause. array_filter doesn’t provide any way for you to pass additional
variables to the filtering function, and $letter is out of the scope of the function when it is executed. use allows
you to bind data to your functions, so you can take advantage of variables that wouldn’t normally be available
to it. I’ll discuss scope in the next section and talk more about the use clause when you look at closures.
It’s not all about consuming functions as input, though; higher-order functions often return them as
output as well. Let’s take a look at an example of that. See Listing 2-43 and Listing 2-44.
function add($method) {
} else {
}
33
Chapter 2 ■ Functional Programming: Key Concepts
$conc = add('concatenate');
34
www.allitebooks.com
Exploring the Variety of Random
Documents with Different Content
something else. Thus the reflection of a person in a mirror is known
as his “image”; in popular usage one person is similarly described as
“the very image” of another; so in entomology the term is applied in
its Latin form imago to an insect which, having passed through its
larval stages, has achieved its full typical development. The term is
in fact susceptible of two opposite connotations; on the one hand, it
implies that the thing to which it is applied is only a copy; on the
other that as a copy it is faithful and accurate.
Here then in the most marked manner the aniconic sacrament has
ousted pictures and statues. It is the embodiment and home of
divine personality and power, and not they. Equally contradictory of
any such law of development is the circumstance that the Greeks of
the 5th and 4th centuries b.c., although Pheidias and other artists
were embodying their gods and goddesses in the most perfect of
images, nevertheless continued to cherish the rude aniconic stocks
and stones of their ancestors. If any such law ever operated in
human religious development, how can we explain the following
facts. In the shadowy age which preceded the Stone age and hardly
ended later than 10,000 b.c., the cave-dwellers of the Dordogne
could draw elks, bisons, elephants and other animals at rest or in
movement, with a freshness and realism which to-day only a
Landseer can rival. And yet in the European Stone age which
followed, the age in which the great menhirs and cromlechs were
erected, in which the domestication of animals began and the first
corn was sown, we find in the strata no image of man or beast, big
or little.
ebookbell.com