The author recommends building some kind of abstract structure factory which has perhaps five external dependencies per codeblock, a composer file, vague notions like dependency injection, auto-wiring, containers, routing, middleware, request factories, response interfaces, a class hierarchy and an obtuse non-production webserver in mental overhead ... lauding the design because he says it complies with a bunch of numbered standards that allow you to swap out your layers-of-assumption components.
This is blatant false economy. Nobody ever swaps out components. Nobody in fire-and-forget webdev land cares about standards. Just get the thing out the door, keep it simple, and thus keep it maintainable.
As others have commented, explicit code is clearer. Clearer code has less bugs.
Why not save the hassle and just use:
<html><head></head><body>Hello, <?php print anti_xss_function_of_choice($_GET['worldtype']); ?> world!</body></html>
This is the 'new PHP' from ~1995, seamlessly using decades of high efficiency improvements to kernel caches, networking gear, the interpreter itself and webservers. Zero complexity, not a class in sight, and definitely no middleware. It's a great language, when not misused.
But 18 years have passed. Every language now has very good package managers. There is an abundance of dynamic languages, most of whom are more consistent than PHP.
I'm not going to waste your time with a long PHP rant. I just hope that everyone is aware that the huge benefits that PHP offered in 2000 are no longer valid. If you are programming in PHP, you owe it to yourself to explore some of the many options that are out there. There has been incredible innovation among software languages since 2000, but PHP has mostly tended to follow a conservative path, mostly imitating Java.
For anyone who won't be bored by another PHP rant, I wrote my thoughts on this subject back in 2014:
All you do is insult the language, and subsequently, the intelligence of those who continue to use it. Many of us have looked at - and heavily used - other languages, and choose to come back to PHP for many (not necessarily all) projects. Your assumption that we're all morons who program in PHP because we're too stupid to try other options is misplaced. You looked elsewhere and preferred what you found. Good for you. Some of us who looked elsewhere found that every language has its faults, and that PHP does the job just fine. Particularly since the performance improvements in later PHP 5.x versions, and finally the leaps and bounds gained in PHP 7, the language is more than good enough for most tasks.
I've done projects in C, NodeJs, Ruby, and yes, even Python. Python fanboys in particular seem to think their use of the language is an indicator of superior intellect or programming ability. The whole "I am smarter/better than PHP developers" gag is really, really, old.
https://www.techempower.com/benchmarks/
But even if both of your points were true, the point is to look at what is happening in other languages and frameworks. Every day you spend learning about PHP is a day that you are not learning about the languages that are really moving the industry forward to interesting new places. Ask yourself, honestly, how many interesting new ideas will you learn from studying PHP, versus the more versatile (as in more platforms, and also the frontend) languages such as Javascript/Node, or the more innovative such as Go or Rust or Clojure or R or Julia? And I'm not even mentioning the more experimental languages, such as Shen or Lux.
I continue to be baffled by this sort of "novelty-chasing" --- do I really care about "interesting new places" or "interesting new ideas"? No; and in fact I'd rather not, because it takes time and energy away from actually solving useful practical problems, besides the ones you create yourself in chasing after the latest cruft.
PHP is slow on an absolute scale, but chances are that a minimal, straightforward application written with it can perform better than something with a bloated framework on top in a different language. That takes true skill and experience, not something you can get if you're continuously jumping around trying to chase the fashion trends.
As someone who has witnessed several major trends in programming come and fall, the amount of churn (and encouragement thereof) in the web community is astoundingly unsettling.
"It's not about the tool, it's how you use it."
The ecosystem is also smaller and deployment in Elixir is still a work in progress (mismatch between Mix and Erlang releases).
About this:
"because it takes time and energy away from actually solving useful practical problems,"
You can not know that without first studying other languages. You might find that you are 10x more productive in Rust. You can only find out by studying Rust.
But you bound the conversation in ways that I didn't when you write:
"in the web community"
I feel that developers can learn a great deal if they study projects that don't necessarily have anything to do with Web programming. Nothing in the article or on this page necessarily restricts us to only considering Web programming.
"It's not about the tool, it's how you use it."
I wouldn't use a hammer to go fishing. Nor would I use a saw to turn a screw. Nor would I use a frying pan to tune a piano. It helps to learn about a lot of different kinds of tools, because over the course of your career, you might be confronted with diverse tasks.
Is this a troll? No you don't need to care. Feel free to go live off roots and tubers in the forest. Or write some COBOL. Anything is justified if you're putting "interesting new ideas" in quotes.
I worked with PHP full-time for several years and energetically rationalized away the time I invested into building that expertise. I liked it, I was getting things done, it would help me get jobs in the future. Utter nonsense. What a waste of my life.
Eventually I snapped out of it. Turns out you can just move to places Silicon Valley, there are jobs at awesome companies working with the cool modern technologies. You don't need anybody's permission, just do it. Want to write Haskell/Go/Rust/Elixir/Clojure every day? Want to work with ML or robots or big data or whatever floats your boat? Just go do it. You don't need to sit there writing PHP as the world passes you by.
PHP is a backwater. People live there and tell themselves that it's fine, good as any place really, can't imagine anything better, probably wouldn't like it anyway. Or they just stop thinking about it.
Remember java was cool or mongodb or node or ruby on rails. It feels like go is becoming less cool. I wonder what next year will bring? Perhaps php will be rediscovered when SV changes once again.
Taylor Otwell says the same thing about laravel/php.
Mark Zuckerberg says the same thing about React / HHVM / Hack (PHP variant).
I'm sure Steve Jobs said the same thing about Objective C or Swift.
It's called an opinion, just because one person who spends more time investing in VCs, and just because we're debating an issue on a site, doesn't mean we have to take the creator of the site's past essays as the absolute truth...
Go, php, ruby, python, lisp variants ALL are the best script if A. it's the only one you know and you just want to launch something or B. You've done your due dilligence to figure out what you need, is it just a crud app? PHP is fine, is it a chat app? Well you might need erlang or elixir on the backend, or something with concurrency.
If you're spending 100+ hours debating on platform instead of building shit, then that's time you can't get back and that's wasted opportunity acquiring customers to a platform you could've had built last week -- if you weren't stuck in...confusion about what framework to build in, or spending all your time in tutorials because you picked the shiniest framework or language that is above your pay-grade so you have to learn everything.
This is on point! Programming PHP is not about diving deep into interesting language constructs or creating beautifully structured software - PHP is about getting things done, about starting hurdle-free and progressing rapidly. It goes against some "good development practices" but it works, see for example the single-file website remoteok.io from Pieter Levels: https://twitter.com/levelsio/status/938707166508154880
That's "chasing shiny". Shiny is the cancer destroying the computer industry from the inside.
Any day not learning how to do web application development in LISP is a day wasted. The old tech is still cutting edge, way ahead of any new shiny garbage, because that garbage is decidedly not moving the industry forward, just introducing one more variation of making a computer do something. And that's extremely bad.
Which of those languages give you NaCl out of the box?
> There has been incredible innovation among software languages since 2000, but PHP has mostly tended to follow a conservative path, mostly imitating Java.
PHP fans like to point out (tongue slightly in cheek) that PHP is the first major language to add modern cryptography to its standard library (libsodium in php 7.2). We can argue about how important that is, but it's also not wrong. And it certainly didn't copy that from Java. :) Further, I think some of your criticisms in the link have also not aged well.
Not sure if composer is "very good," but it's generally worked out better for me than gem.
(Also, package managers are not an unqualified benefit. I like them for installing things I'm not developing, but as far as I can tell they essentially defer a legibility cost for developers. Sometimes worth it. Not always.)
> There is an abundance of dynamic languages, most of whom are more consistent than PHP.
I think it was Ralph Waldo Emerson who had some choice words about consistency. And this criticism has always rung a little hollow to me. I'd agree that some of PHP's dynamic multi-paradigm scripty siblings feel cleaner, but having written code in many of them, it's never felt like a major difference in productivity to sometimes have to pause and consider argument order or precise names. The lookup cost has always seem cheap on on par.
> I just hope that everyone is aware that the huge benefits that PHP offered in 2000 are no longer valid.
There's definitely a closing in the benefits gap since 2000. PHP is far from my favorite language. PHP is not right for many projects. There are still some benefits that PHP prioritizes that I think arguably aren't done better elsewhere
* Trivial deployment story. Your app is one or more files. Drop it in a directory on a wide variety of hosting environments. You're done! (Buuut, if you want something more involved, lots of choices available there too.
* The language is the template language (though there's other options). Some people consider this an anti-feature because it allows amateurs to build ill-organized applications around a dynamic-document-as-program paradigm. I think that's still a brilliant gateway that makes the marginal cost of moving from a static document to a dynamic one small while still allowing an easy transition to front controllers. And it means the templating performs at parity with the language itself and can do as much as the language can do.
Pair it with a simple routing library and model layer and it's as easy to build something reasonable quickly as it is with comparable Python & Ruby frameworks, often with fewer moving parts and similar magnitude of performance.
So sometimes when I have smallish web-facing projects (or projects I think I might want to distribute for others to run on the web), I still often find myself reaching for it, even with plenty of other options at hand, even with languages I like better.
Generally speaking, while I don't think this is satire, I would hate to see someone code this way, unless the point was simply to learn how the components of a web framework work together. This is not "framework-less PHP", it's just a DIY framework, and not a particularly good one. I think that attempting to create a web application without a framework is at best needlessly duplicative of effort, and at worst an open invitation to security flaws and spaghetti code.
The author says, "This is not an anti-framework screed," and it's certainly not polemical. However, I think it's probably more representative of the Zend-ecosystem way of doing things rather than PHP best practices: accretion, as opposed to design.
Seems we finally broke the fever of infectious imperative spaghetti and are coming around to OOP and patterns by following the trail left by JVM ecosystem and eating its droppings and clothing ourselves in its shed skin.
You are on the mark for Java like OOP becoming popular in PHP. I think there are more people trying to do enterprise level work with PHP and they are taking lessons from existing software engineering practicies.
One example is Magento, and arguably it was the right choice at the time and has given it enduring popularity (if not endearment) for nearly a decade.
As more software engineers took web applications seriously they brought best practices and tech stacks with them, and you can see the PHP community really strive to level up.
But if I were to make a bold statement, it is web development in general that struggles producing solid reusable work. You see it in all languages. The only ecosystem I can think of that isn't disparate islands of unique wheel factories is Ruby, and that seems to be because people learn "rails" not ruby.
You can do it, but it's most likely a bad idea to mess around with it considering namespaces and such.
Disclaimer: I've not written much php nor read the article. Just replying to this one comment because the OOP analogy spoke to me.
There's a number of issues inherent in manual include statements:
- When you include a file, unless you include it using the absolute path, the path will be resolved using the include_path ini setting, which works just like the $PATH environment variable works to resolve the location of binaries. Typically, `include_path` will be set to something like `/usr/share/php:.:/some/other/dir". If I encounter `require_once 'Foo/Bar.php';` in some code, what file will that include? `/usr/share/php/Foo/Bar.php`, but maybe also `./Foo/Bar.php`.
- Relative includes are relative to the current working directory, so a different file may be including (or not found at all) depending on what directory I'm executing my script from. To avoid this, it's good practice to include files using `include __DIR__ . '/Foo.php';` to ensure we know exactly what file is included.
- Prior to autoloading, most dependencies were installed in a global location, e.g. `/usr/share/php`, which would then be part of include_path. Different projects on the same machine therefore had to have the exact same dependencies. Autoloading enables per-project dependencies.
- Using manual includes makes it much easier to have a poorly structured project. With autoloading, if I see `$bar = new Foo\Bar();`, then I know exactly what I'm getting: the class Bar, defined in the file `src/Foo/Bar.php;`. On the other hand, if I see `include 'bar.php';`, I have no idea what I'm getting. What's in the file? Could be class, could be bunch of random functions, could be mish mash of HTML and PHP spaghetti.
Same of these issues are manageable even without autoloading by following best practices, but unfortunately there's a lot of really bad code out there that doesn't. Autoloading (along with composer) completely solves a problem that used to exist in PHP. Anyone that actually uses PHP can attest to this. If you've ever worked on a project with a web of manual includes, it's a total nightmare compared to a properly structured project using autoloading.
Autoloading aside, the point of this article, IMO, is that it's quite easy to set up a well structured, maintainable, easy to understand project architecture without using a major framework. The central abstraction here is that all requests go to a front-controller, which then calls a function that accepts a representation of the HTTP request and returns a representation of the response. Having abstractions for Request and Response is much more manageable (and testable!) than having random print statements everywhere and using global variables like $_POST. This is same idea behind just about all web programming "frameworks" in any language. Of course this would all be over kill if all you needed was a "Hello World" page. But this isn't about hello world pages, it's about real projects that grow over time and need manageable structure.
Furthermore, this article advocates for dependency injection. Again, overkill on a hello world page, but in a real project explicit dependencies makes life so much easier.
[1] This is the de-facto standard. Sure you could technically write an autoloader that does weird things, but nobody--human or automated tools--does this in real code. It's not a problem in practice--autoloading in the real world makes things much more explicit than manual includes.
I'd also like to encourage everyone to strace a php run sometime and then tell me how great autoload is..
stat(path1/Class.php)\ Not found
stat(path2/Class.php)\ Not found
stat(path3/Class.php)\ Not found
stat(path4/Class.php)\ Not found
stat(path5/Class.php)\ found!
open(path5/Class.php)
read(path5/Class.php)If I were to write a website in PHP, I'd use functional programming and certainly no framework. And I'm still scarred from the Autoloader in Perl. Never again!
When you first started with PHP, you may have used includes or requires statements throughout your app to bring in functionality or configuration from other PHP files. In general, we want to avoid that because it makes it much harder for a human to follow the code path and understand where dependencies lie.
Autoloading just means that when your application needs to use a class, PHP knows where to look for it and automatically loads it when it's called for.
How in $deity's name can you say that specifying immediately the exact path to the file included, in the file that includes it, is "much harder to follow" than hiding it behind the indirection of the autoloader and whatever it does!? Honestly, WTF!?
(Maybe the joke here is that everyone is just pretending to admire the emperor's new clothes, in which case I apologise.)
Edit: here's an example of the OOP articles I mentioned: https://csis.pace.edu/~bergin/patterns/ppoop.html