In 2001 I got my start in programming. It was a very basic start: my (to-be) stepdad was teaching me about a “chat response bot” he was working on, and showing me things. I don’t recall the language he was using anymore, but later, in 2002, I started learning HTML.
In the middle of 2002, while doing my HTML experimentation, I began learning about server-side scripting. In particular, I started learning PHP. It was either 4.1 or 4.2 at the time, it would depend on what part of the year I was working in, but I remember that I began learning about echo
, and a few other basic PHP features.
Now, since then, nearly 18 years have passed. Anyone born when I started learning PHP would be reaching adulthood now. More than half of my life has passed, and now I feel bittersweet as I come full-circle back into some primarily PHP development.
PHP was once the de-facto standard
Back in the early 2000’s, PHP was really becoming the de-facto standard for server-side web development. The ease with which one could pick it up, combined with the growing community of folks who continued to support each other made it a prime choice for major projects. Now-a-days PHP is seen as a black-sheep, but it shouldn’t be.
When PHP 5 came out I had really started getting into web development. This would have been the middle of 2004. Windows XP was out and was regarded as a truly remarkable operating system. Within the next 2 years PHP received some significant love, and 5.1 and 5.2 came out. But then, something happened. Development on PHP seemed to slow, and the next version wasn’t released until 2009. That left a nearly three-year gap from 2006 to 2009 where PHP was stable at 5.2.
After 5.3, it happened again. Nearly 3 years from 2009 to early 2012 before a new PHP version, 5.4, came out. I have a feeling this is when PHP started to see a downturn of popularity. At this point I was moving on to .NET development. WHen .NET 4.0 was released in 2010, I jumped on that bandwagon and have been doing .NET development for the nearly 10 years since.
But PHP truly is a good choice again
During the PHP 5 era, when PHP saw 6 years with only 2 releases in that period, it felt like it had gone by the wayside. Folks were jumping off PHP and into other avenues. A friend of mine even wrote a C-based CGI interface for his website. Yes, his entire site is written in C…I don’t know why, but it was done.
But there’s an interesting thing that happened, once PHP 5 development ramped back up, with much more widespread use of the internet, development truly ramped up. PHP started receiving features that other languages like C#, Visual Basic, Ruby, Perl, Python and others have. In fact, with version 7, PHP really is a very good choice for certain web applications.
The biggest issue with PHP used to be the dynamic capabilities of it, and you had to catch it all at run-time.
I remember in my PHP 4 and 5 years that, if you didn’t know the nuances of the language, PHP seemed daunting to work with. There wasn’t a lot of compiler support, and really you had to run your PHP code to find even trivial errors. Back then, I didn’t have any money so I couldn’t buy any of the high-end IDE’s, so I used Crimson Editor to do it all. Sure, it could point out a few very basic issues, but you really only found them when you ran your code.
Of course, to add to this, PHP didn’t have a naming standard for a long time. (I can’t remember if it still does or not.) It grew organically, which means that new development was based on the need, not on the wants. This is part of why we have different naming conventions in the language: substr
, str_replace
, and so-on. Referencing information in PHP.net became critical.
But all of that has changed.
If you look at PHP 7.4, it’s almost unrecognizable if you come from 4 or 5. The new capabilities are astounding, and due to some of the rewrites and the AST-based compilation now, a much larger collection of IDE’s and linters is available. Add to that the ability to give type-hints, visibility modifiers, Unicode support, and the language is phenomenal. I actually started using it for a few new projects, and I have to say: PHP 7 is what PHP was meant to be.
I want to talk, in the rest of this post, about some of these new features in PHP 7, and why I think they should encourage you to reconsider PHP as a choice for web-based development, if you haven’t already. Half-baked, incomplete history lesson aside, I feel that it’s important that we bring light to some of them, because they really do change how PHP works.
We’re going to start at PHP 7, and work through 7.4.
The important points of PHP 7
Let’s ignore, for a moment, the immense performance improvements that came with PHP 7, because there were a lot. PHP had been seen as slow (because of the interpreted aspect of it), but with PHP 7 a lot of that has changed, and I don’t want to get into the performance aspects.
Return Types
If you’ve ever done C, C++, C#, or Java development, you’re likely familiar with the concept of a “return type”: the specific data-type that will be returned by the function.
Historically, PHP had allowed any function to return anything. The old function syntax was pretty simple:
function sd($values) {
if (!is_array($values)) {
return null;
}
if (count($values) < 2) {
return null;
}
$sum = 0.0;
$count = 0;
foreach ($values as $value) {
$sum += $value;
$count++;
}
$avg = $sum / $count;
$sumSquares = 0.0;
foreach ($values as $value) {
$sumSquares += pow($value - $avg, 2);
}
return $sumSquares / ($count - 1);
}
We’re going to use this function for most of our discussion.
Now, if you were looking at this function elsewhere, a smart compiler would only be able to tell you that the function looks like: sd($values)
. We have no idea what $values
is supposed to be, and we have no idea what we get back.
With PHP 7, we can start telling people what we’ll get back: function sd($values) : float
will do it. The new : float
at the end says “this function will give you back a floating-point value.” (Decimal number.)
But, with our function, if we add that particular “annotation”, we will get an error at the two tests at the beginning: null
is not a float
.
Exceptions
Introduce the next major PHP 7 feature: exceptions. With exceptions, we can start telling callers we had an error in a way that they can properly digest. This is extremely important, and while exceptions had existed in PHP before, PHP 7 began embracing them in the core libraries, which made them much more friendly.
if (!is_array($values)) {
throw new Exception('Values must be an array!');
}
if (count($values) < 2) {
throw new Exception('Values must have two or more elements!');
}
Again, if you have done much .NET or Java development, this will look rather familiar.
But if you haven’t, let’s talk about exceptions briefly.
What is an exception?
Exceptions deserve their own blog post, in fact even their own book, but I’ll give a brief overview here.
Most programs, at least the ones we’ll be dealing with, flow top-down, or beginning-to-end. That is, statements happen in the order they are written, from the top of the file to the bottom:
$a = 1; // $a === 1
$a = $a + 5; // $a === 6
$a = $a / 2; // $a === 3
$a = $a * 4; // $a === 12
If we want to skip a set of statements, we can use an if
, or some other form of “flow-control”.
$a = 1; // $a === 1
$a = $a + 5; // $a === 6
if ($a < 10) { // $a < 10 === TRUE
$a = $a * 2; // $a === 12
}
$a = $a / 4; // $a === 3
With the if
here, the statement $a = $a * 2
only happens when the condition, $a < 10
, evaluates to TRUE
.
In our function, return
is a form of flow-control: we can stop the function there so that nothing else happens.
But, exceptions are another form of “flow-control.” When we throw
(as it’s called) an exception, we stop the function at that point, and it sends the program into an “error state” that says “I can’t continue working because something is broken.” In our case, both of our exceptions indicate that the array is not correct for our function. That means our function will stop executing, and it will send that error to whomever called it.
Back to Exceptions in PHP 7
As a result of how exceptions work, throw new Exception
will stop execution of our function, but instead of returning null
for both errors (which was one of the previous common practices), it will give the caller the information they need to fix the error.
try {
echo sd(5);
} catch (Exception $a) {
echo 'There was an exception: ', $e->getMessage();
}
Because we use exceptions now, in this case the program will print “There was an exception: Values must be an array!”
So now, our function looks a little different:
function sd($values) : float {
if (!is_array($values)) {
throw new Exception('Values must be an array!');
}
if (count($values) < 2) {
throw new Exception('Values must have two or more elements!');
}
$sum = 0.0;
$count = 0;
foreach ($values as $value) {
$sum += $value;
$count++;
}
$avg = $sum / $count;
$sumSquares = 0.0;
foreach ($values as $value) {
$sumSquares += pow($value - $avg, 2);
}
return $sumSquares / ($count - 1);
}
In addition, elsewhere in the system we now know that sd($values) : float
, which means we know what it returns when we use it.
The important points of PHP 7.1
With PHP 7.1 we got a new return type: void
. This doesn’t affect our example function, but it does allow us to do something like the following:
function print_data_to_screen($data) : void {
echo $data;
}
When we see this elsewhere in the IDE, we know that void
means that the function doesn’t actually return anything: it does some work, then it is done. This is important because we may end up calling to functions that do things, but don’t give us data back. As a result, we don’t want to try to assign or reference a value, because they don’t have one!