PHP Doesn't Suck Anymore
developerjoy.co
developerjoy.co
Going from a language with a well organised stdlib with consistent syntax to php is not fun.
Sure, it has a lot of nice features now, and some of the footguns have been removed, but the core language is still there and it's still a mishmash with a bunch of hidden landmines.
As someone who spent many years developing in (and defending) PHP, I agree with everything you just said.
Nowadays, I'd rather reach for Crystal, Go, or Rust for back-end application development, and Python or Typescript (!) for automation scripts.
This is one of the weakest, "not happening in reality" issue of PHP though. It's the most obvious, and the one who don't use php but glance at it point. But in the real world, any editor you use not only show it but also show a type error if you made a mistake, on top of that after a few hours you know which is which (yes strpos and in_array have an opposite haystack/needle, but each always use the same, once you use them more than 5 times you remember the same way you remember to check for 0 on strpos).
There are still flaws in the php world, but the one most commonly pointed out are always sounding funny to me because they're flaws if you show an exemple in a conversation but that you don't actually hit when coding.
Good languages don't make you memorize exceptions.
Yes... it's a bit /s, and perhaps is a bit much, but... this "my language has no defects!" attitude from everyone crapping on PHP is tiresome. I've been programming as a hobbyist since the 80s, and professionally since the early 90s. Nothing is perfect, everything has warts, the holy wars suck. I've been with PHP since early 96, and have worked in ASP, .NET, Python, Ruby, Java/JVM, Node/JS, and a couple other stacks. They all suck in more than a few ways.
For those of you who only ever work in one tech for years without needing to touch anything else... and get to perfect your parameter-order-fu down to a reflex... great. I'm routinely having to switch between different SQL and various server-side languages, and even then ... 'obvious' things like array/string handling have different syntaxes I have to jump between in a single day. (postgresql arrays are 1-based, not 0-based, IIRC). You know what? I deal with it and move on. IDEs/tools help. Memory helps. Nothing is perfect.
Praytell, how does your editor show you a type error when both `needle` and `haystack` are strings?
It's hard to trust a stranger from internet claiming something, but we are in IT so it should be relatively trivial to prove your claims, right?
And that will return true, because you forgot the third "strict" parameter. This is really something strict_types could/should have fixed, but it doesn't.
You can have code reviews and static analysers and all of that to catch this, but it's definitely a landmine. I've seen some pretty serious CVEs that were fixed just by adding that last parameter to some in_array() call.
Was that everything? You basically state there's a problem because you didn't use the function correctly and language didn't fall head over heels to stop you from doing silly things due to slopiness?
P.I.C.N.I.C.
Anyone who is not capable of taking care of what you called footgun in a way where they automate - that person is not serious.
If there's a pretty huge problem - manage it. That's your job as programmer. If you're lazy, sloppy and prefer whining online over being proud of your work - there's no programming language that will take care of that for you.
Please provide examples in other languages (eg rust) so that I can answer your original question properly and to your satisfaction
What kind of logic is this, to blame the tool because you have no clue how to use it?
Tools must be designed so that they're difficult to use incorrectly. That's why we have guards and interlocks on any tool more complicated than a shovel.
This really isn't that hard, we're not trying to travel to Mars.
It would easily catch this. https://phpstan.org/r/a827ff45-4ee2-4bee-8ae0-935832e627b3
I hate Rollercoasters, I hate surprises and strong emotions. So if you ask me how Disneyworld is, I'll tell you it sucked for me. But maybe you are onto that, so you shouldn't trust me.
Back yo PHP I've used it for super fast tiny dynamic websites, and it works wonders. I wouldn't do an online exchange with it though.
It starts as the ultimate anti-structure. Nothing, not even MVC. But then you can refactor parts out of it and start moving towards a structure. Very freeing if it's a small one-off page/project and you know what structure works for you.
(Of course, if you need a database and authentication and Scaling and so forth, that's when you start bringing in the heavy artillery (libraries and packages), or switch to a framework.)
Malvina Reynolds - Little Boxes https://youtu.be/VUoXtddNPAM?t=14
It just keeps running and auto corrects any temporary load issues because of its stateless nature. I don't have to worry about memory leakage or processes that eventually become unresponsive and needs to be restarted. If the unlikely event that the PHP process crashes, it will just restart automatically and handle the next request as if nothing happened.
Its the ideal solution for side projects, and I am definitely going back now that I don't have time to maintain complicated infrastructure.
PHP was my generation's version of AWS stateless "lamda". Just place a file in the folder, and it will be executed on demand and clean up resources after the request has ended. A server could handle many different websites at the same time. That was basically how we could get cheap webhosting. They just put a bunch of Apache-instances behind a load balancer and used a shared network drive to read the files from
To be fair, it shows up as a nightmare from a certain scale. Toy projects might not reach this level..
Python has been around for like 30 years, why isn't that quite the case?
I guess there was mod_python but nobody cared enough: https://modpython.org/
I guess there's now mod_wsgi which is similar to PHP-FPM in some ways: https://modwsgi.readthedocs.io/en/develop/
Yet, even with the actual deployment not being much different (just used Apache as an example here), there's still dependency management, which Python is often described to be pretty messy at, virtual environments or not. With PHP, most of the stuff you need for common use cases often is pre-installed and is just a matter of enabling some plugin in the config.
That said, I deploy most of my stuff in containers, so PHP, Python, Node, .NET, Java and others all become more alike when viewed from the outside.
> Python has been around for like 30 years, why isn't that quite the case?
> I guess there was mod_python but nobody cared enough: https://modpython.org/
Because it sucks! We tried it, it was bad, the Python community left it behind. Maybe if PHP left things that suck behind too then fewer people would say that PHP sucks.
> It is the purest form of web programming. You don't need a framework. Spin up a server and just start writing. Experiment. Do crazy things with it, like an art project. Every page is it's own world. Have fun with it.
Why would that be a bad thing? Even when it comes to something like REPLs, everyone always touts being able to iterate more quickly as a good thing, don't they?
Edit: aside from the implications of an in process language runtime, that was discussed in another comment.
“This is good because it enables you to iterate quickly” isn’t a good argument when you can iterate quickly regardless.
Necessary? Not quite.
But having those things be closer together leading to faster iteration? I'd argue that that's definitely true, same as how someone could skip out on writing a bunch of enterprise programming patterns, MVC or even tests, as well as use a language with a dynamic type system, or even write serverless functions. Not that any of that is very maintainable long term, but at the same time nobody would expect that from something that's very much like a REPL.
It's the same as how I like to have a clearly separated front end (typically a SPA) and a back end API (something RESTful) in most cases so that those technologies wouldn't be coupled and the API could be re-used as necessary, except that people who go for the various SSR and templating approaches typically code around me in circles, because they don't have to write as much API client code as I do.
In the age of cloud, you just run your web application as its own server, and just have a proxy that fronts it.
How is a mainstream web server acting as a reverse proxy for an app server unsafe?
You get the benefits of one common approach to configuration, request logging (and possibly log shipping), rate limiting, compression, path rewriting and so on, while letting the app server handle the actual app and language runtime stuff (whether it's some Python app server, PHP, Java with Tomcat or whatever). You can even serve any static assets right there, alongside your API.
You can either include everything in a container, have separate containers for each process with overlay networking, or just have them run on the OS directly with only the web server binding to whatever ports you want to expose.
As for scaling, none of that prevents you from running anywhere between 1 or a million instances in parallel, with some load balancing (whether it's multiple servers or containers across a cluster). If it's really that bad, throw in HAProxy or something into the mix, alongside whatever cache solution tickles your fancy.
That's besides the point that I could provide a service to everyone in my country on a single rack (redundancy aside), not everyone even needs some mythical sky high scaling target.
> In the age of cloud, you just run your web application as its own server, a just have a proxy that fronts it.
Whether you use your own ingress (there's a lot of good ACME solutions out there) or something that your cloud provider gives you, using a server per app would in many cases be wasteful and there's a bunch of ways to increase the density, especially with the dynamic scheduling most container orchestrators could also give you.
mod_php was great for local iteration or when you wanted a very simple setup (and the same could be said about mod_python etc.), but most people have moved over to PHP-FPM nowadays: https://cwiki.apache.org/confluence/display/HTTPD/PHP-FPM There's probably more recent information somewhere, but this pretty much covers it.
Here's a very simple setup of two separate processes, with Supervisord (this is what runs in my self-contained dev container, but no reason why someone couldn't do something similar with systemd, or on a container cluster, with different users/permissions for each process):
[supervisord]
nodaemon=true
[program:php-fpm]
command=/usr/sbin/php-fpm -c /etc/php/fpm/php-fpm.conf --nodaemonize
[program:apache2]
command=/usr/sbin/apache2ctl -DFOREGROUND
And approx. how the Apache configuration might look: LoadModule proxy_fcgi_module "/usr/lib/apache2/modules/mod_proxy_fcgi.so"
<FilesMatch \.(php|phar)$>
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
Conceptually, that's not very different from WSGI for Python: https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface#S...But yeah, I agree about the shortcomings of mod_php.
php -S localhost:8000
https://www.php.net/manual/en/features.commandline.webserver...This achieves the same thing while providing more control and layering standard protocols.
Scripting? Ha! We used to do CGI in C when Perl wasn't fast enough. <old-man-yells-at-cloud />
How do you go into production? You put the file in a folder on the Web server. It works everywhere the same.
The code writing part itself is very straightforward and there's nothing counterintuitive as long as you don't try to do something that it's not designed for.
>there's nothing counterintuitive as long as you don't try to do something that it's not designed for.
Maybe that's the key. Instead of trying to write programs with tools that are not made for this but are somehow bullied into doing it, just use the right tools.
For generating HTML based on a request and data in the database, PHP it is. Don't try to make a language made for DOM manipulation process data and generate HTML.
For Web UI, DOM + JS it is. Learn how browser works and write the JS that will modify the DOM as needed which will result in interactive UI. Don't stack abstraction.
Well, not really because you have this massive php.ini file with tons of settings and whatnot, and scripts not working due to that was always a common point of failure back when I was using PHP. Also: not having some extension, which are almost always in C and require server installation (which is quite different from many other languages, where the user can usually specify most or all of their dependencies).
Maybe all of this changed? I don't know. But PHP in general has been the most fickle and unreliable environments I've dealt with. Give me any random servers, and I find it very hard to tell if my PHP script will run.
That's of course for singe server applications. However, because everything is straightforward and built for purpose and not trying to pretend being something else, more complex systems were still easy to setup and manage.
The joy of coding PHP usually died off with frameworks like Symfony where they built complex abstractions for the pleasure of the "Enterprise" projects with many moving parts.
I also have to say that php.ini is probably one reason PHP became so successful in the first place, by having things like safe_mode and such so it could be easily used on shared hosts with ease. All the $2/month shared hosts were offering PHP, not Perl or Python, because of this (and mod_php).
But other settings like that automatic $_GET/$_POST importing ... yeah, that was a lot more misguided. Even error_reporting really should never have been a system setting: always let the code handle these sort of things. And even safe_mode is mostly outdated and useless now, because no one is doing shared hosting any more.
Unfortunately all cloud providers I know bank on JS. I like JS but when it is in the browser, on the server it’s a disaster.
Today that sort of thing is very rare; you will run in a virtual machine or container, and have an execution environment all to yourself.
PHP-FPM which has options to specify system user per pool is basically how restrictions on file_get_contents are enforced.
For example, both ASP and ASP.NET can be developed using Notepad.exe directly on an IIS web server, and you can similarly test changes by simply refreshing your browser.
Personally I'm allergic to this style of development, the "banging on it with a rock until it starts moving" approach tends to result in poor outcomes over the long term.
I much prefer that a compiler go over the entire codebase and check everything when I hit the compile button.
Sadly, this bad habit from PHP still lingers in ASP.NET Core to this day, and causes me endless grief.
Just over the last couple of months, I have encountered the following:
- DEV, UAT, and PRD are out-of-sync with each other and the source code. When I asked the developers why that is, they said they make changes to individual files instead of "building the whole thing", because "that's faster". Okay, they saved the two minutes the pipeline takes to run, great. Now I have to spend a week disentangling the mess.
- I refactor something, hit build, it comes back with all green ticks, I deploy... and the site is broken with HTTP/500 a day later because these scripting-style frameworks don't build the page code until runtime.
- A security vulnerability code scanner was enabled, and it broke the build. Why? Because it actually builds the code, all of it! Except that these frameworks have two sets of page template files that contribute to the "final product": 1) the list of page templates registered with the build system or VS project file, and 2) the list of files physically in the Git repo. Some build steps consider only the former, the web server considers the latter. You can remove a page from a build system, and it'll remain working. It's like removing C code from Linux and still have it turn up in the kernel! That's nuts, and a security nightmare. Cough-xv-cough.
PS: It's possible for ASP.NET Core to be configured to both compile every page on publish and support hot-reload and automatically include every file in the build if it's physically in the folder structure. This really ought to be the default, but isn't... to pander to ex-PHP devs or something.
I was sold on this too, that's why I left PHP for sexier stuff and never regained my productivity. As it turns out, most of the time I don't have a complete idea on what I'm doing but instead I have a direction and banging on it with a rock until it starts moving *in the right direction* is very productive because the design happens at the same time with the development.
My PHP code was complete "garbage" but it worked as expected and made me money and/or satisfaction of building things. Later I improved my coding skills and become much more aware of patterns and structures and found myself optimising the code instead of the product, destroying my productivity because as it turns out computers don't actually care or reward you for beautiful code. All that matter is, what that code is doing regarding the expectations of the humans who benefit from it.
Example 1:
I developed internal tools on a single server. The way I would do it was to have a personal folder on the server that I could use for development. Then I would commit the files to CVS which was the used for "deployment" to the main "production" folder. This worked well for me.
Example 2:
We also had a customer facing website where this practice was not allowed. We had proper build pipelines that created RPM packages which was installed by hand on the production machines.
My point is that there were many ways of avoiding editing the files directly in "production", even back when PHP ruled the world.
PS: I saw a developer take out an 80K user enterprise because they tried to change the look and feel of a login page live on the prod server. They didn’t know any better because they were used to editing pages in live systems. That bad habit resulted in about a million dollars of lost work.
Oops.
However due to all the shit from developers PHP slowly became a half assed copy of Java. Instead of understanding what it was.
Node is the new php
Mixing server side and front end code is bad news. I think following many PHP-MySql tutorials will result in SQL injection vulnerabilities. Not good.
The same tutorial with Django wouldn’t have the same problem because Django auto-escapes strings you dump into HTML. These vulnerabilities only exist in this tutorial because PHP treats its output as HTML by default not text, so you need to put in extra effort to be secure.
People who are new to PHP and want to learn how to use MySQL will search for “PHP MySQL tutorial” and they will find insecure garbage.
The fact that you can find good tutorials does not negate the fact that people do find terrible ones.
And we aren’t talking about an article, we’re talking about a tutorial. There’s a very big difference between the two, why are you switching? Tutorials are obviously vastly more important to beginners.
Let me remind you of the context:
> > Mixing server side and front end code is bad news. I think following many PHP-MySql tutorials will result in SQL injection vulnerabilities. Not good.
> i think you'd have to go back at least a decade to find tutorials that bad
This is something that is harming people learning PHP today, not the distant past.
> The same tutorial with Django wouldn’t have the same problem because Django auto-escapes strings you dump into HTML. These vulnerabilities only exist in this tutorial because PHP treats its output as HTML by default not text, so you need to put in extra effort to be secure.
I don't understand why you keep ruminating about Django, which is obviously irrelevant as a comparison. If you want to use Django as a point of comparison you'd need to compare with Laravel.
You wrote something about how "people" do web development in Python, I don't see the relevance to your decrepit comparison.
Everyone that starts building computer network services is dangerous for about 5-10 years regardless of what tutorial material they initially come across. If not longer, since it takes a long time to internalise the protocols, client platforms, server platforms, relevant network layers, common threat vectors, and so on.
Naturally the web frontend is written in PHP, so are the cronjobs, shell scripts, message queues, WebSocket server, client software, statistics and the server automation (think Ansible, but imperative). Sharing my own libraries between all these parts is extremely valuable. Owning the whole stack means I never have to deal with black boxes or fiddle with dependency management. The language just gets out of the way so you can solve your actual problems.
The fact that PHP is reasonably good at all these things is a big advantage. The performance is certainly good enough (never became a problem) and the long running server applications (e.g. the WebSocket servers) are rock solid.
For basically all purposes ansible is imperative.
I thought php has a per request execution model.
Hell, in PHP 5 era and before, it even HAD to, PHP had been designed as "you get a brand new process every request" and so a lot of things with memory went wrong if you ran for too long.
This changed with PHP 7, some framework appeared to allow an event based system, and then PHP 8 (or a later minor update) added fibers to the core to support it more easily.
These day, event based php has several well supported frameworks, is stable and fast, and allows you to have the same codebase on your websocket or other event system as you use on the rest of your app (sharing libraries is super cool, using the same DTO on the sender and receiver also, etc ...)
If only there were a language that was as universally deployed and well supported and extremely optimized on both server AND client, and had all of the capabilities of PHP and many more...
Because today, using an anisomorphic language that can't run on both sides is like riding a bicycle with only one leg.
Javascript's ecosystem is not anywhere that yet.
If it's a stable environment that runs old code you want, then if I had my way we'd all be programming interactive distributed network extensible web apps in PostScript instead of JavaScript, and that language has been stagnant for a much longer time than PHP has ever existed (13 years before PHP 1.0 was released in 1995), since you can still print and view all of your old PostScript documents from 1982, 42 years ago.
HyperMedia browser with embedded "applets" in PostScript:
https://donhopkins.medium.com/hyperties-discussions-from-hac...
HyperCard-like GUI builder and SimCity in PostScript:
https://donhopkins.medium.com/hyperlook-nee-hypernews-nee-go...
Visual programming language in PostScript:
https://donhopkins.medium.com/the-shape-of-psiber-space-octo...
Owen Densmore's description of John Warnock's "Linguistic Motherboard":
https://news.ycombinator.com/item?id=29295116
Owen Densmore's object oriented PostScript programming system:
https://news.ycombinator.com/item?id=18696116
Brian Reid's history of JaM, Interpress, and PostScript:
https://news.ycombinator.com/item?id=37202149
PostScript's relation to Forth, Lisp, and Smalltalk:
https://news.ycombinator.com/item?id=21968175
PostScript's relation to PDF:
https://news.ycombinator.com/item?id=37202149
Alan Kay on "Should web browsers have stuck to being document viewers?" and a discussion of Smalltalk, HyperCard, NeWS, and HyperLook:
https://donhopkins.medium.com/alan-kay-on-should-web-browser...
And you're confusing stagnant with not breaking backward compatibility and / or the entire ecosystem not changing every couple of years.
This sounds like an obfuscated way of saying that JavaScript is the only worthwhile language.
Of course you could choose to run a WASM PHP interpreter in the browser, but you be you.
Or you could petition all the browser vendors to support PHP directly. Get back to me on that when you've sorted it all out and resolved all the political and technological and economic issues, and also implemented a better framework than SvelteKit with it.
There’s little in the way of fun in the ecosystem. Not a lot of true open source in the conventional sense, lots of Microsoft MVP consultant types with blogs promoting their services. Those websites look like time capsules from 2011. You won’t find many beautiful, “handcrafted” blogs on .NET topics. A perhaps bizarre metric, but it helped me well in gauging an ecosystem’s vibe (Rust, Go, Python and others pass that vibe check, for example).
Which is actually my main reason why I shill it here on HN - please, stop picking Go for the fun technical challenges. It's an exceedingly poor choice for that and you are making yourself a fool with it because you never looked at platform implementation details and capabilities to make an informed choice.
The "higher level managed Rust" you are looking for has always been C# even more so in the last couple of years due to proper low-level abstractions and performance it offers.
> I don't know how to stop it [...] there was never any intent to write a programming language [...] I have absolutely no idea how to write a programming language [...] I just kept adding the next logical step on the way.
Having to write a bit more code because it doesn't have some feature is not ideal, but whatever. Not able to correctly race-free implement file access is a much bigger issue. I have some other gripes (which may or may not be fixed), but this was and remains my main one.
Sure, the most straightforward way is to first use the "x" flag for write-only, and "x+" for read/write access.
$fp = fopen('file.txt', 'x+');
From the PHP docs:"If the file already exists, the fopen() call will fail by returning false and generating an error of level E_WARNING. If the file does not exist, attempt to create it. This is equivalent to specifying O_EXCL|O_CREAT flags for the underlying open(2) system call."
And finally to convert E_WARNING errors to exceptions, use you can use set_error_handler() to throw an exception (and even write business logic to filter them): https://www.php.net/manual/en/language.exceptions.php
They're not unhandleable.
But if you want a single function that throws a specific exception when a file exists, specific to the behavior you want, I got you:
<?php
declare(strict_types=1);
namespace Argp242;
use function fopen as php_fopen;
function fopen(
string $filename,
string $mode,
bool $use_include_path = false,
$context = null
) {
if (file_exists($filename)) {
throw new \RuntimeException('E_EXISTS');
}
return php_fopen($filename, $mode, $use_include_path, $context);
}
To run this code from outside a namespace, simply: try {
$fp = Argp242\fopen($filename, $mode);
} catch (RuntimeException $ex) {
// Handle $ex
}
Throw it in a library somewhere, having written it once, and now you can just use that whenever you want that behavior in your PHP code.Trying to make PHP work for a job it's not suited for and failing is not a reason to hate PHP. It's a reason to ask yourself "why".
And this is not exactly a huge ask, or a very obscure function call. You can kind of work around all of this if you're careful, but it's not exactly brilliant is it? Literally every other mainstream language can do this. This is really a "only in PHP" type of thing.
Just say "yeah, this is still a downside of PHP; hopefully it will get improve one day!" Fine. Fair enough. No language is perfect and I'm not here to bash PHP. I consider this to be a major pain point, but other people do other things and maybe it's less of an issue for them. Also fine. What I don't get are these contortionist tricks – I already knew how this would go when I posted it: first there would be the "but you can do this", and then when mentioned that's not really sufficient the "yes but you don't need that anyway".
What a painful and unpleasant conversation this is turning out to be.
Finally, something we both agree on
You can, it's via `error_get_last()`. We've had that for 17 years..
If I have to deal with files, I'll create a class and I'll combine functions file_exists, is_file, is_writable, file_get_contents, file_put_contents (and new fsync) in conjunction with stream_context_create. I can even get the errors that OS spits out and test for what exactly went wrong, but you obviously ignored that and gave up. I can tell you used the language sporadically, not professionally.
You're taking a small, localized issue that arose, while your job as programmer is to get around idiosyncrasies in programming languages with the focus on achieving the end goal.
I've a list of terrible things that PHP does but I have one for JS/TypeScript/Go/Rust/<you name it>.
My job is to know these and achieve goals, not to criticize languages because file handling in it is not the same as in C++ and language didn't fire up 50 AWS instances to spam X.com with messages in hopes that I somehow notice them.
Coolio, so how do you do this?
I spent several years full-time working with PHP. I ran in to this several times. It's not a small issue. And my entire point is I can't work around it, because as near as I can tell, it just doesn't offer me the required primitives. That was certainly the case when I last looked at this, but that was a long time ago so maybe things changed?
So you end up having to choose between stable libraries in the old style or experimental modern libraries.
While some features can be retrofitted to work with old code (e.g. Java 8's SAMs were smart a way for old libraries to support the new lambdas), in a lot of situations you'll have to wait years for the stable libraries to support the new features.
Having said that, it's nice to see PHP catching up. I haven't used it in a long time, but I like to check the changelog once in a while.
Nowaday you use composer so your versionning and compatibility is done for you, everything is made out of libraries instead of monolithic bloc, and no major libraries use anything below PHP 7.X
I don't think you can find any sort-of-major library that doesn't work on PHP 8, nor anything with any kind of serious usage that isn't working on PHP 7. That's sort of the point of PHP making sure backward compatibility remains.
And if you mean "but my code can't use the good stuff", actually nothing stops it, even the type system stictness is decided caller side, specifically to avoid the issue you mention.
Can you name any PHP libraries that don't support the latest version, that you wanted to use, and held you back from upgrading?
Latest code sample is at the bottom, covers a single specific use case (DTO) and it's still old as last update is november 2022.
PHP in general has managed to had great feature while cleaning up and keeping true to its mantra of "it should be simple and easy".
Modern PHP is super fun to use, and whether you like the verbosity and completeness of symfony, the "take a shortcut around the things you don't care so you can focus on your stuff" of laravel, the event based system of swoole or similar, the microframework like slim or just raw php, it's hard not to find a shoe that fit.
What's notably funny is how they managed to do that without breaking bc, and how that is perceived highly depend on who is reading. Take switch(). The original php version of it is rather terrible in what it does in term of "programming language correctness", but it worked and had its use. At the same time, a clean one that did what was needed was really wanted.
So instead of breaking every single software out there, making wordpress and company stuck on old version forever, they added a match(), which is a bit different and much cleaner. It's not really "the broken one and the good one", as their feature is different, but it's obvious that people who look for something bad will see that as terrible. In reality, you mostly don't use switch() in new code, but its behavior is fully described and documented.
I started with php when it was still a perl script and did it professionally for 10 years after that.
PHP has experienced a 400% performance increase between 5.6 and 7, and another 20% between 7 and 8. It's fast enough for most use cases, and if you need a specialized use case, use a specialized language."
If you like to pay for servers... https://aws.amazon.com/blogs/opensource/sustainability-with-...
PHP is amazing for small and medium sized companies that just need to get stuff done.
What good is it to send ungodly time and effort when you'll most likely never ever need it?
Even your supplied link states they’re not supported at a “low level”, but states nothing about “native”.
Consider the intended purpose of the language and then consider whether the abstraction offered is appropriate. IMO in the case of PHP and UTF-8 it is not.
In my specific case it made my job harder than I would like on 2 projects I used PHP for, which is why I am complaining.
TLDR: in 2024 with PHP8 you still need mbstring extension and also you should be careful around UTF-8 if you do any text processing. In almost all other modern programming languages it's just works.
The whole concept of having special Unicode-aware strlen or substr is nonsense.
> '蛋糕'.substr(0,1)
'蛋'
> '蛋糕'.length
2
> Buffer.byteLength('蛋糕')
6
You do have to be careful when working with binary data (e.g. streams) but this is expected. > '𐐩'.substr(0, 1)
'\ud801'
> '𐐩'.length
2
[1] https://en.wikipedia.org/wiki/UTF-16#DescriptionIt just so happens that your example consists of two UTF-16 codepoints.
(Node.js' Buffer uses UTF-8 by default).
It just happened to end up that way because Rasmus Lerdorf just doesn't give a shit. ¯\_(ツ)_/¯
And I've written and maintained lots of PHP code for decades, so I know from first hand experience what its problems are, and I'm not just complaining about something I've never used. And I keep receipts.
>"We have things like protected properties. We have abstract methods. We have all this stuff that your computer science teacher told you you should be using. I don't care about this crap at all." -Rasmus Lerdorf
The point of the quote is not about abstract methods and properties, it's about a culture of not giving a shit, and being proud of it.
If you really didn't already know about Rasmus Lerdorf's anti-intellectual attitude (who admits to being "really, really bad" and a "terrible coder", but still thinks he's "better than you"), then here are some more quotes:
>"There are people who actually like programming. I don't understand why they like programming." -Rasmus Lerdorf
>"I'm not a real programmer. I throw together things until it works then I move on. The real programmers will say "Yeah it works but you're leaking memory everywhere. Perhaps we should fix that." I’ll just restart Apache every 10 requests." -Rasmus Lerdorf
>"I do care about memory leaks but I still don't find programming enjoyable." -Rasmus Lerdorf
>"I don't know how to stop it, there was never any intent to write a programming language [...] I have absolutely no idea how to write a programming language, I just kept adding the next logical step on the way." -Rasmus Lerdorf
>"I was really, really bad at writing parsers. I still am really bad at writing parsers." -Rasmus Lerdorf
>"I really don't like programming. I built this tool to program less so that I could just reuse code." -Rasmus Lerdorf
>"I actually hate programming, but I love solving problems." -Rasmus Lerdorf
>"For all the folks getting excited about my quotes. Here is another - Yes, I am a terrible coder, but I am probably still better than you :)" -Rasmus Lerdorf
https://en.wikiquote.org/wiki/Rasmus_Lerdorf
And who remembers how careless, reckless, and blithe he was with the PHP 5.3.7 release he didn't bother to test because running tests was too much of a hassle because there were already so many test failures that wading through them all to see if there were any new ones was just too much to ask of him, the leader of the widely used project, in charge of cutting releases?
>5.3.7 upgrade warning: [22-Aug-2011] Due to unfortunate issues with 5.3.7 (see bug#55439) users should postpone upgrading until 5.3.8 is released (expected in a few days).
No seriously, he's literally as careless as he claims to be (when he says that repeatedly, you should believe him!), and his lack of giving a shit about things like tests and encryption and security that are extremely important has caused actual serious security problems, like breaking crypt() by checking in sloppy buggy code that would have caused a unit test to fail, but without bothering to run the unit tests (because so many of them failed anyway, so who cares??), and then MAKING A RELEASE of PHP 5.3.7 with, OF ALL THINGS, a broken untested crypt()!
Do you think that's just his sense of humor, a self deprecating joke, breaking then releasing crypt() without testing, that's funny in some context? What context would that be? Do you just laugh and shrug it off with "Let Rasmus be Rasmus!"
https://www.reddit.com/r/programming/comments/jsudd/you_see_...
>r314434 (rasmus): Make static analyzers happy
>r315218 (stas): Unbreak crypt() (fix bug #55439) # If you want to remove static analyser messages, be my guest, but please run unit tests after
http://svn.php.net/viewvc/php/php-src/trunk/ext/standard/php...
https://plus.google.com/113641248237520845183/posts/g68d9RvR... [broken link]
>Rasmus Lerdorf
>+Lorenz H.-S. We do. See http://gcov.php.net
>You can see the code coverage, test case failures, Valgrind reports and more for each branch.
>The crypt change did trigger a test to fail, we just went a bit too fast with the release and didn't notice the failure. This is mostly because we have too many test failures which is primarily caused by us adding tests for bug reports before actually fixing the bug. I still like the practice of adding test cases for bugs and then working towards making the tests pass, however for some of these non-critical bugs that are taking a while to change we should probably switch them to XFAIL (expected fail) so they don't clutter up the test failure output and thus making it harder to spot new failures like this crypt one.
And don't even get me started about mysql_real_escape_string! It has the word "real" in it. I mean, come on, who would ever name a function "real", and why?
That implies the existence of a not-so-real mysql escape string function. Why didn't they simply FIX the gaping security hole in the not-so-real mysql escape string function, instead of maintaining one that was real that you should use, and one that was not so real that you should definitely not use, in the name of backwards compatibility?
Or were there actually people out there using the non-real mysql escape string function, and they didn't want to ruffle their feathers by forcing those people with code that had a security hole so big you could fly a space shuttle through to fix their gaping security holes?
The name of the function "mysql_real_escape_string" says all you need to know about the culture and carelessness and lack of security consciousness of the PHP community.
Melania Trump's "I REALLY DON'T CARE DO U?" nihilistic fashion statement sums up Rasmus Lerdorf's and the PHP community's attitude towards security, software quality, programming, standards, computer science, and unit tests.
¯\_(ツ)_/¯
> [...]
> The name of the function "mysql_real_escape_string" says all you need to know about the culture and carelessness and lack of security consciousness of the PHP community.
The reasoning for this boils down to historic reasons and backwards compatibility. And the naming here isn't even PHP's fault at all, so maybe rethink your rant a bit!
Correctly escaping a bind variable string in MySQL depends on the connection's character set, since a few rarely-used character sets involve more complexity with escaping. But full support for character sets wasn't added to MySQL until version 4.1, released 20 years ago in 2004.
So prior to that, in the MySQL C client API, you could safely escape strings using the mysql_escape_string C function. But after connection-level character sets were added, this was no longer sufficient. And you can't change the function signature in a widely-used C library without breaking all prior users of the library. So the MySQL C client API introduced mysql_real_escape_string to solve this, which takes a connection pointer as its first parameter, and then deprecated the old mysql_escape_string at the same time.
So then PHP added their mysql_real_escape_string to match this, and deprecated the old mysql_escape_string, but did not remove it because it would break all old programs. And at the time two decades ago, this actually made sense! Many of those old programs were still using pre-4.1 MySQL (since 4.1 was still brand new), in which case the old mysql_escape_string was still perfectly secure, since connections didn't have character sets.
Today it's clear that both PHP and MySQL should have acted more aggressively to remove the deprecated connectionless mysql_escape_string shortly after this all happened. But from my memory, the industry's views on security vs backwards compatibility were quite different 20 years ago than they are today.
After further reflection, some of the fine details in my comment above may be off. I vaguely remember MySQL having a single server-wide (I believe?) configurable charset option before MySQL 4.1, so it's likely the MySQL C client library API gained mysql_real_escape_string earlier than 4.1.
Anyway though the broad point remains -- PHP didn't pick the "real_" naming, MySQL did; and the reason for MySQL's API there makes more sense in the historical context of expanding charset support, and needing a different C function signature to accept a connection arg.
And fwiw I do agree that "real" is a rather poor choice for this sort of API naming, but I assume the MySQL folks just went with that to avoid an excessively-long function name... also the developers of MySQL weren't native English speakers. Anyway, hindsight is 20/20 and all that.
It has existed approximately forever, in this form:
list($username, $domain) = explode("@", $email);It has a rather nice interactive shell, https://psysh.org/ . I've built non-trivial, non-web systems in it.
Concurrency 'within' the language isn't as nice as some alternatives, but the FCGI-style deployment is quite reliable and convenient in practice.
This article is a little short on explanations or examples, though, so it’s hard to even really know what a lot of this is about, but it sounds mostly like syntax refinements and a few new language features. Which is great. Between that and the performance improvements, I’m glad to hear that PHP is still alive and well.
All that said, my memory of why PHP got such a bad rep was not so much the language itself, but the truly dangerous defaults, magically populated variables and more, that were so embedded into the usage of the language that for years, the maintainers were reluctant to make the necessary breaking changes to address the risks. Those issues drove far more people away—to the emerging frameworks like Rails and Django or all the way to Java or .NET—than the lack of named parameters or the need for the ‘array’ keyword.
Instead of a PHP developer many are now calling themselves a Laravel developer because the framework is all they know.
It’s just me, my text editor and an FTP client.
When I hear people expressing that PHP "sucks", that's mostly coupled to the ecosystem, not necessarily the language itself. Yes, the biggest warts in the language might be non-issues now if you write 100% of your code yourself, but the ecosystem is the same as it ever was.
PHPs utilitarianism is its biggest strength but also its biggest weakness when it comes to its libraries. Packagist is mostly a graveyard of libraries that people have coded up for their exact niche use-case 8 years ago (with no updates since), with little flexiblity beyond that (like you would see for libraries in other ecosystems).
The popular frameworks (mainly the CMSs, but also some of the MVC ones) suffer from a similar fate: Great if you want to hack something up quickly or do a small extension to it, but full of footguns and lacking in developer tooling.
> if you write 100% of your code yourself
The only way I was able to tolerate it is by carving out my own little world, and being very conservative with any external dependencies. Come to think of it, this approach has worked well for me with other languages but not to this extreme where I consider it a hostile environment.
Sophistry about how my solution won't scale to a million users per day or I should have used their framework from the start rather than having a bunch of HTML files won't matter to me nor the <10k people I expect on my website. In many cases, modern languages and frameworks drive adoption for themselves by tricking you into solving a problem that is not actually the problem you have, but they happen to be adapted to.
Could you provide some examples? I wrote a lot of PHP libraries over the years, and while some are definitely stale because nobody uses them (and thus I have no incentive to keep the lights on), the only time I see dead packages, they're actually forks of other open source software that people contributed exactly one commit to (to change the package name).
All the PHP projects I've seen, eventually failed and had to be rewritten in another language. It was impossible to add new features and fix bugs in such a code. For example, if the original code uses copy paste instead of functions (and it is very often the case for PHP code), you'd have to fix every bug 3-5 times (most of the time, you fix it in one place and only after deployment realize, that the bug still manifests itself in 2-4 other places).
Yeah, maybe PHP is very easy to write and deploy, but this simplicity somehow makes bad programmer out of the person writing in PHP. I know, it's very subjective, but I had such a negative experience that I gave myself a promise to avoid PHP related jobs at all costs.
Also, maybe it was slightly more difficult to use other languages for web development 20 years ago. You'd have to use CGI, or set up some mod_python with all of its quirks, but those times are long gone. It's almost as easy now to develop/deploy Web apps in any other language.
Laravel’s collections fix my syntactic issues with PHP arrays.
My only complaint is that type checking is performed at runtime, so if you forget to mark a field as optional you get a type error even if you account for the nullref in your code.
...and PHP still kinda sucked. Maybe it has improved between 2021 (when I last committed to that new project) and 2024, but I'm skeptical.
It was a huge disappointment to me because I really want PHP to be nice. PHP was the second language I learned for bigger projects after Perl, so some part of it still feels like home and evokes a beautiful naive feeling towards programming in me.
Alas, I'm unlikely to try it again in the next decade. I suspect it's slowly catching up to other languages, but at this rate I think more than a few years are needed until parity.
Can you elaborate?
Build an application in Python, then as soon as it becomes pushed by load you're going to need a rewrite. A few small load balancers and virtual web servers doing PHP can handle tens of thousands of requests per second, the database is almost guaranteed to be the bottleneck.
Python is a (according to some) nicer bash, it's not a good alternative for implementing non-trivial systems and web services.
Python took some getting used to, but the more I used it the more strongly I began preferring its lack of things like curly braces, semicolons, even parenthesis in some cases. Because of that, python feels more concise, human-readable, and more efficient to write, than PHP.
I like both languages, and still rely on PHP for a lot of web work, but for data science or ML I do end up enjoying my time with python.
Right, Python has a purpose as a glue language.
I'm more interested in your claim about "usable for any application". How come all those fancy ML types and learned academics refuse to use Python for the core computations they perform when they try to invent witchcrafts, instead opting for C, C++ and Fortran libraries?
Sometimes the algolians are called general-purpose programming languages, as opposed to SQL, functional programming languages, logic programming, and so on. Sometimes anything it's used as an opposite to domain-specific languages.
Yes, PHP 3 sucked, but PHP 4 is good now!
Yes, PHP 4 sucked, but PHP 5 is good now!
Yes, PHP 5.0 sucked, but PHP 5.3 is good now!
Yes, PHP 5.3 sucked, but PHP 5.5 is good now!
Let’s not talk about PHP 6!
Yes, PHP 5 sucked, but PHP 7 is good now!
Every so often I have to deal with some PHP code, and every time I see that, no, it’s still just the boy who cried wolf. It seems like PHP fans are all too happy to agree with the people saying PHP sucks… as long as it’s not the latest version. And suddenly they can see that version’s faults… as soon as a new version is released that they can tell people doesn’t suck. Maybe if PHP fans hadn’t spent the last two decades telling people PHP didn’t suck when it most obviously did, people would be more inclined to listen today.
It surface seems productive and shiny and for 90% of use-cases you get the job done quickly. But for those other 10% you realize that at its center lies a rotten heart, wired together with duct tape. Syntax is not the problem. Horrendous stdlib and IO interop is what keeps it a mess.
Once you try to do anything more sophisticated you realize its many sharp angles which don't make sense. Such as call-by-reference only working 2 recursions deep. Silently failing when opening files which are too large. Arbitrary decisions and namings on stdlib. The hassle of debugging your program.
Or an ongoing struggle in my old company: Wanting to set up old PHP projects and realizing that your package manager doesn't have them anymore.
PHP is a ticking time bomb.
When it coems to running different PHP versions, modern PHP development has largely moved to using Docker (ddev, for example: https://ddev.com/) for that, and there's plenty Docker images for old PHP versions so it's a non-issue. I'd also imagine it be difficult to get many other outdated programming languages via a package manager.
There's now the PHP Foundation, which while relatively new in its formation, has significantly boosted PHP development and I'd recommend donating if improving the language is important to you.
Java & Maven is extremely stable. It is the exception rather than the rule that something doesn’t build anymore.
> I'd recommend donating if improving the language is important to you.
It's not (-:
Which smells like an anti-pattern to me. Blaming bad code on the language is one way to deal with it.
> Arbitrary decisions and namings on stdlib.
This is absolutely true and even more annoying I find that the ordering of stdlib arguments is inconsistent. Backwards-compatibility is one of the reasons this has not changed, I guess.
What I don't understand is, why people don't apply that same legitimate criticism to python. I recently had to do a project in python and was astounded by the amount of arbitrary namings and design choices.
I also agree that many php codebases, especially if not written in a good framework, are a hot mess.
That being said, the ecosystem if using decent frameworks with php 8+ versions very productive in terms of time vs results and a joy to work with.
I absolutely do. I appreciate the PHP community for having expertise in actually creating sane tools attempting to do a good job. But Python is just batshit crazy with some of the most wild bugs I have seen and no guardrails whatsoever.
Out of all the languages which got a type-system after the fact, PHP is the best one hands down. Runtime-validation of types + non-null by default keeps some of the bad stuff inside Pandora's box.
> Which smells like an anti-pattern to me. Blaming bad code on the language is one way to deal with it.
It was a simple recursive algorithm which we used to make some custom-highlighting on a few select words (much easier to understand than an equivalent iterative approach). But I wasted a good day until I saw that there was a technological limitation which made the algorithm fall apart, and not the logic itself. That's a quite offputting smell.
Of course I understand the economic choice behind PHP... finding PHP programmers is cheaper than going C# or Java. But having a good background in parallelism and having a good grasp on efficient CPU/JVM usage PHP doesn't provide anything unique. Everything it provides, I can achieve equally fast in other established languages, while posing an actual problem when technological limits are reached.
That said last time I used it was ~2007 and I don’t plan to come back.
What a close-minded and weird comparison.
And PHP isn't just Wordpress.
exactly - if I have to build a docker image anyway the deployment advantage of php is completely wiped out.