Rendered at 16:17:01 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
mfonda 1 days ago [-]
After over two decades of working in PHP, I'm now working in Java. PHP is basically Java-lite. I am absolutely loving the compile-time safety of Java, but I dearly miss PHP's maps and arrays. In Java, the amount of verbosity for defining a map/list and operating on it is overwhelming.
Modern PHP is great. Many powerful language features, excellent performance, great community and package ecosystem, and decent enough safety with modern static analysis tools.
I'm not too sure I agree with the author's complaints here. When using something like array_filter, you're typically mapping from collection to collection (i.e. you don't care about the first element--you care about the whole thing) and so this problem is really a non-issue. The next follow up step would usually be foreach, or another operation like array_map, in which case it's a non-issue.
If you really do need the first element, you can use array_first. And if you really do need a fixed-sized collection, you can use SplFixedArray.
The point on properties is valid to an extent, but IMO not really an issue you commonly run into in the real world (regardless of language, your constructors should generally return an object in a usable state).
somat 16 hours ago [-]
Maps should be a first class type in every language.
I have this thing I want to do in C. Now my C is very weak so my plan was to do a prototype in python, keeping in mind the C ecosystem then sit down with my old copy of "The C Programming Language" and struggle through it. Doing it with no dicts was rough.
I am normally the sort to avoid adding any libraries I don't have to but if anyone has any hints to simple hash maps in C I am all ears.
thayne 9 hours ago [-]
My first recommendation is don't use C if you can avoid it. Rust, go, zig, nim, odin, c++ etc. have hashmaps built in to the standar library or the language itself, and will have other advantages over c as well.
If for some reason you absolutely need to use c, consider if you really need a hashmap. If your collection is relatively small, just use an array or linked list with linear search. That's a pattern I've seen used in several c codebases, I think because of the difficulty of using map types.
If linear search would be too slow, then a binary search tree is relatively easy to implement, and gives you log(n) lookup time (as long as it's balanced). Or if you build it up once and don't modify it very much afterwards, you can use a sorted array, with a binary search.
If you really need a hashmap, there are some implementations, but I've also seen a few c projects that just implement their own hashmaps.
My suggestions, none of which are particularly simple but it's C, you get what you get with a language that doesn't even know what strings and arrays are:
0) use Lua with LuaJIT. It has very good C interop and native hashmaps. Downside - Lua has its own rough edges and LuaJIT is frozen at Lua 5.1 with some extensions for 5,2
1) SDL3 has a hashmap implementation with its properties API, and a general purpose hashmap that they're probably going to make public at some point maybe? Downside - overkill if you don't actually want to use the rest of the library.
2) https://github.com/tidwall/hashmap.c this seems to work fine and is the simplest hashmap implementation for C that I've seen. Downside - you still have to write a lot of boilerplate.
nirui 15 hours ago [-]
If I remember it correctly, the "Java-lite" part comes rather late. PHP was more close to Perl and/or other old-days scripting language, it allows you to quickly launch a web page. Just
and you get a hello page with a parameter specifiable via `?user=` query.
But then people started to actually use it to build big sites, `echo($_GET['user'])` alone is not enough, it has to be:
<?php
$user = "guest";
if (!empty($_GET['user'])) { // Have to remember to do this check everytime when handling $_GET/$_POST etc
... safety check etc etc
$user = htmlspecialchars($_GET['user'], ...more parameters...);
}
...
So people started to add module/components as well as ways to load and use those components, to enable them to write code like:
<?php
use My\Beautiful\InputFilter;
use My\Beautiful\InputFilters\Integer;
function get_page_num_from_query(InputFilter $f, array $source, string $name): bool {
return $f->is_valid(new Integer(0, 100), $source, $name);
} // Or something like that, hasn't write a single line since PHP5.
That's when it got it's Java look.
hparadiz 15 hours ago [-]
Namespaces were added long after that step.
DonHopkins 9 hours ago [-]
>That's when it got it's Java look.
Nice Java burn! But now days all you have to say to burn Java is "Lawnmower".
mdavid626 24 hours ago [-]
If I have an “array” and can do array[0] to get first item, but when I filter this array and array[0] throws an error, that’s super weird. What is the meaning of [] or what is an array even? The language forces me to understand how it is implemented under the hood. That’s exactly what the author says: leaky abstraction.
kro 19 hours ago [-]
That also often shoots you as when json_encoding it only becomes an array when ordered "correctly" (numeric 0-based keys without gaps), otherwise an object. So to be safe you generally need to array_values after filtering.
If in your testdata you only remove elements from the end you don't catch that before production data hits.
To get the first element there also is reset().
I love PHP though.
mfonda 23 hours ago [-]
An “array” in PHP is an ordered map.
pavel_lishin 22 hours ago [-]
Isn't exactly their complaint? It's called an array, referred to consistently everywhere as an array, but it just ... isn't.
yegle 17 hours ago [-]
Apparently array is short for associated array:-)
hparadiz 15 hours ago [-]
In PHP the array index supports different key types and there's various optimizations that need to happen when the indexes are all numeric, mixed, or all strings or anything else. Technically it's called associative as soon as even one of the indexes isn't numeric. Internally though they are always numeric and anything non integer is hashed internally with DJB2 (Daniel J. Bernstein) hash algorithm and then stored. Using a non numeric index is slightly slower for that reason.
thayne 9 hours ago [-]
But even if you only have numeric keys, those keys don't need to be consecutive, or start at 0.
15 hours ago [-]
postalrat 19 hours ago [-]
Better than calling it a hash.
pavel_lishin 18 hours ago [-]
I don't think it is, tbh.
Perl's hashes are a complete mystery to me still, but at least it lets me know that it's not just a linear, uh, well, array.
duskwuff 17 hours ago [-]
> Perl's hashes are a complete mystery to me still
They're unordered mappings from strings to arbitrary values ("scalars" in Perl jargon). In this sense they're just like an object in JavaScript.
Where this gets a little weird is that Perl arrays and hashes are fundamental types distinct from scalars - you can't put a hash into a $variable without taking a reference to it first, for instance. But that's more a matter of Perl being picker about the value/reference distinction than a hash-specific thing.
johannes1234321 11 hours ago [-]
PHP arrays are vectors, hash maps and doubly linked lists in one
egeozcan 11 hours ago [-]
> If you really do need the first element, you can use array_first
That probably needs an array_second too, doesn't it? Maybe array_second_from_last as well?
pavel_lishin 1 hours ago [-]
That's foolish. It would clearly be named `second_array_element`.
larsnystrom 9 hours ago [-]
Just use array_values() and suddenly you can use int indicies again.
kaptainscarlet 20 hours ago [-]
Php has compile time safety too but compile time occurs at roughly the same time as runtime lol
blanched 20 hours ago [-]
I'm not familiar with PHP, can you elaborate on what you mean here? What is it compiling? Or are you referring to type safety?
yurishimo 18 hours ago [-]
When a php file is loaded at runtime, it runs through a very basic JIT compiler that does statically check a few things before continuing with execution. Syntax, for example, is checked for the entire file during this step.
Most type checking happens at runtime (this might not be true for interfaces at some level, but I can’t say for 100% certain - I just know I tend to see interface related errors earlier during code execution…). It’s perfectly valid syntax to declare a private method as returning an integer and then for the body of the method to return a string (explicitly cast as a string even). As long as you never call that method at runtime, no exceptions will be thrown.
With a half decent IDE or LSP, these sorts of runtime exceptions can be easily avoided but technically they still exist and if you don’t know about that, it can be argued to be confusing. PHP has made a lot of trade-offs to largely maintain backwards compatibility and many of them live in decisions that happen at runtime.
Modern PHP tooling can provide type safety in a very similar way to Typescript if you’re willing to put in the effort while also still technically offering you an escape hatch to do whatever the heck you want and duck type to your hearts content.
chuckadams 16 hours ago [-]
One form of type checking does happen at compile time (which is really load time in PHP, but close enough), namely when a class extends another class or implements an interface: the types of every method and property are checked to ensure that they are substitutable per the standard variance rules (return types are covariant, parameters are contravariant, props are invariant). Everything else is checked at runtime though, and statically analyzing any of those is left to external tools like phpstan, psalm, or mago.
DonHopkins 9 hours ago [-]
NIT linter warning: That’s not really a JIT compiler.
PHP parses the whole file and compiles it to Zend opcodes before executing it, so syntax errors are caught up front. But "JIT" means compiling an intermediate representation/opcodes into native machine code at runtime, when the functions are called, not at load time when the source file is parsed. If you just load a file and never call any of its code, the JIT compiler should never compile it.
PHP 8's OPcache JIT can do that optionally, but the normal load/parse/compile-to-opcodes step isn't JIT.
flossly 18 hours ago [-]
Have you tried Kotlin? It's a less clunky Java. The syntax is IMHO Ruby-level charming (for an OO-first lang), but with types that are quite a bit stronger than Java. Java interop is quite smooth.
pdpi 15 hours ago [-]
The comparison with Ruby is spot on.
I always thought that DSLs were the one thing Ruby did better than the competition, but Kotlin's combination of receiver lambdas plus syntactic sugar for calling higher-order functions make it an even better language to write DSLs in.
flossly 8 hours ago [-]
That's exactly how i feel about it.
And the code I'm looking at now with Kotlin is so similar to code i liked reading when I was in a committed relationship with Ruby.
Onavo 22 hours ago [-]
Have you tried Lua or one of its variants?
lofaszvanitt 21 hours ago [-]
All PHP needs is python's flexible and convenient manipulation of lists/dicts/objects. Plus dropping the end semi colon and it would riiiiiiiiiiiiiiiip the fabric of spacetime.
dalemhurley 20 hours ago [-]
The semi colon allows you to have lots of flexibility in how you present your code, that is if you still read code, I seem to be an oddity now.
chuckadams 16 hours ago [-]
I'd really like it if PHP switched to Perl's grammar rule where semicolon is a statement separator rather than a terminator. It already does this in a fashion within <?php ?> tags in that statements in those don't have to end with a semicolon. I think it just blindly inserts a semicolon, but that does work -- if PHP did that whenever it saw a `}` token, it should have the same effect.
calvinmorrison 20 hours ago [-]
yes I say this now very often, that PHP has morphed into runtime Java. Quite nice in some ways.
In PHP though the STDlib is not very well thought out, it may be fun(needle,haystack) or fun(haystack,needle) and you just have to remember
empty() will do weird stuff like a string with the value "0" is also empty, so not great for parsing things.
A lot of footguns and the best way to avoid that is with a decent linter that lets you be picky
another thing I mention is avoiding the array_ stuff because of aformentioned reasons, it's easier to remember/reason about boring loops unfortunately.
9dev 19 hours ago [-]
Why not just use a proper code editor with inlay hints, inline documentation, and autocompletion instead? These things are a non-issue, unless you’re working with Notepad++ or something.
hparadiz 15 hours ago [-]
Yea VSCode or Eclipse does this.
dalemhurley 20 hours ago [-]
I have worked with countless programming languages and they all have little oddities.
shevy-java 24 hours ago [-]
> Modern PHP is great. Many powerful language features, excellent performance, great community and package ecosystem
I heard this a long time ago about perl. CPAN is great.
Well ... perl entered the fossilized era. I think people do not really observe things correctly. I am noticing the same with ruby right now - everyone sees that ruby is in decline, very strongly so, in the last 3 years. Yet you have blog posts such as "ruby is not dying - it is aging like fine wine". And these are all NOT BASED ON FACTUAL ANALYSIS. I still think ruby is a great language, but if people are not realistic in their assessment of a situation, what does this tell us about people's evaluation in general? People seem to shy away from criticism. You can see this on reddit too, where moderators ban and censor willy-nilly, or even on github, where you can also quickly get eliminated for not conforming to xyz. It's as if some people are very afraid of strong opinions. I don't understand why - an opinion that is objectively false, can be shown to be false.
chamomeal 23 hours ago [-]
People absolutely have VERY strong opinions and voice them constantly. True of every language but especially php. Almost feel like it’s more acceptable to rant about php than to praise it
susam 23 hours ago [-]
I attended a talk by Rasmus Lerdorf at a FOSS conference in 2006. It has been a long time, so I remember only a few things from the talk, but one thing I remember him talking about is how people love to complain about PHP, often on forums that are themselves written in PHP.
chuckadams 16 hours ago [-]
#include <stdstroustrupquote>
Rasmus also admits that he didn't really know what he was doing when he created PHP, and that it's a bit surprising that PHP has stayed as compatible as it has. I kind of respect him more for that than I once used to.
No, in 2006 it was still considered poor form to reply with a low-effort meme phrase instead of meaningfully criticizing his position with your own.
comex 15 hours ago [-]
Depends entirely on the forum.
I remember it being somewhat common for people to make forum posts consisting entirely of a joke image. However, they weren’t called memes at the time as the word had yet to be popularized.
hluska 14 hours ago [-]
It was not correct to interrupt a talk with a meme and it never has been.
DonHopkins 9 hours ago [-]
But it's always been correct to interrupt a discussion on a PHP forum about PHP security by breaking into Rasmus's account and posting an ironic meme under his name.
unethical_ban 21 hours ago [-]
I know I used to have the impression of PHP as a messy language because I last worked with PHP4. It's come a long way since then, though I don't use it.
xp84 23 hours ago [-]
> objectively
> Ruby is dying
How exactly do you define these “objective” criteria for such sensationalism?
greybeard69 24 hours ago [-]
Mate, not to be rude but your entire comment isn't based on factual analysis; it's a rant about unrelated languages.
23 hours ago [-]
customguy 24 hours ago [-]
> People seem to shy away from criticism.
What actual criticism of PHP is anyone shying away from?
PHP got bashed for such a long time, while simply nothing steps up to do what it does better. Something that, for example, is available on every webhost you can just throw files at, where all (meaningful) config and state can be in those files.
xp84 23 hours ago [-]
I used to really love the dead-simple ease PHP brought to server-side dynamic web stuff too. But when shared cpanel type hosting was orders of magnitude cheaper than anything else, that was a way bigger deal. Today you can deploy a node.js app (all the same “just a script” advantages of PHP) to a half dozen places for free, and for the next step up, a smallish instance at Hetzner, DigitalOcean or whatever, where you can just run any arbitrary container, costs less than those shared hosting once did.
Why do I bring up containers? Because part of why PHP was so dope in this way was the way you can just define 1 file per endpoint and drop it in public_html, and have no server setup to do. Running say, Rails or ASP.NET or a Java site back then meant doing… a lot more, to your server.
But with Docker, you can just steal a good Dockerfile template from someone else, and it’s just like 3-4 simple files for you to manage for a simple Sinatra (Ruby) or node.js version of the “one-off PHP file” things.
customguy 22 hours ago [-]
But I don't want to manage 3-4 files, I want to manage zero files. I don't want half a dozen hosts, I want hundreds of thousands. It's not about costs, I really mean the simplicity and pervasiveness. PHP apps that are simple (in that they don't require any "rare" modules to be enabled) can easily be written to not run in relative folder structures, you can move them around like .exe files if you will. Not "like moving an exe file and then just updating a few lines in this file over there", that is a completely different thing for me.
edit: Granted, I agree that if you want to do all sorts of things on the internet, maybe PHP is not the right choice. But for simple, dynamic web things that I want to just make and then run like this forever, that I can work on but don't have to? PHP and vanilla HTML and Javascript are where it's at for me, hands down. Everything else I know is either too new or seems to have constant churn or issues. That you hear nothing about PHP other than complaining it's "outdated" or whatever from the outside -- always "why are you using this?" never "why oh why am I using this?" -- is because it just hums along, IMO. I like it better than Python, and I kinda view it as in that class.
mschuster91 19 hours ago [-]
> Today you can deploy a node.js app (all the same “just a script” advantages of PHP)
You still need to build a router and a web server in said nodejs script. And manage everything, including taking care that requests don't accidentally mutate global state.
PHP in contrast is stateless. Way less bs to take care about.
Pay08 21 hours ago [-]
I've always thought that the core idea of PHP, the intermixing of code and HTML is an incredibly elegant solution to a very difficult problem. But at the same time, the language itself does suck (although I won't discount the improvements it has made). I would really love for there to be an entirely reimagined PHP from the ground up, and to hell with backwards compatibility or availability.
customguy 16 hours ago [-]
> I would really love for there to be an entirely reimagined PHP from the ground up, and to hell with backwards compatibility or availability.
I'm halfway onboard :) That is, personally I do like that PHP is kinda "boring", it's just a programming language that mostly looks like other curly brace languages that can basically do anything I ever need to do with strings out of the box. And I like that PHP, while also adopting more advanced programming concepts, stays nice with all the simple stuff. I like the stewardship, you might say, although I don't pay any attention to it. New PHP versions always either have things I don't understand, don't care about, or really like. The performance goes steadily into the correct direction, too.
I'm sure people who know more about programming and the version history will disagree about something, but for my "low-tech" usage, it's actually one of the few happy places of computing. Not happy as in exciting, more like working in a modeset garden, without stuff blowing up constantly, and salesmen posing as flowers.
But I still would love to see and try out "takes" on that, or on what other people like about it. At least to start with, I guess it would just need to be be somewhat painless to use with with Apache, NGINX, or come with a webserver built-in. Then people can use that locally and on servers they fully control, and if it's really good, and really good with resources, basically a painless additional thing to add, web hosts might adopt it etc.
krapp 21 hours ago [-]
There was. It was called Hack[0]. Among other things it had XHP built in so you could write HTML natively (as opposed to concatenating strings) and define your own templates easily[0]. It even handled escaping. It really improved on a ton of PHP's flaws.
Unfortunately newer versions of PHP killed it and it's dead now, and even more unfortunately while PHP absorbed a lot of features from Hack, native XML was not one of them. There was even going to be a Hack version of the Composer package manager but that never got finished AFAIK. Distros stopped supporting it. I think I still have my half-finished attempt at a Hacker News fork in Hack sitting around on a hard drive somewhere. I can't even find an environment to run it in anymore.
XHP was a modified PHP before Hack came about, but only Hack supports it now. XHP did have a longer reach though: JSX is its direct descendant.
krapp 15 hours ago [-]
Making it an extension rather than default was a mistake on PHP's part. 99% of PHP is being run on shared servers and most people cant recompile it, and most of the rest just won't.
Having a language whose entire purpose is to be a templating language for HTML have no concept of what HTML is, is just ridiculous. You have to use a templating framework that rolls its own ad-hoc DSL and parser to manage context just to make PHP do what it should be able to do safely and sanely out of the box.
It doesn't matter now, since "web dev" is whatever JS vibe-coded nonsense Claude shits out and no one cares anymore, but ye gods it could have been so much better.
chuckadams 15 hours ago [-]
It was never any kind of official extension, it was an outright fork of PHP (it changed the grammar) and FB never really attempted to push it to core, or really engage with PHP's core dev process in any way. PHP came about in the era of server-side includes, and expecting it to have grokked the DOM structure out of the box is just hindsight.
Anyway, I don't even think about server-side rendering anymore, and for the last few days have had Claude "shitting out" Vue components that replace legacy Bootstrap 3 components with html5 alternatives for my PHP app to use via Inertia.js. The axe-grinding is not helpful to either of us.
hparadiz 15 hours ago [-]
Lol to true. Who even uses twig or smarty anymore hesitantly raises hand
DonHopkins 8 hours ago [-]
I have a client I've been working with for decades (because they're great people to work with), maintaining and improving their php code base that still uses Smarty templates. So I know and hate Smarty from first hand experience, and appreciate what a terrible idea Smarty is and why.
I've also extensively used Zope and Plone, which attempt to give designers a "safe" set of capabilities and subset of Python which was a total disaster. Template DSLs always end up trying to regrow programming language features, much usually worse then the languages they are implemented in.
Zope is particularly illustrative because it recursively accumulated: TAL, METAL, TALES, RestrictedPython, and DTML: all to avoid "just use Python templates". (And don't even get me started on all the layers CMF and Plone introduced!)
This happened with Smarty, Zope Page Templates (ZPT), TAL/METAL, RestrictedPython, Django templates, Helm templates, Jenkins pipelines, GitHub Actions YAML, Terraform HCL, and countless other attempts to create a "safe non-programmer-friendly mini-language" that eventually mutates into a worse programming language, often with horribly leaky abstraction layers of \escaping and < perfect syntax and <![CDATA[ cruft.
I Wanna Be <![CDATA[ (Sung to the tune of "I Wanna Be Sedated", with apologies to The Ramones):
This attitude causes disasters like PHP's "Smarty" templating language.
PHP was already a templating language, but somebody got it in their head that there should be an iron-clad separation between designers and programmers, and that PHP gave designers too much power and confused them, and that their incompetent untrustworthy designers who refused to learn anything about programming deserved something even "simpler" than PHP, so they came up with Smarty.
Then over time the realized that their designers were powerless, so their programmers would have to learn TWO languages so they could wade into the Smarty templates to make them actually work with all the extra code they had to write because Smarty was so crippled, so they nickle-and-dimed more and more incoherent programming language elements into Smarty, making it EVEN HARDER to use and more complicated and less consistent than PHP, yet nowhere near as powerful.
DonHopkins on Aug 19, 2019 | parent | context | favorite | on: YAML: Probably not so great after all
One of the most ridiculous examples of this was the Smarty templating language for PHP.
Somebody got the silly idea in their head of implementing a templating language in PHP, even though PHP is ALREADY a templating language. So they took out all the useful features of PHP, then stuck a few of them back in with even goofier inconsistent hard-to-learn syntax, in a way that required a code generation step, and made templates absolutely impossible to debug.
So in the end your template programmers need to know something just as difficult as PHP itself, yet even more esoteric and less well documented, and it doesn't even end up saving PHP programmers any time, either.
>Most people would argue, that Smarty is a good solution for templating. I really can’t see any valid reasons, that that is so. Specially since “Templating” and “Language” should never be in the same statement. Let alone one word after another. People are telling me, that Smarty is “better for designers, since they don’t need to learn PHP!”. Wait. What? You’re not learning one programming language, but you’re learning some other? What’s the point in that, anyway? Do us all a favour, and just think the next time you issue that statement, okay?
>I think the Broken Windows theory applies here. PHP is such a load of crap, right down to the standard library, that it creates a culture where it's acceptable to write horrible code. The bugs and security holes are so common, it doesn't seem so important to keep everything in order and audited. Fixes get applied wholesale, with monstrosities like magic quotes. It's like a shoot-first-ask-questions-later policing policy -- sure some apps get messed up, but maybe you catch a few attacks in the process. It's what happened when the language designers gave up. Maybe with PHP 5 they are trying to clean up the neighborhood, but that doesn't change the fact when you program in PHP you are programming in a dump.
6 hours ago [-]
krapp 14 hours ago [-]
> PHP came about in the era of server-side includes, and expecting it to have grokked the DOM structure out of the box is just hindsight.
Obviously not from the beginning. But by the time template frameworks like Twig came around it should have been possible. If it can be done at runtime it's possible to build into the language proper. And I'm specifically talking about the time when PHP 7 started taking other features from Hack.
I'm not grinding an axe here, i'm just stating an opinion.
DonHopkins 8 hours ago [-]
I've seen the PHP Hammer, and I'd hate to see a PHP Axe: it's probably all dull blades, no handle!
You can say the same thing about lisp (and C in some regards). Sometimes a language is done and anything you add to it is breaking things for no sizable improvement. And if your primary target is Unix, it’s often so easy to write a shim for C/C++ libraries that you don’t bother implementing your own version of stuff.
Pay08 21 hours ago [-]
Which lisp? :P
FDETalkDotCom 11 hours ago [-]
PHP is bananas kinds of awesome.
Yesterday, Cursor coughed up https://fdedictionary.com for me in PHP. You know what, it is like a dozen files and works awesome, no daemon needed, basically just a web server, some PHP files, and one SQLite file.
Today, Claude Code, the major hotness, made changes to a (different) toy app with less complexity, in node.js and you know what, it has ~49,000 files. And uses a 3rd party SaaS to host the db, and another 3rd party SaaS to do auth, and yet another 3rd party SaaS to import a repo and do deployments and hosting.
Simplicity has a place for some things. I love PHP+SQLite for tiny apps, and LLMs/agents are awesome at it.
I forgot, ChatGPT one-shotted the PHP app and Cursor put the finishing touches on. What a world. Long live PHP, is the point. Arrays and all.
sandreas 10 hours ago [-]
For Toy Apps you can even use PHP's integrated WebServer like
php -S 0.0.0.0:8000 public/index.php
It's not for production use, but only needing one Tool can be helpful under specific circumstances.
moebrowne 9 hours ago [-]
Also set PHP_CLI_SERVER_WORKERS=10 to enable multiple threads
chuckadams 24 hours ago [-]
> This lax behaviour for property definitions makes writing code around them harder. Especially when you take into account that any object can have properties dynamically added to them:
Doing so now raises a deprecation warning, unless you add #[AllowDynamicProperties], and PHP 9 will convert it to an error. I'm told this will simplify internals and unlock optimizations.
Arrays are still fairly awful, but generics may become a reality sooner rather than later, and on that could be built Vec and Dict types, à la Hack. PHP is going to be stuck with arrays as they are now for forever, but they'll at least become optional for new code.
Yokohiii 16 hours ago [-]
Not sure why a language that barely has a type system needs generics.
chuckadams 6 hours ago [-]
PHP has had a type system for over a decade now, including things like union and intersection types that are still not in Java. Most static checking still needs an external analyzer, but even without one, PHP does check subclasses and interface implementations for Liskov substitutability in a way that Python does not.
larsnystrom 22 hours ago [-]
I've been writing PHP for 20 years now. It's my bread and butter.
The one thing I really wish PHP would add is structurally typed objects. I really miss it when moving back and forth between PHP and TypeScript.
They could call them anonymous objects if they want to (that would be a more culturally correct analogue to anonymous classes).
Like, I wish it was possible to do
{
string $mystring = $myvar,
}
and have it be equivalent to
new class($myvar) {
public function __construct(
readonly public string $mystring,
) {}
}
and then be able to typehint it like
function ({ string $mystring } $myobj) {
echo $myobj->mystring;
}
and honestly, why not go all the way and allow type definitions/aliases, something like
type myobj_type = { string $mystring };
That'd be great.
idoubtit 21 hours ago [-]
You can do that. Of course, PHP's native types are quite limited, but a phpdoc syntax should work with static analysis tools. For instance:
It may work in your IDE (autocompletion, etc.) but there is no standard on this side. Some IDE have their own parsers, others use one of the LSPs for PHP.
larsnystrom 21 hours ago [-]
Yeah, at the moment we use arrays as anonymous objects and phpdoc+phpstan to verify the types, but I want it in the language. PHP already supports intersection and union types, it really feels like just skipping the naming part and going all in on structural typing is not that far fetched by now.
Ayesh 24 hours ago [-]
PHP has quite a lot of oddities such as how loose comparisons (`==`) are made, numeric-strings, and type coercion. But the two oddities mentioned in the article are not that "odd" with a bit of context.
- PHP has `SplFixedArray`[^1] that work similar to the standard arrays you expect from other languages. SPL extension is always available in PHP 5.3+, it is not even possible to compile PHP without it anymore. There is no specific type for list-arrays and associative arrays, but there is an `array_is_list` function to quickly check it.
- For typed properties, if a property is not typed, it is effectively considered `mixed $var = null`. If the property is typed, and has no default value, then it is considered uninitialized, and not allowed to access.
Arrays in PHP are mostly confusing if you are used to them in other languages.
Instead of $array[0] - the first element is accessed via array_first().
Having them as key-value means, that you can easily just remove some items in the middle, during iteration etc. No automatic shifting happening.
The thing which bites me is when some internal functions actually reindex the array. array_filter does not, but for example array_reverse, array_slice etc. do (preserve_keys always defaults to false). And for array_merge too, but there it's no array_merge(preserve_keys: false), but instead the + operator. (Why is this operator overloaded?!)
On the topic of the uninitialized state, as co-author of that RFC:
I agree with the author that nullable properties should have been auto-initialized to NULL. I haven't ever seen any benefit of an uninitialized state for these. Some co-authors of that RFC disagreed and wished for consistency with the other typed properties. The good thing probably is, that we still could opt to change this with a relatively minor BC break.
For non-nullable properties, I do think there is value. Not every value is actually available/ready in a constructor. Sure you can assign dummy values to properties. But it's requiring you to then manually guard/assert that the property is actually initialized. If you happen to access a non-nullable typed property without isset(), then your code is likely broken anyway and I'm grateful for the Error exception thrown.
Also, PHP has this peculiar feature of ReflectionClass::newInstanceWithoutConstructor(). This is forcibly having an object in an uninitialized state. Whether that feature should exist or not is a good question, but in practice it's helpful for object hydration for example. This was one further motivation to introduce the uninitialized state.
The author of the post suggests checking at the constructor boundary. But this doesn't inhibit objects leaking / not finishing the initialization properly. (class Foo { public stdClass $object; function __construct() { global $foo; $foo = $this; } } new Foo; $foo->object ... is now still existing? PHP doesn't have mechanisms to invalidate objects at a distance. That would be the alternative, but also spooky.) Some choices need to be made, and all choices will have some rough edges.
Side note: I personally never use is_null(), but nearly always isset(). This nicely checks for the uninitialized state too. Static analysis tells me anyway, when I access a variable or property name which can never exist.
idoubtit 21 hours ago [-]
There's one problem with arrays that I haven't seen mentioned here or by the OP: when inserting a key-value, the type of the key may change.
For instance ["4" => "four"] === [4 => "Four"]
This can lead to some unexpected behaviors. For example, I've already been bitten by `array_merge()` whose result is different if its parameters are arrays with numeric indexes.
The key type changing is generally not a problem per se, but it's definitely odd with the default re-indexing behaviour depending on whether something is integer keys only or not.
That's exactly what I've been complaining in my post above. If there were no automatic reindexing, then this wouldn't be a problem either.
tikotus 17 hours ago [-]
I hadn't done any PHP in almost 20 years, not since my studies when LAMP was still the way to go. But recently I had a reason to create a dynamic web page (not what I usually do) and went with PHP. Haven't regretted it.
I haven't run into any of the quirks. I keep things simple, and it just works. The only problem I ran into was the realization that PHP is the wrong tool for long running tasks. After some rogue requests/users running my whole service to ground, I had to move the long running endpoints to node.
hparadiz 15 hours ago [-]
Try https://reactphp.org/ for job running. Use apc or memcached for persistent storage. Don't run jobs through web. Queuing things (you can start with a basic rdbma for your queue storage) and have a job runner fire them from a job runner. Can all be done in PHP. Have scaled it to billions per 24 hours.
nullbio 16 hours ago [-]
The hate PHP gets is from people with 15 year old ideas of what PHP is. It's just bandwagon effect at this point.
artyom 14 hours ago [-]
I agree, as I was one of them. Rightfully so, because PHP 20 years ago was the prime example of a complete disaster. Not just occasionally, there were long years of incompatibility, missing implementations, incoherent errors, security issues, fragmentation, etc.
Paid my share of dealing with those problems with PHP 5 and 6 (after coming from PHP 4). I think it became a more sane ecosystem around very late 7.x to 8.
I won't touch PHP ever again, but I'm glad (no irony) that they finally were able to pull it off. There were some good ideas there, then they quickly became victims of their own success.
Nowadays, there's places (Amazon) where PHP is just forbidden at a company-wide level (not joking) because of their early, long-standing reputation of being a mess. Or places where they just gave up and re-implemented their own PHP (Meta). I don't see that changing any time soon.
moebrowne 9 hours ago [-]
> Paid my share of dealing with those problems with PHP 5 and 6
Hard to take this seriously when there was no PHP 6.
If you were there, you'd remember the UTF8/Unicode fiasco (how long it took, how many people was both relying and struggling with it, and how they needed to cover it up after even some hosting providers attempted a beta upgrade and had to roll it back).
There was a PHP 6 (I'm including the non-updates in PHP 5 "waiting" for it), they just had to rewrite history as of PR damage control back then. That's what the article you linked describes, pretty much.
usernametaken29 6 hours ago [-]
It was said in different ways in this thread but mostly a language that needs a triple equality operator because they fucked up their normal equality operator to a point where it’s so unintuitive that people flat out recommend not using it at all, is what gives it a bad reputation. Likewise PHP primitives are runtime configuration dependent, you can throw different values at your runtime and get different function returns. I remember large parts of F3 was testing the environment config for databases to see what would be the correct expected returns.
That’s insane. I’m saying it. Both of these things make me RUN.
I don’t care about features, I can code in C99 if need be. But I can’t deal with a language in which the work befalls on me to read the documentation even for the most trivial things, because it is plainly illogical or not deterministic.
That’s why people hate PHP.
The rest really doesn’t matter and boils down largely to preference.
arialdomartini 4 hours ago [-]
Hint: use test assertions instead of print + comments for the examples.
t1234s 23 hours ago [-]
The last part about "$" is epic.
kyriakos 23 hours ago [-]
petition to use Euro symbol when coding PHP in EU.
Sure it's full of wtfs and as consistent at French on a good day.
But as a business language, it's as twisted as the business needs its code to be, I found it to be a great match. And there is literally nothing you can't get Laravel to do. It's that good.
Now working with other stacks, most colleagues' features are "wow wow wow slow down this is a big deal" ... In PHP/Laravel, it ain't.
PHP is fast enough, powerful enough and comfortingly weird enough. It reminds you that computers weren't that serious.
pavel_lishin 18 hours ago [-]
> You just have to know that, or else you end up with subtle bugs.
This might as well be PHP's slogan, tbh.
I've worked with PHP since... good lord, 200...2? And it's wild that this is still the case.
chrisandchris 21 hours ago [-]
About undefined vs. NULL:
> Not a warning—a FATAL error occurs if you try to access an uninitialized property. This comes up a lot in cases where you try to deserialize data into a PHP object. If a field's data isn't present you might not initialize the property at all.
I don't think that is an issue, except in interpretet type-unsafe languages it is harder to anticipate when writing code whether that value is NULL or undefined/uninitialized. E.g. it is basically the same in C#, but here the compiler warns you that the value is not initialized and forbids some actions (like reading the value of it).
For anyone wondering the number in the second example isn't just some random big number it's: PHP_INT_MAX + 1
stephenr 7 hours ago [-]
If I show a person on the street a Fuji apple and a Honeycrisp and ask if they're approximately the same, they're going to say yes even if they're labeled.
Php has had a strict equals operator for decades. You not using it is not a language fault.
For the second point: I doubt you'll fine any language where you can just do an equals comparison on floats and it works as expected. That's the nature of floating point numbers.
senfiaj 18 hours ago [-]
> Despite all the critiquing I've done in this article, I still think the amount of hate PHP gets is undeserved.
As a person who also codes in PHP at work, I still dislike the language syntax part. JS/TS also has terrible parts, but IMHO, compared to PHP, I don't face them as much and they are much easier to avoid when you have enough knowledge and stick to good parts.
As the author mentioned, in my experience PHPs arrays are quite annoying to work with, and you can't do anything about them. This C-like procedural syntax for array and string manipulations makes discoverability harder. Some functions (in_array, implode, shuffle, trim, stripos, lcfirst, etc) still have inconsistent namings despite many of them have a standard prefix in their name, such as array_ or str_.
I mean OK, PHP is still widely used, has new features and is still and far from dying (mostly for reasons other than syntax), but please don't pretend that it hasn't some issues with basic stuff which are still there even in 8.x version.
I found php’s array methods lacking as well. The inconsistencies are a pain. I ended up porting many of the methods from lodash, underscore, etc. to php: https://github.com/mpetrovich/dash
Maybe you’ll find it helpful
makeitdouble 1 days ago [-]
To note, it is surprisingly refreshing to completely forgo instanciable classes on a modern codebase.
Phpstan deals well with type definitions, arrays are powerful enough to contain whatever needed, and functions can be stored and passed around easily enough.
chuckadams 24 hours ago [-]
Array shapes are still second-class citizens defined in phpdoc, with an inferior editor UX, and lack of any run-time enforcement. A proper record type for PHP with value semantics would be an ideal solution for me. Would go nicely with the pattern matching proposal that's still incubating.
skydhash 23 hours ago [-]
If there is one thing I love about Clojure and Common Lisp, it’s that you’re not supposed to care about the shape of a complex data if it’s external to the module. What really matters are the functions that are exported and their signature. Anything that’s not standard in the library should be used as an opaque blob. And something like CLOS is about making this easier to define.
love2read 24 hours ago [-]
I’d love to see a post like this for JS that actually talks about things people run into. Usually when people make a post like this in js, its about archaic things nobody actually uses.
Honestly the only way to remain sane in either, but especially if you use both, is to always use === and never use boolean logic (!) when a string could be involved.
moritzwarhier 22 hours ago [-]
That's what I say in code reviews as well. Same for numbers.
!someValue is useful only for:
- booleans, including optional booleans (which is why every bool flag should default to false)
- undefined, null (falsy), or object/function (truthy)
It's nice for the second variant to also cover falsy NaN or things like this, for example for forms.
I guess that's where
!!""===false
comes from.
But it's this exact case that keeps tripping me up.
What about empty arrays?
Per my original comment, now I'd have to look up if
![]
is false in PHP, or just
empty([]) === true
.
So yea I agree, and extend your case to PHP "arrays" (in JS,
!![] === true
is
true
zerocrates 17 hours ago [-]
Obviously it depends what you're working on, what your patterns are, and so on. But my experience is that PHP involves so much array wrangling that devs are more likely to have a handle on what an array will do in this context (an empty array is falsy).
It's the string ones (in particular that in addition to the empty string, "0" specifically is the only other falsy string) that tend to catch people out.
kif 1 days ago [-]
Also `empty("0") === true` is a common gotcha.
user3939382 14 hours ago [-]
In what context are you doing if("0")? People always have these obscure type comparison complaints, not just for PHP, and all I can think is why would you write that?
jorams 3 hours ago [-]
Something you'll see in real codebases is code that cares whether an input value is "empty", but it doesn't matter if it's null or an empty string. It's very easy to go for this:
if ($input) {}
It'll work through every test case you try, and then someone enters a 0 into the field and it's also unexpectedly considered empty.
progforlyfe 19 hours ago [-]
I have not seen "PHP" listed as a language used in any Hacker News job posting in a very long time. Everything is Javascript/Typescript now, with the occasional Rust, C/C++, Golang, Python, Ruby. I never see PHP ever.
Every time I work in another language I miss PHP’s arrays.
conceptme 24 hours ago [-]
Basically every other language has the same functionality (or better) as a hashmap.
ceejayoz 24 hours ago [-]
I’m well aware of them. I’m not sure I agree with “better”.
xp84 23 hours ago [-]
I’m very curious to hear your take on this. I started out on PHP for about 4-5 years then moved on to Ruby and JS. I never once had any fond thoughts for PHP’s split-personality array thing. So I’m very curious what it is that other people appreciate about it.
ceejayoz 23 hours ago [-]
Having to switch implementations and potentially functionality because, say, the order of the collection matters now is rather annoying, IMO.
rokkamokka 1 days ago [-]
They are an incredibly versatile tool for sure. Even more so wrapped in a Laravel Collection
lazka 23 hours ago [-]
That array keys are auto-coerced to integers has bit me multiple times.
spiderfarmer 1 days ago [-]
Absolutely. If you don’t know PHP arrays aren’t actually arrays, the other languages feel inferior.
bakugo 1 days ago [-]
For me, it's the exact opposite. Every time I work with PHP, I wish I could have TypeScript's properly typed arrays and dictionaries instead of the janky untyped 2-in-1 mess it actually has.
Maybe that’s because a site last updated 8 years ago is utterly irrelevant for, like, anything?
guskel 3 hours ago [-]
It’s not so irrelevant if your org is stuck on older versions of PHP.
9dev 2 hours ago [-]
Being stuck on versions of PHP published >= 8 years ago isn't a valid excuse anymore, with AI and static analysis tools available IMHO. And even if you really don't identify using CVE-ridden, unsupported, ancient software to handle customer data as a critical business risk and insist on riding the burning train instead - well, then you've lost all right to poke fun at the legacy PHP versions you're stuck on, because the pain is entirely self-inflicted by your org.
spiderfarmer 1 days ago [-]
I think the “bad rep” is coming from developers that stopped developing themselves.
chuckadams 23 hours ago [-]
I've written PHP off and on since the .php3 extension was a thing, and I can say that PHP very much deserved the bad rap it had for some time. It's evolved beyond most of that, but a lot of that is due to the composer ecosystem making up for it while the behavior of many builtins remains beyond repair. Which is fine, every language has baggage and warts. PHP's warts are sometimes heinously ugly, and they're on full display in many legacy codebases, but modern PHP is something I actually find to be fairly pleasant to develop with, far more than Go or vanilla JavaScript.
spiderfarmer 20 hours ago [-]
The most under appreciated thing about PHP is the fact that after 20+ years I can still develop in PHP and never had to learn a JS framework, Rust, Go, Ruby, Java or .NET.
fancyswimtime 17 hours ago [-]
?? you can write JS without having to learn a framework. They exist in PHP too such as Symfony. This constant complaint about frameworks seems less about the framework and more about having to learn to work with people which is partly why the framework abstraction exists.
luke5441 17 hours ago [-]
I think the biggest problem is that the main way to use it is as a HTTP response handler, whereas other languages are more general purpose.
So when a developer wants to develop themselves outside of a HTTP response handler, they need to switch languages.
I've thrown together quick and dirty CLI scripts with PHP, just because it's the language I know best. It works fine.
esskay 23 hours ago [-]
A lot of it came from the rather harmful "php a fractal of bad design" article that used to get posted everywhere despite being highly inaccurate and out of date. Thankfully its fairly rare to see someone daft enough to still try using it in a discussion. PHP's come a very long way since then.
thayne 23 hours ago [-]
What is inaccurate about it? Maybe it is out of date now, but when I first read it about a decade ago, when I did a fair amount of PHP development, I had personally encountered most of the issues mentioned in there.
I've heard that PHP has improved a lot since then, but I don't see how you could really fix all the inconsistencies, global state, and "oddities" without a lot of breaking changes and really making it into a different language.
duskwuff 17 hours ago [-]
The essay was largely accurate when it was written in 2012. We are living in the grim dark far future of the year 2026, and PHP has now addressed many of the issues it raised.
spiderfarmer 20 hours ago [-]
PHP should learn from JS where you have to abandon frameworks every two years.
esskay 20 hours ago [-]
> What is inaccurate about it?
It's been debunked so many times over the years, I'm afraid I don't have the energy or desire to do it again when it's really not needed if you're far out of the php ecosystem that it really won't make a difference. Suffice to say the PHP it is talking about is nothing at all like modern PHP.
thayne 15 hours ago [-]
Sure PHP has improved since that was written, but I'm pretty sure it was accurate when it was written. And I suspect that it was probably a contributing factor in some of PHP's improvements since then.
fg137 23 hours ago [-]
No. Bad rep comes from developers who used other languages and never looked back.
spiderfarmer 21 hours ago [-]
So they stopped developing in PHP am I right?
frutjgma 24 hours ago [-]
I did PHP for 15 years. Modern PHP looks good but I still wouldn't go back.
phplovesong 21 hours ago [-]
What is even "modern php"? It has the same warts than it had back in the day, last i looked nothing is fixed.
20 hours ago [-]
iceluc000 14 hours ago [-]
Perfect Circle(neal.fun)
cess11 23 hours ago [-]
I like the arrays, they make it feel like a bit of a low level language and there are some weird tricks one can do with them. As for class property behaviour, I kind of get nervous if my properties or the constructor don't enforce default values I can then fit into downstream logic.
One of the best things with PHP is PsySH, or "Tinker" as the laravelists call it. It's not a REPL in the Common Lisp sense, but it is quite nice for an interactive programming shell. I've spent countless hours solving problems very, very quickly in it, and alongside Picolisp pil + and Elixir iex it's one of the earliest tools I install on a new system.
The thing I miss the most is a nice concurrency story. It has become better but it's still a bit of a mess, often it's nicest to just implement workers as PHP and then implement control somewhere else, e.g. Elixir, or grab one of the application servers that are nowadays a thing in PHP.
bakugo 24 hours ago [-]
> This example exposes the "uninitialized" state that a property can be in, which is NOT the same as NULL. This distinction frustratingly comes up when you try to do a null check on these properties:
If you're accessing an uninitialized property or checking if a property is uninitialized, you're probably already doing something wrong.
The point of class properties with no default value is that you're supposed to set them either in the constructor, immediately after creating an instance, or via some other method that guarantees they'll have a value by the time you need to read them (such as deserialization with validation).
If you want your properties to have a default "unset" value that you can trivially check for, that's what null is for. The author doesn't make it clear whether they are aware that you can declare a nullable string and give it the default value of null, but I hope they are.
xp84 19 hours ago [-]
I think anyone would agree with the “you’re doing something wrong” part, but if you declare that a property is typed and non-nullable, it would be nice if a constructor that didn’t populate its non-nullable properties would cause an exception to be thrown or something, as the constructor didn’t construct a valid object by its own specification. The wrongdoing was in the constructor so the constructor should be where that happens, not the innocent caller later who trusts the type definition.
Maybe it’s too impossible to do that, but the behavior described seems like it puts you right back in the world of completely dynamic anything-goes (PHP’s legacy, basically).
I thought part of the point of types was to give the caller confidence that simply accessing a typed property is guaranteed to return a certain type (null being a type that may be included).
shevy-java 24 hours ago [-]
All of PHP is an oddity. It is a practical oddity, but also ugly to no ends. I am glad to have abandoned it many years ago.
Surprisingly enough, I was more productive in PHP than I was in perl. Perhaps perl is even stranger than PHP.
acomjean 23 hours ago [-]
Modern PHP is pretty good. I’ve been using it for a while so it’s comfortable.
I’ve been doing so Perl maintenance lately and I miss PHP. Perl is a lot weirder than PHP. If I didn’t know C or had dabbled in Perl before I would be completely confused. There is More Than One Way to do it (the Perl rallying cry) causes a lot of confusion. The one nice thing about Perl is that it doesn’t really change anymore, and you can see where it positively influenced others.
21 hours ago [-]
tacker2000 18 hours ago [-]
[dead]
ryan_glass 22 hours ago [-]
[dead]
spotlayn 19 hours ago [-]
[flagged]
phplovesong 21 hours ago [-]
PHP is fundamentally broken, and unfixable. Its a toy language, and there is no reason to pick it in 2026
Modern PHP is great. Many powerful language features, excellent performance, great community and package ecosystem, and decent enough safety with modern static analysis tools.
I'm not too sure I agree with the author's complaints here. When using something like array_filter, you're typically mapping from collection to collection (i.e. you don't care about the first element--you care about the whole thing) and so this problem is really a non-issue. The next follow up step would usually be foreach, or another operation like array_map, in which case it's a non-issue.
If you really do need the first element, you can use array_first. And if you really do need a fixed-sized collection, you can use SplFixedArray.
The point on properties is valid to an extent, but IMO not really an issue you commonly run into in the real world (regardless of language, your constructors should generally return an object in a usable state).
I have this thing I want to do in C. Now my C is very weak so my plan was to do a prototype in python, keeping in mind the C ecosystem then sit down with my old copy of "The C Programming Language" and struggle through it. Doing it with no dicts was rough.
I am normally the sort to avoid adding any libraries I don't have to but if anyone has any hints to simple hash maps in C I am all ears.
If for some reason you absolutely need to use c, consider if you really need a hashmap. If your collection is relatively small, just use an array or linked list with linear search. That's a pattern I've seen used in several c codebases, I think because of the difficulty of using map types.
If linear search would be too slow, then a binary search tree is relatively easy to implement, and gives you log(n) lookup time (as long as it's balanced). Or if you build it up once and don't modify it very much afterwards, you can use a sorted array, with a binary search.
If you really need a hashmap, there are some implementations, but I've also seen a few c projects that just implement their own hashmaps.
0) use Lua with LuaJIT. It has very good C interop and native hashmaps. Downside - Lua has its own rough edges and LuaJIT is frozen at Lua 5.1 with some extensions for 5,2
1) SDL3 has a hashmap implementation with its properties API, and a general purpose hashmap that they're probably going to make public at some point maybe? Downside - overkill if you don't actually want to use the rest of the library.
2) https://github.com/tidwall/hashmap.c this seems to work fine and is the simplest hashmap implementation for C that I've seen. Downside - you still have to write a lot of boilerplate.
But then people started to actually use it to build big sites, `echo($_GET['user'])` alone is not enough, it has to be:
So people started to add module/components as well as ways to load and use those components, to enable them to write code like: That's when it got it's Java look.Nice Java burn! But now days all you have to say to burn Java is "Lawnmower".
To get the first element there also is reset().
I love PHP though.
Perl's hashes are a complete mystery to me still, but at least it lets me know that it's not just a linear, uh, well, array.
They're unordered mappings from strings to arbitrary values ("scalars" in Perl jargon). In this sense they're just like an object in JavaScript.
Where this gets a little weird is that Perl arrays and hashes are fundamental types distinct from scalars - you can't put a hash into a $variable without taking a reference to it first, for instance. But that's more a matter of Perl being picker about the value/reference distinction than a hash-specific thing.
That probably needs an array_second too, doesn't it? Maybe array_second_from_last as well?
Most type checking happens at runtime (this might not be true for interfaces at some level, but I can’t say for 100% certain - I just know I tend to see interface related errors earlier during code execution…). It’s perfectly valid syntax to declare a private method as returning an integer and then for the body of the method to return a string (explicitly cast as a string even). As long as you never call that method at runtime, no exceptions will be thrown.
With a half decent IDE or LSP, these sorts of runtime exceptions can be easily avoided but technically they still exist and if you don’t know about that, it can be argued to be confusing. PHP has made a lot of trade-offs to largely maintain backwards compatibility and many of them live in decisions that happen at runtime.
Modern PHP tooling can provide type safety in a very similar way to Typescript if you’re willing to put in the effort while also still technically offering you an escape hatch to do whatever the heck you want and duck type to your hearts content.
PHP parses the whole file and compiles it to Zend opcodes before executing it, so syntax errors are caught up front. But "JIT" means compiling an intermediate representation/opcodes into native machine code at runtime, when the functions are called, not at load time when the source file is parsed. If you just load a file and never call any of its code, the JIT compiler should never compile it.
PHP 8's OPcache JIT can do that optionally, but the normal load/parse/compile-to-opcodes step isn't JIT.
I always thought that DSLs were the one thing Ruby did better than the competition, but Kotlin's combination of receiver lambdas plus syntactic sugar for calling higher-order functions make it an even better language to write DSLs in.
And the code I'm looking at now with Kotlin is so similar to code i liked reading when I was in a committed relationship with Ruby.
In PHP though the STDlib is not very well thought out, it may be fun(needle,haystack) or fun(haystack,needle) and you just have to remember
empty() will do weird stuff like a string with the value "0" is also empty, so not great for parsing things.
A lot of footguns and the best way to avoid that is with a decent linter that lets you be picky
another thing I mention is avoiding the array_ stuff because of aformentioned reasons, it's easier to remember/reason about boring loops unfortunately.
I heard this a long time ago about perl. CPAN is great.
Well ... perl entered the fossilized era. I think people do not really observe things correctly. I am noticing the same with ruby right now - everyone sees that ruby is in decline, very strongly so, in the last 3 years. Yet you have blog posts such as "ruby is not dying - it is aging like fine wine". And these are all NOT BASED ON FACTUAL ANALYSIS. I still think ruby is a great language, but if people are not realistic in their assessment of a situation, what does this tell us about people's evaluation in general? People seem to shy away from criticism. You can see this on reddit too, where moderators ban and censor willy-nilly, or even on github, where you can also quickly get eliminated for not conforming to xyz. It's as if some people are very afraid of strong opinions. I don't understand why - an opinion that is objectively false, can be shown to be false.
I remember it being somewhat common for people to make forum posts consisting entirely of a joke image. However, they weren’t called memes at the time as the word had yet to be popularized.
> Ruby is dying
How exactly do you define these “objective” criteria for such sensationalism?
What actual criticism of PHP is anyone shying away from?
PHP got bashed for such a long time, while simply nothing steps up to do what it does better. Something that, for example, is available on every webhost you can just throw files at, where all (meaningful) config and state can be in those files.
Why do I bring up containers? Because part of why PHP was so dope in this way was the way you can just define 1 file per endpoint and drop it in public_html, and have no server setup to do. Running say, Rails or ASP.NET or a Java site back then meant doing… a lot more, to your server.
But with Docker, you can just steal a good Dockerfile template from someone else, and it’s just like 3-4 simple files for you to manage for a simple Sinatra (Ruby) or node.js version of the “one-off PHP file” things.
edit: Granted, I agree that if you want to do all sorts of things on the internet, maybe PHP is not the right choice. But for simple, dynamic web things that I want to just make and then run like this forever, that I can work on but don't have to? PHP and vanilla HTML and Javascript are where it's at for me, hands down. Everything else I know is either too new or seems to have constant churn or issues. That you hear nothing about PHP other than complaining it's "outdated" or whatever from the outside -- always "why are you using this?" never "why oh why am I using this?" -- is because it just hums along, IMO. I like it better than Python, and I kinda view it as in that class.
You still need to build a router and a web server in said nodejs script. And manage everything, including taking care that requests don't accidentally mutate global state.
PHP in contrast is stateless. Way less bs to take care about.
I'm halfway onboard :) That is, personally I do like that PHP is kinda "boring", it's just a programming language that mostly looks like other curly brace languages that can basically do anything I ever need to do with strings out of the box. And I like that PHP, while also adopting more advanced programming concepts, stays nice with all the simple stuff. I like the stewardship, you might say, although I don't pay any attention to it. New PHP versions always either have things I don't understand, don't care about, or really like. The performance goes steadily into the correct direction, too.
I'm sure people who know more about programming and the version history will disagree about something, but for my "low-tech" usage, it's actually one of the few happy places of computing. Not happy as in exciting, more like working in a modeset garden, without stuff blowing up constantly, and salesmen posing as flowers.
But I still would love to see and try out "takes" on that, or on what other people like about it. At least to start with, I guess it would just need to be be somewhat painless to use with with Apache, NGINX, or come with a webserver built-in. Then people can use that locally and on servers they fully control, and if it's really good, and really good with resources, basically a painless additional thing to add, web hosts might adopt it etc.
Unfortunately newer versions of PHP killed it and it's dead now, and even more unfortunately while PHP absorbed a lot of features from Hack, native XML was not one of them. There was even going to be a Hack version of the Composer package manager but that never got finished AFAIK. Distros stopped supporting it. I think I still have my half-finished attempt at a Hacker News fork in Hack sitting around on a hard drive somewhere. I can't even find an environment to run it in anymore.
[0]https://docs.hhvm.com/hack-overview/
[1]https://docs.hhvm.com/hack/XHP/introduction/
Having a language whose entire purpose is to be a templating language for HTML have no concept of what HTML is, is just ridiculous. You have to use a templating framework that rolls its own ad-hoc DSL and parser to manage context just to make PHP do what it should be able to do safely and sanely out of the box.
It doesn't matter now, since "web dev" is whatever JS vibe-coded nonsense Claude shits out and no one cares anymore, but ye gods it could have been so much better.
Anyway, I don't even think about server-side rendering anymore, and for the last few days have had Claude "shitting out" Vue components that replace legacy Bootstrap 3 components with html5 alternatives for my PHP app to use via Inertia.js. The axe-grinding is not helpful to either of us.
I've also extensively used Zope and Plone, which attempt to give designers a "safe" set of capabilities and subset of Python which was a total disaster. Template DSLs always end up trying to regrow programming language features, much usually worse then the languages they are implemented in.
Zope is particularly illustrative because it recursively accumulated: TAL, METAL, TALES, RestrictedPython, and DTML: all to avoid "just use Python templates". (And don't even get me started on all the layers CMF and Plone introduced!)
This happened with Smarty, Zope Page Templates (ZPT), TAL/METAL, RestrictedPython, Django templates, Helm templates, Jenkins pipelines, GitHub Actions YAML, Terraform HCL, and countless other attempts to create a "safe non-programmer-friendly mini-language" that eventually mutates into a worse programming language, often with horribly leaky abstraction layers of \escaping and < perfect syntax and <![CDATA[ cruft.
I Wanna Be <![CDATA[ (Sung to the tune of "I Wanna Be Sedated", with apologies to The Ramones):
https://donhopkins.medium.com/i-wanna-be-cdata-3406e14d4f21
https://news.ycombinator.com/item?id=32886424
This attitude causes disasters like PHP's "Smarty" templating language.
PHP was already a templating language, but somebody got it in their head that there should be an iron-clad separation between designers and programmers, and that PHP gave designers too much power and confused them, and that their incompetent untrustworthy designers who refused to learn anything about programming deserved something even "simpler" than PHP, so they came up with Smarty.
Then over time the realized that their designers were powerless, so their programmers would have to learn TWO languages so they could wade into the Smarty templates to make them actually work with all the extra code they had to write because Smarty was so crippled, so they nickle-and-dimed more and more incoherent programming language elements into Smarty, making it EVEN HARDER to use and more complicated and less consistent than PHP, yet nowhere near as powerful.
https://news.ycombinator.com/item?id=20736574
DonHopkins on Aug 19, 2019 | parent | context | favorite | on: YAML: Probably not so great after all
One of the most ridiculous examples of this was the Smarty templating language for PHP.
Somebody got the silly idea in their head of implementing a templating language in PHP, even though PHP is ALREADY a templating language. So they took out all the useful features of PHP, then stuck a few of them back in with even goofier inconsistent hard-to-learn syntax, in a way that required a code generation step, and made templates absolutely impossible to debug.
So in the end your template programmers need to know something just as difficult as PHP itself, yet even more esoteric and less well documented, and it doesn't even end up saving PHP programmers any time, either.
https://web.archive.org/web/20100226023855/http://lutt.se/bl...
>Bad things you accomplish when using Smarty:
>Adding a second language to program in, and increasing the complexity. And the language is not well spread at all, allthough it is’nt hard to learn.
>Not really making the code more readable for the designer.
>You include a lot of code which, in my eyes, is just overkill (more code to parse means slower sites).
https://web.archive.org/web/20090227001433/http://www.rantin...
>Most people would argue, that Smarty is a good solution for templating. I really can’t see any valid reasons, that that is so. Specially since “Templating” and “Language” should never be in the same statement. Let alone one word after another. People are telling me, that Smarty is “better for designers, since they don’t need to learn PHP!”. Wait. What? You’re not learning one programming language, but you’re learning some other? What’s the point in that, anyway? Do us all a favour, and just think the next time you issue that statement, okay?
http://www.ianbicking.org/php-ghetto.html
>I think the Broken Windows theory applies here. PHP is such a load of crap, right down to the standard library, that it creates a culture where it's acceptable to write horrible code. The bugs and security holes are so common, it doesn't seem so important to keep everything in order and audited. Fixes get applied wholesale, with monstrosities like magic quotes. It's like a shoot-first-ask-questions-later policing policy -- sure some apps get messed up, but maybe you catch a few attacks in the process. It's what happened when the language designers gave up. Maybe with PHP 5 they are trying to clean up the neighborhood, but that doesn't change the fact when you program in PHP you are programming in a dump.
Obviously not from the beginning. But by the time template frameworks like Twig came around it should have been possible. If it can be done at runtime it's possible to build into the language proper. And I'm specifically talking about the time when PHP 7 started taking other features from Hack.
I'm not grinding an axe here, i'm just stating an opinion.
https://blog.codinghorror.com/the-php-singularity/
https://web.archive.org/web/20120711143431/http://me.veekun....
Yesterday, Cursor coughed up https://fdedictionary.com for me in PHP. You know what, it is like a dozen files and works awesome, no daemon needed, basically just a web server, some PHP files, and one SQLite file.
Today, Claude Code, the major hotness, made changes to a (different) toy app with less complexity, in node.js and you know what, it has ~49,000 files. And uses a 3rd party SaaS to host the db, and another 3rd party SaaS to do auth, and yet another 3rd party SaaS to import a repo and do deployments and hosting.
Simplicity has a place for some things. I love PHP+SQLite for tiny apps, and LLMs/agents are awesome at it.
I forgot, ChatGPT one-shotted the PHP app and Cursor put the finishing touches on. What a world. Long live PHP, is the point. Arrays and all.
Doing so now raises a deprecation warning, unless you add #[AllowDynamicProperties], and PHP 9 will convert it to an error. I'm told this will simplify internals and unlock optimizations.
Arrays are still fairly awful, but generics may become a reality sooner rather than later, and on that could be built Vec and Dict types, à la Hack. PHP is going to be stuck with arrays as they are now for forever, but they'll at least become optional for new code.
The one thing I really wish PHP would add is structurally typed objects. I really miss it when moving back and forth between PHP and TypeScript.
They could call them anonymous objects if they want to (that would be a more culturally correct analogue to anonymous classes).
Like, I wish it was possible to do
and have it be equivalent to and then be able to typehint it like and honestly, why not go all the way and allow type definitions/aliases, something like That'd be great.- For Psalm, see https://psalm.dev/docs/annotating_code/type_syntax/utility_t...
- For PHPstan, see https://phpstan.org/writing-php-code/phpdoc-types
It may work in your IDE (autocompletion, etc.) but there is no standard on this side. Some IDE have their own parsers, others use one of the LSPs for PHP.
- PHP has `SplFixedArray`[^1] that work similar to the standard arrays you expect from other languages. SPL extension is always available in PHP 5.3+, it is not even possible to compile PHP without it anymore. There is no specific type for list-arrays and associative arrays, but there is an `array_is_list` function to quickly check it.
- For typed properties, if a property is not typed, it is effectively considered `mixed $var = null`. If the property is typed, and has no default value, then it is considered uninitialized, and not allowed to access.
[^1]: https://www.php.net/manual/en/class.splfixedarray.php
But it doesn't have Perl's brevity: https://imgur.com/a/CfRqh5X
Having them as key-value means, that you can easily just remove some items in the middle, during iteration etc. No automatic shifting happening.
The thing which bites me is when some internal functions actually reindex the array. array_filter does not, but for example array_reverse, array_slice etc. do (preserve_keys always defaults to false). And for array_merge too, but there it's no array_merge(preserve_keys: false), but instead the + operator. (Why is this operator overloaded?!)
On the topic of the uninitialized state, as co-author of that RFC:
I agree with the author that nullable properties should have been auto-initialized to NULL. I haven't ever seen any benefit of an uninitialized state for these. Some co-authors of that RFC disagreed and wished for consistency with the other typed properties. The good thing probably is, that we still could opt to change this with a relatively minor BC break.
For non-nullable properties, I do think there is value. Not every value is actually available/ready in a constructor. Sure you can assign dummy values to properties. But it's requiring you to then manually guard/assert that the property is actually initialized. If you happen to access a non-nullable typed property without isset(), then your code is likely broken anyway and I'm grateful for the Error exception thrown.
Also, PHP has this peculiar feature of ReflectionClass::newInstanceWithoutConstructor(). This is forcibly having an object in an uninitialized state. Whether that feature should exist or not is a good question, but in practice it's helpful for object hydration for example. This was one further motivation to introduce the uninitialized state.
The author of the post suggests checking at the constructor boundary. But this doesn't inhibit objects leaking / not finishing the initialization properly. (class Foo { public stdClass $object; function __construct() { global $foo; $foo = $this; } } new Foo; $foo->object ... is now still existing? PHP doesn't have mechanisms to invalidate objects at a distance. That would be the alternative, but also spooky.) Some choices need to be made, and all choices will have some rough edges.
Side note: I personally never use is_null(), but nearly always isset(). This nicely checks for the uninitialized state too. Static analysis tells me anyway, when I access a variable or property name which can never exist.
This can lead to some unexpected behaviors. For example, I've already been bitten by `array_merge()` whose result is different if its parameters are arrays with numeric indexes.
That's exactly what I've been complaining in my post above. If there were no automatic reindexing, then this wouldn't be a problem either.
I haven't run into any of the quirks. I keep things simple, and it just works. The only problem I ran into was the realization that PHP is the wrong tool for long running tasks. After some rogue requests/users running my whole service to ground, I had to move the long running endpoints to node.
Paid my share of dealing with those problems with PHP 5 and 6 (after coming from PHP 4). I think it became a more sane ecosystem around very late 7.x to 8.
I won't touch PHP ever again, but I'm glad (no irony) that they finally were able to pull it off. There were some good ideas there, then they quickly became victims of their own success.
Nowadays, there's places (Amazon) where PHP is just forbidden at a company-wide level (not joking) because of their early, long-standing reputation of being a mess. Or places where they just gave up and re-implemented their own PHP (Meta). I don't see that changing any time soon.
Hard to take this seriously when there was no PHP 6.
https://ma.ttias.be/php6-missing-version-number/
If you were there, you'd remember the UTF8/Unicode fiasco (how long it took, how many people was both relying and struggling with it, and how they needed to cover it up after even some hosting providers attempted a beta upgrade and had to roll it back).
There was a PHP 6 (I'm including the non-updates in PHP 5 "waiting" for it), they just had to rewrite history as of PR damage control back then. That's what the article you linked describes, pretty much.
Sure it's full of wtfs and as consistent at French on a good day.
But as a business language, it's as twisted as the business needs its code to be, I found it to be a great match. And there is literally nothing you can't get Laravel to do. It's that good.
Now working with other stacks, most colleagues' features are "wow wow wow slow down this is a big deal" ... In PHP/Laravel, it ain't.
PHP is fast enough, powerful enough and comfortingly weird enough. It reminds you that computers weren't that serious.
This might as well be PHP's slogan, tbh.
I've worked with PHP since... good lord, 200...2? And it's wild that this is still the case.
> Not a warning—a FATAL error occurs if you try to access an uninitialized property. This comes up a lot in cases where you try to deserialize data into a PHP object. If a field's data isn't present you might not initialize the property at all.
I don't think that is an issue, except in interpretet type-unsafe languages it is harder to anticipate when writing code whether that value is NULL or undefined/uninitialized. E.g. it is basically the same in C#, but here the compiler warns you that the value is not initialized and forbids some actions (like reading the value of it).
$ php -r 'var_dump("01234" == "1234");' bool(true)
$ php -r 'var_dump("09223372036854775808" == "9223372036854775808");' bool(false)
Php has had a strict equals operator for decades. You not using it is not a language fault.
For the second point: I doubt you'll fine any language where you can just do an equals comparison on floats and it works as expected. That's the nature of floating point numbers.
As a person who also codes in PHP at work, I still dislike the language syntax part. JS/TS also has terrible parts, but IMHO, compared to PHP, I don't face them as much and they are much easier to avoid when you have enough knowledge and stick to good parts.
As the author mentioned, in my experience PHPs arrays are quite annoying to work with, and you can't do anything about them. This C-like procedural syntax for array and string manipulations makes discoverability harder. Some functions (in_array, implode, shuffle, trim, stripos, lcfirst, etc) still have inconsistent namings despite many of them have a standard prefix in their name, such as array_ or str_.
I mean OK, PHP is still widely used, has new features and is still and far from dying (mostly for reasons other than syntax), but please don't pretend that it hasn't some issues with basic stuff which are still there even in 8.x version.
Just to not write a full article, you can read here: https://waspdev.com/articles/2025-06-12/my-honest-opinion-ab...
If interested, I also listed some annoyances of JS: https://waspdev.com/articles/2025-04-16/what-i-dislike-in-ja...
Maybe you’ll find it helpful
Phpstan deals well with type definitions, arrays are powerful enough to contain whatever needed, and functions can be stored and passed around easily enough.
Archaic maybe, but still brings a smile
But apparently they deprecated and then changed(?!) the associativity in the past few years, which if anything just makes things even more confusing.
Once again showing how out of date peoples hate for PHP is
!someValue is useful only for:
- booleans, including optional booleans (which is why every bool flag should default to false)
- undefined, null (falsy), or object/function (truthy)
It's nice for the second variant to also cover falsy NaN or things like this, for example for forms.
I guess that's where
comes from.But it's this exact case that keeps tripping me up.
What about empty arrays?
Per my original comment, now I'd have to look up if
is false in PHP, or just empty([]) === true.
So yea I agree, and extend your case to PHP "arrays" (in JS,
isIt's the string ones (in particular that in addition to the empty string, "0" specifically is the only other falsy string) that tend to catch people out.
Of couse it can be argued that PHP can be used outside this one way as well, but even e.g. https://symfony.com/doc/current/mercure.html is using golang.
I've heard that PHP has improved a lot since then, but I don't see how you could really fix all the inconsistencies, global state, and "oddities" without a lot of breaking changes and really making it into a different language.
It's been debunked so many times over the years, I'm afraid I don't have the energy or desire to do it again when it's really not needed if you're far out of the php ecosystem that it really won't make a difference. Suffice to say the PHP it is talking about is nothing at all like modern PHP.
One of the best things with PHP is PsySH, or "Tinker" as the laravelists call it. It's not a REPL in the Common Lisp sense, but it is quite nice for an interactive programming shell. I've spent countless hours solving problems very, very quickly in it, and alongside Picolisp pil + and Elixir iex it's one of the earliest tools I install on a new system.
https://psysh.org/
The thing I miss the most is a nice concurrency story. It has become better but it's still a bit of a mess, often it's nicest to just implement workers as PHP and then implement control somewhere else, e.g. Elixir, or grab one of the application servers that are nowadays a thing in PHP.
If you're accessing an uninitialized property or checking if a property is uninitialized, you're probably already doing something wrong.
The point of class properties with no default value is that you're supposed to set them either in the constructor, immediately after creating an instance, or via some other method that guarantees they'll have a value by the time you need to read them (such as deserialization with validation).
If you want your properties to have a default "unset" value that you can trivially check for, that's what null is for. The author doesn't make it clear whether they are aware that you can declare a nullable string and give it the default value of null, but I hope they are.
Maybe it’s too impossible to do that, but the behavior described seems like it puts you right back in the world of completely dynamic anything-goes (PHP’s legacy, basically).
I thought part of the point of types was to give the caller confidence that simply accessing a typed property is guaranteed to return a certain type (null being a type that may be included).
Surprisingly enough, I was more productive in PHP than I was in perl. Perhaps perl is even stranger than PHP.
I’ve been doing so Perl maintenance lately and I miss PHP. Perl is a lot weirder than PHP. If I didn’t know C or had dabbled in Perl before I would be completely confused. There is More Than One Way to do it (the Perl rallying cry) causes a lot of confusion. The one nice thing about Perl is that it doesn’t really change anymore, and you can see where it positively influenced others.
https://www.reddit.com/r/lolphp/top/?t=all
https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/