I think you are stretching the hammer analogy well beyond its useful limit. I've no idea what php function you think has a redundant left and right version, but to humor you, sure there are lots of nail pullers that have two similar sides or ends to attack different sizes.
eg http://s.shld.net/is/image/Sears/00938076000
There are also lots of physical tools that completely reasonably do have exactly duplicated sides or ends because they wear out, but I don't see how you want that to apply to software.
Talking about == is not trivial or apologetic. That's the way I expect comparison to work in a loosely typed language. I expect 0, 0.0, '0', '0.0', -0, 00, 0x00, null and false to be logically equivalent most of the time. If it also means that if I don't validate input from an http request 0=='0 foodle fish' also evaluates as true, then that's a cost I'm willing to bear.
Would you expect "1.30" == "13e-1", since both are strings? How about "0xb" == "0xB"? 0 == "zero"?
I don't see how this is anything but bugprone, and all to save you from actually saying what you meant and slapping a couple int()s on your input.
Compare JavaScript, a language with much the same == problems, where the community generally advises against ever using == at all. CoffeeScript (different syntax that compiles directly to JavaScript) even translates == into ===, leaving the original buggy operator unavailable.
I would not expect "1.30" == "13e-1" or "0xb" == "0xB" to compare as true, but it's of kind of cool that they magically do.
I don't think 0 == "zero" is a meaningful comparison, so I don't think there is any single sensible answer. I know "zero" will be cast into 0 and therefore it will be true. That's not a matter of expected language logic, it's just personal preference on do you want your language to fail hard when given garbage input, or continue.
Most input to a PHP program is going to be strings. It is going to have come from an untyped GET or POST request string decoded into string parameters. If you expect it to be integers it needs to be cast somewhere. For most applications you should be doing that explicitly, taking control of the process and deciding how to respond to user error or other invalid input.
Our main difference of opinion seems to be that I think it is good that the language tries to help when the programmer is lazy, and you think it should immediately reprimand them with a rolled up newspaper so they will be forced to do it properly before seeing any output.
It's good when languages try to help. Reprimanding someone for not doing enough work is useless.
My problem is that the language is guessing wildly, in ways too obscure to be mentioned in the documentation or known by you (a user of the language), even when both operands are strings. That means it appears to work much of the time even if you don't think you're being lazy, but might actually have a bunch of false positives you didn't expect. And that's kind of a bad thing in a programming language. Same sort of reason manually escaping everything is hard to get right: if you forget, your code still works fine under "normal" circumstances.
Now, if == did a strict comparison and there were a separate imlazyjustslopittogether operator, there wouldn't be a problem. Defaults matter.
Talking about == is not trivial or apologetic. That's the way I expect comparison to work in a loosely typed language. I expect 0, 0.0, '0', '0.0', -0, 00, 0x00, null and false to be logically equivalent most of the time. If it also means that if I don't validate input from an http request 0=='0 foodle fish' also evaluates as true, then that's a cost I'm willing to bear.