PHP needs its own ES6
( Originally posted in https://dev.to/hamatti/php-needs-its-own-es6-28fa. )
I have a love-hate relationship with PHP. I have written PHP in many forms from website templating and Wordpress to full MVC and SPA backend solutions in the past 15+ years.
I was reading through Bronson Dunbar's post "Using and learning ReactJS for 2 years, what have I learnt, and I stopped at this:
For the past few years (after getting over the Python 2->3 pain), I've been thinking and speaking about how I want PHP to break backwards compatibility. I know it's not gonna happen because such a big part of Internet runs on PHP and it would break everything.
So Bronson's post gave me something to think about: maybe we don't need a "new PHP", maybe we need ES6-for-PHP — a layer on top of PHP that would allow us to tackle the issues and write different PHP while still being compatible under the hood.
I'm no language designer nor someone who finds joy (nor has skills) in building new programming languages. But I'm a dreamer and I can dream.
One of the big annoyances in PHP is the inconsistent standard library. Which is actually a feature, not a bug. When Rasmus Lerdorf was creating the language, he used different kind of naming schemes to balance the function hashing.
Well, there were other factors in play there. htmlspecialchars was a very early function. Back when PHP had less than 100 functions and the function hashing mechanism was strlen(). In order to get a nice hash distribution of function names across the various function name lengths names were picked specifically to make them fit into a specific length bucket. This was circa late 1994 when PHP was a tool just for my own personal use and I wasn't too worried about not being able to remember the few function names.
But it's 2019 and a lot of PHP is still being written. What if we could make it more enjoyable? (I love writing Ruby and Ruby on Rails and DHH's The Rails Doctrine is an inspiration to me. Especially the part about developer happiness.)
So what should we work on?
Consistency-layer on standard library naming
As you can see from the quote above, PHP's functions were named for specific purpose: to balance the hashing function. It means that as the standard library has grown, it's impossible to remember how to write function names because there's no consistency.
bin2hex. And there's
recode_string. You can probably see the point.
So first plan of action: creating a consistent and predictable naming scheme
Turning array functions into methods of arrays
Let's take a look. Let's say we have an array of values that we want to first filter and then map. In vanilla PHP, we would do this:
return number * 2;
return number % 2 == 0;
array_map has parameters as
callback, array and
array_filter has parameters
array, callback. I have no clue why they are the exact opposite of each other but more often than not, I don't remember which is which and I have to resort back to docs. Also it's difficult to follow because of heavy nesting.
Let's see how we could make it nicer.
->filter(num -> num % 2 == 0)
->map(num -> num * 2)
Making array functions into methods of array itself, we could chain things. Even if we don't want to adopt ES6-style arrow functions for anonymous functions, it would make this code much easier to follow and ready.
Second plan of action: make
array_ functions into methods of arrays and make then chainable
One sort to rule them all
How about sorting then? Currently PHP's sort is a huge mess. Back in 2015, I wrote a blog post about my pain with them. Quoting myself:
There’s of course sort. Instead of giving a flag or parameter to
sortto reverse the order, you have
rsort. Then if you want to keep the key=>value pairs intact, there’s
asort(which has caused me most confusions ever since I accidentally used that one instead of sort) and
arsort. Then you can sort with keys
krsort. For natural sorting there’s
natsortand case insensitive
natcasesort. And when all this is not enough, you can use custom defined comparing function with
uksort. And the inconsistently named
array_multisortfor multidimensional arrays.
What if instead, we would have just
sort() function and that would work with either flags, keys or custom callbacks. And please have an option for sort that returns array, not just sort as a side-effect. One of the first custom functions I create in most PHP projects is a
sorted function (name borrowed from Python) that enables me to be more functional.
Third plan of action: unify sorts
Separating sequential array and associative array
Did you know that PHP only has associative arrays? It works quite okay while you're in PHP land but when you start converting it to JSON, you start to see issues. Another one of my blog posts from last year highlights this issue.
If you sort an array with numeric, sequential and unordered keys, you turn from object to an array. If you sort an array with numeric, sequential and ordered keys, it remains an array. Whatever you do for non-numeric or non-sequential array, it will stay an object.
When I'm reading through code or writing it, I should be able to figure out more consistently what the outcome will be. Using
array_values to reset a "once a sequential array that got turned into associative array" is horrible.
Fourth plan of action: separate array types
There are probably other parts of the standard library that could benefit from a "ES6 Treatment" but the biggest pain points of my life regarding developing with PHP are these.
- Consistent naming
- Array functions into chain-able methods of array
- One sort, no more
- Two arrays are better than one
Which parts of PHP would you like to see enhanced with ES6-for-PHP type of solution?