There are differences between the languages as such, e.g. PHP has traits, Python has Operator overloading, etc. From a tooling perspective I cannot tell that there is any big differences.
spl_object_hash returns a unique id, rather than a hash. So why the name? Probably because it's formatted as a masked hex value. I had already started writing code to deal with hash collisions when I found out.
The `self` and `static` keywords for accessing the current class do roughly the same thing, except `self` is static and `static` is dynamic. That's not very nice.
You can't define consts on traits. If you google it, you find a reddit thread where multiple people offer creative theories of why consts on traits would violate OOP principles, and a bug report where you find out that it's because the implementation is too naive to deal with collisions.
Sequential and associative arrays are the same data type, even though in practice you always use them either one way or the other. That interacts really badly with JSON (is an empty array supposed to become [] or {}?) and makes code harder to understand.
Anonymous functions are called closures, but they aren't closures, unless you manually declare which variables from the surrounding scope you want to access and that you want the access to be referential.
Weak typing is still around in enough places to make me paranoid. `in_array('3', ['03'])` is true (and `in_array($x, [true, false])` is true for absolutely any $x). You have to pass an extra boolean argument for strict typing, which is not nearly as easy to spot as a == operator.
Relatedly, arrays can only have string or int keys, with mandatory weak typing. A string that's sufficiently int-like is converted automatically. So this code throws a type error when it reaches 3, even though it was a string when it was entered into the array:
<?php
declare(strict_types=1);
function foo(string $s) {
}
$arr = ['x' => 1, ' ' => 2, '3' => 3];
foreach ($arr as $key => $value) {
foo($key);
}
DateTime::ISO8601 does not implement ISO-8601, and is only kept around for backward compatibility with broken programs. You have to use DateTime::ATOM.There's a lot more like this. PHP is much better than it used to be, and it's very much possible to write good PHP programs, but I find it painful to use.
They don't prevent me from using PHP, but they make it unpleasant. A lot of mental effort that could be going into making sure my own code makes sense has to go into making sure that PHP's behavior makes sense and matches my mental model, more so than with many other languages. It increases friction.