Functional Programming in PHP7. Higher Order Functions

I’ve decided to bring my notes out of Evernote and present them on a blog. I’ve been keeping programming notes for a while but it is only recently that I’ve decided to share them. Call it lack of confidence or whatever but I’m now ready for the Internet to review my work.

This post is based on some notes I made on functional programming with PHP7. It is a beginners level ‘functional’ post, but you’ll need to be quite advanced with more proceedural PHP to start. That’s where I was when I made these notes so I figure that best suits any readers.

The aim: is to look at two principles and see them working in some code. These two principles are

  • Static types
  • Higher order functions

Traditional PHP is normally more of a dynamically typed language meaning types are not required until runtime. This is still the case in PHP7 but we can make PHP more statically typed by enforcing static typing with

1
declare(strict_types=1);

By enforcing strict types any deviation from this now results in fatal php errors (1). Here is an excellent and thorough look at types in programming.

First of all we’ll make a function called toAll which is statically typed in the following way

1
2
3
4
// toAll :: (string -> ()), array -> ()
function toAll(callable $action, array $array): void {
}

Because functions in PHP7 are first class objects they can take and return functions themselves. Statically typing means telling PHP what we are passing in and what we are expecting out. Here you can see that we are passing in a callable object and an array. As we will not be returning anything from the function we use VOID because we are not using the return statement.

This is the complete function. For every item in the array we call callable, passing in the array item as an argument.

1
2
3
4
5
6
// toAll :: (string -> ()), array -> ()
function toAll(callable $action, array $array): void {
foreach($array as $elem) {
$action($elem);
}
}

The next function is a true higher order function because it returns another function. The important thing to notice is the use keyword which points at the file pointer which in turn points at the fwrite function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// writeToFile :: string, string -> (string -> ())
function writeToFile(string $path, string $mode = 'w'): callable {
if(is_dir($path)) {
throw new \Exception('File must not be a directory!');
}
$_fp = fopen($path, $mode);
if(!($_fp && is_resource($_fp))) {
throw new \Exception('Error opening file!');
}
return function ($contents) use ($_fp) {
fwrite($_fp, "$contents\n");
};
}

Setting things up like this allows us to use this in the following way.

1
2
3
4
5
6
7
8
9
10
11
12
13
$writer = writeToFile('file_to_write_to.txt');
$writer('<p>First Paragraph</p>');
$writer('<p>Second Paragraph<p>');
// change the mode to append
$appender = writeToFile('file_to_write_to.txt', 'a');
// use the toAll function we made to apply to each element of the array
toAll($appender, ['Functional', 'PHP', 'Rocks!']);
// apply the string to upper to each element of the array, then apply to the appender
toAll($appender, array_map('strtoupper', ['Functional', 'PHP', 'Rocks!']) );

We end up with a text file with the following in it

1
2
3
4
5
6
7
8
<p>First Paragraph</p>
<p>Second Paragraph</p>
Functional
PHP
Rocks!
FUNCTIONAL
PHP
ROCKS!

It is possible to see how this style of programming opens many possibilities over the more procedural or OO style often associated with older versions of PHP.