This part is laughable. People who have been programming PHP for 20 years (several of them at my company) still routinely discover hidden bugs, quirks or general behavior that is totally unintuitive and nowhere found in the documentation.
A classic boiled frog statement.
__It's not undocumented, someone posted a comment about that bug...__
I will quietly place my face in my hands and weep to the memory of php coding I did 20 years ago.
Seems the same nonsensical masochism is still going strong.
Need to do something new in Node? Sift through a bunch of search engine spam, read a few dissenting answers on stackoverflow that refer to a previous version, eventually find a library that does what you want, written by skullM4ster2004, plug one's nose and install it.
You should revisit the language. PHP7 was a huge leap forward. It's a different language now.
I remember no discernible border between 'official docs stop here' and 'user contributed opinions start here'.
I do agree with the sentiment though that these unofficial notes should be taken with a grain of salt. In my experience, they have been more help than hindrance.
i suppose it's fitting for a web-centric language to crowd source its docs on a website, but does any other mainstream language do this?
Much more frequently I’m looking up something related to the tools and libraries I’m using.
The only surprising thing I’ve learned about PHP at the language level in the last 6-10 months is that you can call array_filter() without a callback to cull nulls.
It's mostly things like parameter order for certain built-ins that aren't intuitive and/or finding built-ins I've never used or heard of because there are so many obscure ones (there are nearly six thousand) that keep me coming back. For example, how do you disable errors in a DOMDocument? It ought to be as easy as DOMDocument->setAttribute("errors", "false"), but no it's a separate function call to libxml_use_internal_errors(true). There are like five other similar function calls for this too. PHP has abstraction leaks and little inconsistencies like this everywhere.
Granted, languages with small standard libraries, like JavaScript, by contrast get an easy cop out to blame the community of various package maintainers here. But at least in that case someone can always just write a better library.
All the above said, do enough real work in any language and you'll find cases where the idioms of the language don't map to your work.
Of course I’m speaking succintly above. It’s not that bad, but it’s not that much better either. I’m not going to stockholm myself into using a language just because it’s “mature” if I don’t have to. I may have that relationship with JavaScript but at least in that case resistance is somewhat futile and there are practical benefits to be had.
(a) you're a true, deep expert who uses the language all day every day
(b) the docs are so poor it's not even worth having them open
I’m also willing to grant implicitly that there are tradeoffs here. Languages with small standard libraries usually have big community libraries and vice/versa.
I've only used Go sparingly - I heavily relied on docs, but yeah it may have a shallow learning curve. It's certainly much saner than Python (which seems to be the other language used in my "space" for e.g. ad hoc ops tooling, etc.)
Labeling these things as "gotchas" doesn't make them predictable imo.
If predictability means to predict, that standard library will behave nonsensically, then yes, PHP has the one high predictability.
Oh, so you _haven't_ used any of the recent versions of PHP, then. You're just talking shit with no actual recent experience. Gotcha. Well, thanks for your input.
docker run -it php:8.0 bash
# php -a
Interactive shell
substr("abcdef", 3);
// no result
-- Ah right, PHP does things differently than other almost every other language that has a REPL and I have to echo a value, which was just returned, even on the REPL ... php > echo substr("", 3);
-- Silently hiding the error. Idiocy. php > echo substr(null, 3);
-- Silently hiding the error. Idiocy. php > echo substr("abcdef", 3);
def
Who is shit talking now? Are you suggesting, that all this is normal and OK? Nothing is fixed. It's still badly designed and probably will remain shitty like that, until PHP programmers finally realize, that this needs to be properly fixed.EDIT: Of course the docs also do not mention this to happen at all and tell you, that the first argument must be a string. So I guess that means, that in PHP terms, null is a string. Great for type safety!
https://wiki.php.net/rfc/engine_warnings
https://wiki.php.net/rfc/deprecate_null_to_scalar_internal_a...
Which is more important really? I genuinely don't know the answer to this.
If you never upgrade, sure. PHP 7 and each minor version in it have deprecated and removed plenty of stuff that was legal in 5.6. PHP 8 is on track to do more of the same. I think the backwards incompatible changes are pretty much all good for the language, but claiming backwards compatibility in PHP is completely wrong.
If you aren't on PHP 8, you aren't supported, and if you're on anything earlier than 7.4, you aren't getting security releases. And the new versions released yearly all have breaking changes, and get three years of security support. It's not 2015 anymore.
PHP is documentation done right because of the comments, essentially "Stack Overflow" for PHP before stackoverflow.com was a thing.
I've found an example of documentation done wrong recently with Microsoft .NET 6.0. Apparently, Microsoft has decided that code samples are no longer important
It's funny really, for a programming language to rely on comments made by random people, instead of having those aspects covered in the documentation itself. Shows a bit of lack of care. It seems half-assed as many things in the ecosystem seem. What happens, if they ever lose that database of comments? The whole world scratches their heads wondering how to use standard library functions? Ridiculous. I hope they have good backups.
> I've found an example of documentation done wrong recently with Microsoft .NET 6.0. Apparently, Microsoft has decided that code samples are no longer important
And for as long as important documentation resides in comments in PHP docs, the same can happen to PHP docs. Lets say they push out PHP 9 and some things change. Someone thinks "Ah those comments are not actually true any longer. Lets get rid of them." Bam, massive resource lost, because the knowledge has not been integrated into the documentation.
Assuming they backup the website, how's it going to get lost?
I've always been a fan of PHP too; it was my first programming language that I used to build a shipping application, but saying there are 'no unknown unknowns' in a language as quirky and old as PHP is akin to denying the sky is blue.
PHP 4 + 5 had so many weird quirks, and they lasted a long time because PHP 7 took so long to ship (note there was no PHP 6). When 7 hit, they followed it up with many minor releases to try deprecating/removing/correcting some of those quirks, which itself introduced more unknowns when refactoring legacy code. Suddenly the quirks you were used to for so long were now gone or behaving differently (or more sensibly at least), but this required even more refactoring to account for.
When a language is always changing or evolving you can never know in advance with certainty how new features or changes will change how existing code will work.
I noticed being stateless made it difficult to scale for any complex app. It’s been 7-10 years since I used it but Drupal used 60-128MB+ plus per request. As it was stateless it had to do a full bootstrap for every request coming in, set up a new database connection, module discovery etc, all which was heavy to do for every request. Most people scaled Drupal by putting Varnish in front preventing the origin from being hit so not really scaling Drupal as such, varnish is taking off some load where it can.
Drupal is probably the extreme though. If you have a simple app with a few scripts, light use of a DB it’s not to bad. I’ve heard it’s come on a lot in the past 10 years and Laravel. I certainly had less issues using PHP than I do with JavaScript.
Then, for app performance:
My approach is to usually design the app / refactor the app so static content can be fully cached. In ecommerce sites this can make an absolutely impressive difference. Then, leverage opcache and object cache and further separate cacheable path from dynamic path in dynamic SSR queries. Always drive using APM performance metrics as a guide. No need to optimize the DELETE /user endpoint called twice a week.
Then, identify the heavy hitters in the dynamic DB queries, and basically write those in hand rolled SQL. It usually boils down to 4 or 5 queries doing 99% of the work (GET /posts, GET /categories, GET /products, etc...). I do this fairly late in the game, but think about it very hard up front. I like to use some kind of ORM for everything writing to the DB, and sql builders / pure SQL for reading.
The split between cacheable / non-cacheable can be subtle depending on the application, and might require some non-obvious structures in the codebase.
For real tricky performance issues (not something I had to do in PHP projects), I will either ducttape some AWS infrastructure or handroll a microservice in C++ or golang. This is something I had to do for realtime / transient loads.
It doesn't make scaling hard, it makes scaling very easy because you can just horizontally scale out as many instances as you need. The constant factor is pretty awful, but that's the tradeoff you make for statelessness.
In practice it makes scaling hard for financial reasons if you require 128MB+ per request. A 32GB server will struggle with more than 256 concurrent requests at 128MB+ per request. A 32GB server is an extremely large server for such low request numbers.
If you can bring the memory usage down stateless works well. I use a bit of rust on aws lambda with the lowest memory settings so pay fractions of a cent and can handle more traffic than I ever need. I do set up persistent connection pools for the life of the lambda and only bootstrap once to bring down latency per-request but treat it as an ephemeral horizontal scaled service.
With that said, I think the stateless nature of php is talked up too much.
While not enforced by the nature of the language like php, writing stateless apps in other languages comes quite naturally.
Scaling difficulties are almost always to do with the database solution rather than the app, and overcoming those problems has little to do with the choice of language.
I of course value at least partial "stateless" (functional core / hexagonal architecture, event driven architecture) in any language, because they reduce complexity so much.
In Laravel it's not too hard to avoid this problem but a lot of noobs don't get the lazy / eager loading thing and then you end up like this.
Drupal seems to add hundreds of queries for every module you add.
I do think very hard up front what the product will require in terms of: - static content - dynamic content that is cacheable and which keys can be used to cache it
Static content can use ORM as much as it wants, cloudfront will take care of it. dynamic content that is rarely hit doesn't really need much help either if there are no UX latency requirements. dynamic content that is hit very often (usually only a couple of endpoints) can be rewritten into manual SQL.
If you think about it, most page hits with dynamic content can be rendered basically by the DB + templating engine, and no other logic should be involved.
I do think people who react so viscerally negative to it in 2022 are only doing so from an old preconception and not judging it for what it is today. I build seriously large and complex applications and never once have I felt that I was fighting PHP or it was holding me back. I don't really get the hate.
https://www.brightball.com/articles/no-such-thing-as-real-pr...
(Old article with a lot of dead links now, just FYI).
These days most organizations will not tolerate just copying files over. There will be a process for testing the code and then stuff will probably be put in a container, to be even easier to run on another server.
At that point the advantage of just sftp-ing files over disappears. It is no longer deemed safe enough to do so. Usually it is not the end of the world, if your website is down for a minute, but it does tarnish the public image of reliability, so organizations are not willing to put up with developers making a typo somewhere bringing down their website or causing at least an annoying error on the website.
Instead of copying files over to another server, you would typically do some docker pull or other container engine pull some image or what have you. Then you would run that previously tested thing on the server.
There is a whole range of projects like that out in the wild, once you leave the realms of startups and big tech.
It's about as easy to do "proper" deployment using bundles / containers / CICD / kubernetes / gitops with PHP as with any other stack. It's also possible to click a wordpress domain for $10/month and upload 2 php files and start making revenue.
For a small business that is starting up, choosing between $10k of freelance work to get a nice github actions workflow on GKE + a monthly retainer of $2k for "maintenance" vs a one time $1k of freelance work to get a wordpress where you can configure the plugins and theme yourself is a no brainer. Many of those small business then grow much larger and reach a point where in hindsight you can say "should have gone with docker containers". But the original decision was not just perfectly valid, but probably the only reasonable one.
I am not a JS fan. This is not because I have anything against the language; it's just that I have no real need for it, and have treated it as a "necessary evil," in my frontend work, so I don't believe that I have much of a platform to lob spitballs at it.
PHP, on the other hand, is a language that I have used for over 20 years. I think it was 3 or 4, when I started. If I do backend work, these days, I'll be doing so, in PHP.
I always like looking at the "fishtank graph"[0]. That sort of puts things in perspective.
[0] https://w3techs.com/technologies/history_overview/programmin...
> - no "unknown unknowns". it's so tired and true, there's no surprises
I had one web host where magic_quotes_gpc was enabled. Good luck figuring out what the hell is going on with all these extra quotes in your variables.
And I kept looking up how to do prepared SQL statements in PHP, finding the mysqli functions, and then eventually figuring out that mysqli wasn’t available on your average web host with PHP back then.
(Yes it was that long ago. I also think a lot of the hate comes from that era)
I remember the documentation as well, with usually all the gotchas in the comments. Which is great, but there were a lot of gotchas. like, A LOT.
If you're using something other than cgi to get your httpd to talk to your webapp, your answer lies in understanding the architectural decisions of that tool.
In the most primitive ways, you would at least do cache warming, which usually means "building" the app instance in a separate folder and swapping the active directory served by the web server. That's basically what a basic Capistrano deploy would do.
Nowadays I'd expect most shops to be using containers for PHP too, and that means building your container like any other language.
What I'm saying is, the days where PHP deployment was simple have been long gone, for at least a decade in my experience.
Back in the day PHP got big because most of the larger shared-hosting sites provided mod_php out of the box, along with MySQL.
If you wanted to run CGI scripts you were probably capable of doing that, whether in Perl or something else, but most of the other options came later or were unusual.
I know when I tried to setup a few sites a long long time in the past I had to get a VPS of my own, with root, to configure Apache appropriately. None of the shared hosting sites would have run the kind mods I wanted to have.
I think the "the more things change, the more they stay the same" is a great thing, and something to very much be aware of and study. The move back and forth from backend state to frontend state to slim apps to fat apps has been going on since the 60ies, and is driven by ultimately hardware and networking costs.
The underlying patterns are all fairly well understood, which means that knowing both approaches and being aware that things are going to slosh back and forth heavily simplify long term design.
I haven't written these thoughts out, but in many ways the codebase (as in, how your files are organized) is largely independent of how your code is actually deployed and where it runs. If you are aware that some business logic might one day run in the frontend on the client device, and 4 years later might make more sense ot run in a lambda, that's something you can architect for.
Serverless / stateless is ultimately "functional programming". If you write your code as a side-effect free function, leveraging technologies like WASM, you can keep the same code, and deploy it frontend or backend or both or as a lambda or as a single node worker, and the code itself won't change. These are the things that next.js and vercel and edge computation leverage, but it is true in every codebase (embedded, desktop applications, etc...).
Edit: Not sure why this is controversial. Here is a "hello world" benchmark I just ran on my machine, in units of hello worlds per second: Perl – 1020 runs/second; Python – 78 runs/second; Ruby – 30 runs/second.
Drop a file on a server, it notices filesystem change, reloads an app (or spawns a second copy of app, waits for it to initialize, kills original app and switches over to a new one)?
One problem with this approach is what happens when you're updating multiple files. If the server restarts immediately on the first change, you end up loading a mix of old and new files, which probably won't work properly. But if you delay the restart to wait for all the files, how long do you wait? If the delay is too long it's confusing and annoying (did the server restart yet?) and if it's too short you get mixed versions as before.
So it's better to explicitly signal when it's time to restart. You can still have automatic restarts in the development environment.
[1] https://docs.gunicorn.org/en/stable/settings.html#reload
Ex. First even triggers a 5 seconds wait. If before those 5 seconds have passed there is another trigger (say after 1 second) another 5 seconds wait starts, for a total of 6 seconds in this example.
I think downvote = disagree is expected. If someone thinks your comment is not making valid points, downvoting is a way to bury it below other comments.
So that, naturally, the comments that the community most agrees with (in addition to adding quality content) bubbles to the top.
I agree that the comments should be removed or at least hidden by default as they're usually not relevant anymore.
I respect that some people accept dynamic typing as a better tradeoff for various reasons (I've worked with Ruby for many years before I discovered my love for type systems), but to me that statement reads similar to:
"No long CI builds because we skip all the tests."
:)
Compile-time type checking is a soundness proof of your program, which is an entirely different thing.
So I am sure some professionals write brillant code in php, particularly in large organisations, but my guess is that the median code base quality out there is probably pretty lousy. Anything below the 80th percentile probably too.
Also it’s for websites only.
One of the things I do like about PHP is that while most legacy codebases out there are lousy (even when good developers are involved), and often lousy for totally legitimate reasons, PHP with its "don't even try to do clever" approach makes many things easier.
Of course, I only dealt with so many legacy applications. My worst experiences have always been with python legacy code because there were strata of conflicting "better code" approaches piled on top of each other.
Once you start abstracting into patterns, and you don't have the experience needed to get a sense of good architecture, it's easy to make a real tangled mess.
In any case, I definitely agree with all those pros. What I dislike about PHP is that as you start growing a codebase, especially with includes, your attack surface just grows and grows and grows. In other frameworks where a stack is involved attack surface generally grows as well, but since any PHP script has access to the request, it's much much worse.
I think it's the best documentation out there, and that part of the reason it's easy to document, is because the language uses a standard library, and functions, as opposed to the structure of the language, itself, to provide most of the utility. Functions are easy to document.
They do a good job of "cleaning out the cruft," as well, so that there isn't much in the way of "no longer applies" stuff.
Part of it, too, is that the language probably supports stuff all the way back to 4. They tend not to deprecate, and accrete, instead (not always a good thing). That means that examples and discussions maintain relevance, even years later.
One of the biggest issues that people tend to have with PHP, is that it allows you to write bad code.
I came from a C++ shop (another language that people love to hate). If you think you can write bad code in PHP, C++ says "Hold my beer."
I am a big believer in Discipline. With Discipline, we can write excellent, maintainable, code in any language. I have written stuff in Assembly, FORTRAN, Pascal, PL/1, Perl, Bash, BASIC, C, C++, ObjC, and Swift, that is quite well-structured, maintainable, and well-documented.
That's sort of true, but the default state mechanism (session files) doesn't scale well, or even work across load balancers that don't maintain server affinity for each client. Scaling a PHP app isn't hard, but it can be non-trivial if you've written the code without considering scaling. Other serverside scripting languages (Python, Ruby with Rails) nudge you in the right direction in ways that PHP doesn't.
(I do like modern PHP well enough.)
The killer feature of PHP has always been the hosting ecosystem. A simple FTP upload would do the job without knowing much about the hosting infrastructure. Recently we've got that kind of "serveless" experience for other languages as well but the deploying is proprietary and the providers are very few. I'm aware only of Google Cloud Run.
As for JavaScript even its inventor said it's time to move on. It's time for a new language and a new DOM interface. Maybe we can fix the "language" issue with WASM but we are still left with the DOM.
Facebook manages quite well with PHP. Maybe it's your fault you didn't learn how to use modern PHP practices which have been well-documented for over a decade now.
I didn't say you can't make it work. You can build great stuff using just bash scripts. I'm pretty sure you can have success with any programming language. That doesn't mean it's the "best" way to do it.
>> Maybe it's your fault you didn't learn how to use modern PHP practices which have been well-documented for over a decade now
I doubt it's my fault. I'm not "special". I think PHP is prone to bugs and bad practices both due language design and bad documentation.
Not in 2022. I avoided PHP for a long time. I got back to it and found that the Internet and books are full of best practices and I have not had an issue with documentation either. Would you please give me an example of how PHP is more prone to bugs vs. other languages in this area? I have found it to be really difficult to write buggy and insecure code. For example if you have not heard of PDO and you do not prepare, bindValue/bindParam, and then execute, that is your fault (make use of filter_input() as well!). It is advised literally everywhere today. Regardless, my return to PHP was pleasantly surprising. I finished my project pretty quickly and I have not used any frameworks. Security vulnerabilities? Perhaps, but so far so good. We will see. I tried my best and I have done my research. Every time I mention that it is written in PHP, people frown because they are stuck at PHP 5 or so. That said, subpar defaults in php.ini is still a thing though.
Sources?
I hadn't seen that quote, do you have a link?
The anti-PHP cult is strong here on HN. List 5 benefits of React and watch your upvotes skyrocket.
I always have a hard time understanding what exactly is meant with comments like these. We can all agree that PHP has a wildly uneven standard library, had its fair share of security-relevant footguns, tends to have unexperienced developers. That's not extremely different from python and node.js, for example.
The language significantly cleaned up its act, it has had classes, traits, closures, introspection, namespaces, packages for well over 10 years now, a robust third party library ecosystem and many successful projects to build upon (wordpress, drupal, woocommerce, phpbb, etc...). This makes it a pretty good choice for many applications.
The stateless model and the resulting "no crazy stuff" approach makes it a much more reasonable choice for web development than say, python+django or ruby+rails to me. There's nothing I loathe more than trying to find which duck-typing, method-injecting package is causing a slow-burn memory leak in production.
I also don't understand where the "most web technology is terrible" stance comes from. I find the quality of software engineering and the care put into developer UX and productivity in the web world quite inspiring. It has been a forcing function on all programmer tooling since the cambrian explosion in the earlier 2010s.
Then comes the shiny new car - it has way too many gadgets and gizmos, you don't know how most of them work. Heck, you don't even know what half these gadgets are for. You don't know when or how it will break. But most importantly, you don't know how to fix something when it breaks, because there is too much magic going on. High maintenance, constant stress.
The first case is PHP. People can dunk on it all day, every day. But it is good enough for most projects. And with tools like Laravel, Composer etc, PHP is constantly improving too.
The latter? I dunno, there are lots of candidates for it I suppose.
In this case PHP is unexpectedly rounding floats for display.
~ python3
Python 3.9.13 (main, May 24 2022, 21:28:44)
[Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> b = 46333.48000000001
>>> b
46333.48000000001
~ php -a
Interactive shell
php > $b = 46333.48000000001;
php > echo $b;
46333.48According to the Twitter thread:
> First value was retrieved from a db, second was calculated, which has introduced rounding errors.
There are better examples of PHP being bad.
This is perhaps one of the better things about it! It feels like lots of different languages and frameworks would benefit from comments at the bottom of the page, from the community, explaining various common use cases and gotchas.
Somehow it feels like docs being on GitHub with people being able to contribute to them there somehow can have higher friction, versus a forum-like system.
> - it's stateless by design (much easier to scale)
I'll grant you this one. Though PHP in practice goes to great lengths to add state back in for performance reasons (e.g. memcached, or for a while APC).
And Haskell is stateless, too, yet not a frequent choice for web work.
> - it was "serverless" before Serverless
This is retconning. It was never trivial to set up a LAMP stack, especially at scale. I can't tell you how many times I've seen the PHP "too many open database connections" error because someone just treated their Wordpress blog as "serverless" and it went to the top of HN.
> - surprisingly performant
I can't speak about the latest stuff, but PHP5 in ~2014-15 was abominably slow. There were certain "benchmarks" which indicated it was fast, but on closer inspection, these were simply calls where PHP provided thin wrappers around C calls.
I had to once take an Excel file, parse it and then present certain fields to the user for the DB to be updated. This was possible in PHP, but it took excruciatingly long (like 8 minutes - in fact, sometimes Apache would just drop the connection), and third party library support was just awful. I implemented the same task in Python, and not only was the code much simpler and and easier to write, but the task took a second or two each time.
> - no "unknown unknowns". it's so tried-and-true, there's no surprises
The standard library is a toxic sludge of surprises. Nothing is consistent. "Will this function treat an array like a list or a dict? Who knows?"
Maybe this is better now, but the last time I dabbled in PHP, I spent a while trying to get a workable debugger set up and gave up. Stepping through code is apparently impossible, and every now and then you hit some fatal error that immediately crashes your code.
> - deployment is so simple, just drop a file on a web server. No middleware needed.
What does this mean?
First, PHP has middleware (e.g. memcached, Apache/Nginx).
Second, the complexity of deploying a Python, Node, Rust, Go or Ruby application is not the "middleware." The complexity is ensuring that the update is correct, the update is applied consistently, can be rolled back, doesn't cause downtime, etc. I could also do updates by running webpack dev server in prod and dropping files in there for deployment. As easy as PHP, yet a terrible idea.
> - No long compile times because there is no compiling needed.
This is odd to say the least. PHP's biggest weakness IMO is that each thread must entirely parse and interpret its executing program on every single call. That is a ton of wasted work, and there are literally sections in the PHP docs about tools to circumvent this problem.[0] And the solutions involve caching, which mean we give up (1) the "stateless" benefit and (2) the "just drop in a file" benefit, or else we need to add a bunch of cache coherence logic. It would be so much easier if someone could compile the PHP code to a bytecode format and drop _that_ in, which could just start executing on an interpreter ASAP.
Ultimately, I think the list is getting downvoted because it deviates so much from developers' experience with PHP. PHP started out as a sub-Turing templating tool that had a Perlish language bolted on, which then mutated to look a lot like Java. Eevee's classic blog rant[1] calls it a "fractal of bad design," but the reality is PHP has no design: it's just a kludge of duct tape and bolts.
Also, maybe this is totally incorrect now with PHP6--er PHP7 and PHP8. But my experience with PHP4 and PHP5 was so horrific that I will not be working with it again. I've yet to find a PHP use case that is not better solved with a combination of a static site generator and something like AWS Lambdas or Cloudflare Workers.
[0] https://www.php.net/manual/en/book.opcache.php
[1] https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/
As a counterpoint, I used PHP5 when writing https://www.goldeneaglecoin.com/ and it was always < 50 ms on my endpoints, running on some crusty hosted celeron at the time. Adding caching and opcache doesn't invalidate the stateless approach.
Programming is about adding abstractions on top of underlying computational substrates. Ultimately our CPUs don't care if we run haskell or PHP, they just run machine instructions. I never found it too complicated to use useful abstractions in PHP.
I usually prefer inheriting a subperforming cache-free PHP site, because devising a consistent cache strategy is usually not too hard (cache static content + opcodes on deploy, determine which invalidation keys you need for the subset of dynamic content that does the bulk of the load / has latency requirement, don't cache the rest). If I have a big collection of lose php files, that's reasonably easy to do. If i have a tangled web of middlewares and ORM'd business logic, it's much harder, and I usually have to unfold it to "lose leaves".
> Adding caching and opcache doesn't invalidate the stateless approach.
> Programming is about adding abstractions on top of underlying computational substrates. Ultimately our CPUs don't care if we run haskell or PHP, they just run machine instructions. I never found it too complicated to use useful abstractions in PHP.
I'll push back a little on these. TL;DR: it's a trade-off.
My point with Haskell is that the entire language itself is stateless, so if per-request statelessness ("shared nothing") in PHP is a virtue, then certainly total statelessness ("purity") in Haskell is even more of a virtue. The problem is that, despite having similar performance to PHP, Haskell is hard to write.
This is illustrated with caches: if a PHP program had a line something like `if ($cache.retrieve('foo') != null) { echo "Success!<br />"; } else { echo "it's broken"; }`, then now global state matters again.
Haskell doesn't allow code of this form, but forces you to think harder about how to make it work using e.g. monads, and this can be frustrating. But if you can get Haskell to work, you can get caching nearly for free.
function get_all_products() {
return cached(function () { return Sql::Select(PRODUCT_TABLE); }, Cache::GetSessionCacheKey());
}
render_template(Page::GetTemplate(),
[ "products" => get_all_products(),
"user" => get_user_data()
]);
or as I did for https://goldeneaglecoin.com/ , I would internally route "HTTP" calls, so the javascript and PHP would look identical: /*
* @url: /products
* @cache: session(1h)
*/
function get_products() {
return Sql::Select(PRODUCT_TABLE);
}
render_template(HTTP::GET("/templates/products"), HTTP::GET("/products");
while the javascript looks like: GET("/products").then((products) => render_template("/templates/products", products))
The caching is declarative, and the code is "stateless." This is fast enough that caching the render is pretty much not necessary, despite running on a t2.medium, and easily sustains > 100 rps. In the happy path, it reads a single value in the object cache. Only an initial hit will cause a render (using a bytecode compiled optimized template), and only the first XHR will cause an actual lookup in the server side cache (if necessary) because the browser then does the rest.I wrote this code 12 years ago, and porting to react doesn't require any change on the server side. We just put RTK-Query in front and let it do all the rest.
I don't understand the purpose of your post.
Do you judge all languages according to your experience from 8 years ago?
Do you go on python boards telling everyone how much you hate working with python 2.7?
Maybe spend your afternoon on rust threads to complain about it not being available to the public yet?
Do you need to like a language for 8 entire years before letting anyone know about it, or just some time within the past 8 years?
GGP was wondering why there were downvotes rather than comments detailing disagreements.
I decided to write down the reasons why I personally would not touch PHP again rather than give a downvote.
Maybe PHP8 or PHP7 or whatever it is (I know they skipped 6?) is awesome, but I've moved on.
Also, FWIW, a few of my objections are certainly still relevant based on the claims in GGP's post and some cursory review of the documentation, particularly around caching & in particular op caching.
> Do you judge all languages according to your experience from 8 years ago?
No, only ones that left mental-emotional scar tissue.
> Do you go on python boards telling everyone how much you hate working with python 2.7?
Python 2.7 was highly pleasant. I wouldn't use it now, but it didn't abuse me. :)
> Maybe spend your afternoon on rust threads to complain about it not being available to the public yet?
GGP: <X> is awesome for these reasons!
GGP: HEY! Why are people downvoting rather than commenting?
GP (me): Here's why your reasons don't persuade me based on my admittedly outdated experience
P: Why are you so critical?
> Do you need to like a language for 8 entire years before letting anyone know about it, or just some time within the past 8 years?
Non sequitur. But the answer is no.
Perhaps it might be more productive if someone commented which of my claims are obsolete rather than ad hominem them. I know that those relating to compilation, deployment & statelessness are still valid, given GGP's comments and my cursory examination of the PHP docs, plus experience with other platforms.
Maybe modern PHP has truly excellent performance. Maybe using a breakpoint debugger has been solved now. Maybe design is better, e.g. the standard lib has functions that can work with arrays as lists and arrays as dicts without being surprising (e.g., `filter()` used to preserve all indexes, since it treated arrays as dicts from numbers to values; often, you needed to use fold/reduce or a loop to re-number after a filter).
Install opcache, done. No need for hyperbole.
Do you ever run into race conditions? And how does it handle cache coherency?
fun thing I also wanted to add a point about documentation but you did it yourself, life is fun sometimes :)
"By design" PHP encourages very very stateful procedural programming. It is one of the languages, where making things not mutate state seems like a mostly unused strategy. The amount of beginner code people find online and that mindset of "if it works it works shrug" continues to keep bad code alive.
The thing that might be referred to here by "stateless" is that a PHP "application" runs the code from top to bottom, as if all was one long script. This primitive handling has its own issues of course, but I will admit, that sometimes it is useful, that you can change the code and do not need to restart PHP or anything, because you will get the new script executed when the next request comes in.
> - it was "serverless" before Serverless
Where "serverless" is just a buzzword. PHP runs on a server just like many other languages. You will need a machine acting as a server, you will need PHP installed, you will need some webserver, usually something like Apache or NGINX with fpm or some other shenanigan. Nothing really special there.
> - surprisingly performant
Which in part, I would claim, is due to its reckless way of handling types, introducing hidden bugs. The type system is quite underdeveloped and cannot give many guarantees. No generics, no general object type, which everything inherits from, but only an object type, which not every other object inherits from. Then that "mixed" type, which just makes things even more fuzzy in a signature of a procedure and encourages bad design again.
Of course, if you throw all safety overboard, then you can get a bit more speed. Not really impressive.
> - no "unknown unknowns". it's so tried-and-true, there's no surprises
I just recently looked at defining constants in PHP. But I could not see in the docs, what the scope of a constant is. Simply not to be found. I just had to try it and hope. This is often the case with PHP and its half-baked docs.
> - deployment is so simple, just drop a file on a web server. No middleware needed.
But the webserver is the middleware you need. Like mentioned above, some Apache you need to configure, or some NGINX, or some other server. Maybe you have only ever deployed on managed infrastructure and never done the actual full deployment? Always enjoyed other people setting things up for you? I guess this is true for most of the people claiming, that PHP deployment is simpler than in other languages.
> - No long compile times because there is no compiling needed.
That again comes at the cost of safety. PHP types if you declare them in the code are not checked at compile time, but only when the code runs, making them merely annotations to read for another person.
In the PHP world we have learned not much from the past decades of programming language design. It is understandable. Lots of people have build tons of almost breaking things on top of PHP's design flaws and would start a riot, if things ever changed. For the sake of backwards compatibility PHP will remain in its swamp of bad design choices.
Sure, people can try to build on top of that, abstracting from it all through more modern web frameworks, plastering over all of the flaws. Sooner or later though, you will need to use some actual PHP code in there somewhere and the bad design will rear its head again.
- worst way to do templating
- weird mental model of putting all logic and templating in one file
That's up to you though. You're welcome to put all your logic in one file and your templating in some other file.
Not just as easy if they don't allow you to insert arbitrary code at arbitrary points as PHP does.
Personally my preferred approach is Wicket where you can't have any logic in your markup at all, all of your logic lives in code and the only thing you can put in the template is IDs for where the code can insert child components or plain text. (OK, it's not quite that strict, but it gets pretty close in practice).
> at some point it boils down to the programmer's level of expertise, but also to the programmers' opinions as there are still a lot of varying opinions on what exactly are best practices.
That's neither here nor there; "programmer's level of expertise" is just abdicating responsibility, when in fact a programmer at the same level of expertise might produce much better code in one language than another.
By using Wicket you are making a choice to opt in to a template system that encourages best practices. This is the same reason people in the PHP ecosystem opt in to Twig/Blade/Mustache, or how people on Ruby opt out of ERB for Slim or Haml.
Also, to be frank, it's a real shame that people look down their noses at PHP so much just because of the sheer amount there is that can be learned about the practical application of design patterns from spending some time in the Laravel code base.
PHP has had solutions from the beginning or at least early times.
PHP lacked that cult figurehead and was always community based. Most new languages are corporate sourced (open source by corporations).
If you choose Hack, you lose the entire PHP ecosystem (composer) that could back you up and save you time. The only ones really using it are Facebook/Meta, so it would be a mistake to choose it for a new project, IMO. It doesn't really have a future.
- it's stateless by design (much easier to scale)
- it was "serverless" before Serverless
- surprisingly performant
- no "unknown unknowns". it's so tried-and-true, there's no surprises
- deployment is so simple, just drop a file on a web server. No middleware needed.
- No long compile times because there is no compiling needed.
EDIT: why the downvotes? If you don't agree, just reply so we can have a healthy dialogue.
EDIT2: I also think there is something unique about PHP documentation. It has plenty of real life examples, and the ability for users to leave comments allows you to hear directly from others "gotchas" that people have experienced. I feel like PHP documentation is very undervalued.