Email or username:

Password:

Forgot your password?
138 comments
Frost, Wolffucker 🐺:therian:

HOLY POOPTARTS this is blowing up,,, 60 boosts and 90 stars???

uhhh if you're looking for a software dev, we're looking for work! We know PHP (as evidenced by me running into this) but also lots of other stuff too. This, um, isn't my even /slightly/ worksafe account though, I was not expecting to go big here.

Frost, Wolffucker 🐺:therian:

okay I'm sorry I gotta mute the thread,

I wish I could mute only the stars and boosts, because I wanna see your replies! but it's all *bloop*bloop*bloop* :3

but do feel free to reply still, I might scour the thread looking for new comments!

Ret

@IceWolf oh yes, that’s super evil lol. Really there’s straight up not much reason to use ==

Woozle Hypertwin

@IceWolf Okay, that is messed up.

They're both evaluating as strings, but then the strings are being evaluated as numbers??

php > echo ('0e83' == '0e99');
1

What's marked as a string should be considered a string until typecast to something else. Putting a number in a string should not cause it to be interpreted as a number.

Are the #PHP devs aware of this?

Gina Peter Banyard

@woozle @IceWolf yes

This has been part of the language since forever.

I have a draft somewhere about what I want to change about comparison but working on other stuff rn.

Gina Peter Banyard

@woozle @IceWolf it used to be even worse in PHP 7 where any non numeric string was `==` to 0

Frost, Wolffucker 🐺:therian:

@Girgias @woozle Hahaha wow. And people say JavaScript is bad,,

PHP 8 seems to have a lot of nice stuff! We skipped, like, the entire history of PHP and only picked it up fairly recently.

Gina Peter Banyard

@IceWolf @woozle some of us are pushing PHP to be better.
JS has the problem that you do not know what the client will be running.

But improving comparisons is something I want to work sooner than later, but it requires some rework at the engine level. Incredibly early draft is here github.com/Girgias/php-rfcs/bl

Ben Ramsey

@Girgias @IceWolf @woozle If this particular example were changed to `===` (i.e., the identity operator, strict comparison), would it still evaluate to `true`?

I have a coding standards rule to always use strict comparison.

Larry Garfield

@ramsey @Girgias @IceWolf @woozle It does not. === skips type juggling, so will compare the strings as strings rather than trying to convert them to ints.

3v4l.org/msiD9

cptwtf

@ramsey @Girgias @IceWolf @woozle

exactly, thats why one should always use the type safe comparison operator except when type juggling is explicitly the wanted behaviour

Frost, Wolffucker 🐺:therian:

@cptwtf @ramsey @Girgias @woozle IMO the normal one should be type safe, or at least a bit less ??? about it, and there should be a separate typejuggling ==.

Frost, Wolffucker 🐺:therian:

@cptwtf @ramsey @Girgias @woozle Kinda like Perl's smartmatching (which I think is deprecated? shame, it's a cool idea).

Woozle Hypertwin

@ramsey

This seems like good practice, which I will be adopting -- but also it kind of reinforces my point that the == operator as implemented is essentially useless, because you can't depend on its behavior.

@Girgias @IceWolf

Woozle Hypertwin

@Girgias

Thanks for your input on this!

I don't know if the answer to this question is impossibly complicated, but what I don't understand is why type-coercion has to take place for comparison operators when both sides of the comparison are the same type.

TLDR: I think what is happening here is that the == operator has a clear preference for numeric coercion -- if a string can be interpreted as a properly-formatted number, it will do that. Only if a string cannot be interpreted that way will it reluctantly do a string comparison:

echo ('0e11' == '0e22');
// ^ shows "1"
echo ('0e11' == '0e2a');
// ^ shows nothing

Also, this is clearly happening at the point of the comparison, and not before:

$x='0e11';
$y='0e22';
var_dump($x);
// string(4) "0e11"
var_dump($y);
// string(4) "0e22"
echo $x == $y;
// 1

The same rule appears to be in effect for !=, >, and <.

Also, this only happens for numerically-formatted contents; the strings 'true' and 'false' are not coerced to boolean values.

Editorializing

(The following is intended not so much as arguing with you as hoping to arm you with more information to present to those who might influence the decisionmaking process.)

There may be valid mental model reasons for doing this, but I think they really need to be spelled out clearly in the manual somewhere and mentioned whenever affected operators are discussed.

To me, right now, it makes no sense. The comparison is between two things that are unambiguously the same type, so there is no reason to coerce either of them to anything else.

There's not even any reason to be attempting to parse the contents of either string (to see if either one might be intended to represent a number).

A string should be a string unless it can't be. I'd rather see string-to-number comparisons generate an error than have this behavior.

The Manual Is Wrong?

This page heavily implies that coercion only takes place if there's a type-mismatch:

If both operands are numeric strings, or one operand is a number and the other one is a numeric string, then the comparison is done numerically.

A warning-example on that page also clearly shows that while 0 == "a" used to coerce "a" to a number before the comparison (in php7), php8 no longer does -- which to my mind implies that in the problematic example which started this discussion, the coercion is taking place via a different mechanism, to wit:

Because the string contents can be interpreted as a number, the '==' operator inexplicably decides to convert it.

It's not even following the usual string-to-int "empty string is zero, anything else is 1" conversion rule:

echo ((int)'a' == (int)'b');
// ^ shows "1"
echo ('a' == 'b');
// ^ shows nothing

Even when both values have been parsed as strings and put into variables marked as type "string", these operators are peering inside the contents to see if they can be interpreted differently.

How does this make sense?

cc: @IceWolf
@cptwtf @ramsey
@Crell

@Girgias

Thanks for your input on this!

I don't know if the answer to this question is impossibly complicated, but what I don't understand is why type-coercion has to take place for comparison operators when both sides of the comparison are the same type.

TLDR: I think what is happening here is that the == operator has a clear preference for numeric coercion -- if a string can be interpreted as a properly-formatted number, it will do that. Only if a string cannot be interpreted that way will it reluctantly...

Woozle Hypertwin

@Girgias @IceWolf

That one always made at least some sense to me -- you're comparing with a number, so of course the string needs to be cast to a number.

But comparing two strings makes them into numbers?? Something rotten in the state of Denmark. What happens if you're comparing, say, two password hashes, and they both happen to begin with 0e?

nex

@woozle PHP devs aren't (merely) incompetent people who are unaware of certain things. Rather, they deliberately insist on not even trying to get anything right. This attitude is a precondition for working on PHP at all.

> But comparing two strings makes them into numbers?

[Edited to remove a part I'd gotten plain wrong; PHP isn't ‘stringly typed’.] Lots of languages are like this; it's a valid design decision. Though it's certainly possible to implement that better than PHP does.

Larry Garfield

@IceWolf This is why strict type safety is a requirement.

Frost, Wolffucker 🐺:therian:

@Crell Personally I don't mind dynamic languages, if that's what you're getting at. You can be dynamic without being boneheaded like this. (I think Perl does it a bit better, IIRC.)

Larry Garfield

@IceWolf You haven't seen anything until you've seen Javascript... :-)

Type juggling outside of a few very narrow conditions is just inherently dangerous.

Frost, Wolffucker 🐺:therian:

@Crell Oh we use Javascript all the time and I personally love it! Not so much for its type handling, it can be a bit wonky (insert holy trinity meme), but y'know.

I'll take some type wonkiness in return for JS's immense flexibility and unopinionatedness. It doesn't try to force you into any one specific pattern or coding style (*cough*Rust).

Frost, Wolffucker 🐺:therian:

@Crell Also JS isn't quite THIS stupendously boneheaded, haha.

Larry Garfield

@IceWolf + means both addition and concatenate, in a language with no explicit types.

Nothing in PHP comes close to that level of dumb. (And PHP has plenty of dumb.)

Frost, Wolffucker 🐺:therian:

@Crell really? *waves paw at the OP* :3

but personally I don't mind the + thing at all, since /usually/ it's clear from context. There are worse things!

Larry Garfield

@evert @IceWolf Because in practice it bites you about 10000x as often as "a string that happens to start with 0e will get coerced to 0 if you try to use it as a number."

Addition and concat are two of the most common operations. Using the same symbol for them when the types are inherently unknown is begging for trouble.

Evert Pot replied to Larry

@Crell @IceWolf well in the example it's not 'tried to use as a number's it's 2 strings being compared no?

Evert Pot replied to Larry

@Crell @IceWolf comparing 2 strings seems common as well :P

Glyph

@IceWolf @jalefkowit I earnestly don’t want to be a sneering elitist but I cannot help but see a *little* bit of a silver lining in a certain photography enthusiast’s public crash-out, in that it may damage the popularity of this language. If you squint, it’s really harm reduction (via doing lots and lots of harm)

Frost, Wolffucker 🐺:therian:

@glyph @jalefkowit Um, no

PHP is GREAT, actually. Why do you think I'm on its docs site!

Sure, it's got some wonkiness. Every language does. But PHP makes webdev and programming in general incredibly accessible. And since it's server-side, it makes lightweight, usable pages by default, unlike every """modern""" Javascript stack.

Glyph

@IceWolf @jalefkowit because of the profusion of design errors like this, php is quantitatively the most insecure high-level language still in use.

I acknowledge that its accessibility is something other languages and hosting environments need to aspire to, and that many people have found that accessibility empowering. but its prevalence is a real problem, complicit in some of the biggest breaches. “Wordpress sharing critical infra” is a cliché at this point

Glyph

@IceWolf @jalefkowit As far as “SSR is good”, I am a python guy who has been doing web dev in various capacities since 2001, no need for argument there :)

Frost, Wolffucker 🐺:therian:

@glyph @jalefkowit Wordpress is also Wordpress. When you run 40% of the internet, of course you're gonna get whacked with a crapton of hacking effort. (See also Windows.)

Frost, Wolffucker 🐺:therian:

@glyph @jalefkowit From what we hear, it's also often Wordpress plugins getting hacked - I don't know how often it's the core of Wordpress itself. (We've never used Wordpress and don't know much about it.) Plugins that for all we know, might be written by those newbie programmers that PHP lets actually program instead of just staring at an impenetrable wall, getting daunted, and walking away.

Should the stuff be secure? Absolutely! But the way to fix that is good tutorials and stuff that teach people how to write good code, as well as potentially giving PHP better defaults if those are bad, not "throw PHP in a ditch, use Python or whatever, it's Inherently Better". (I personally don't jive with Python because of its whole "personal style is bad, you MUST use the ONE TRUE WAY for everything" culture. It's not anywhere near as bad as Rust in that respect, though.)

@glyph @jalefkowit From what we hear, it's also often Wordpress plugins getting hacked - I don't know how often it's the core of Wordpress itself. (We've never used Wordpress and don't know much about it.) Plugins that for all we know, might be written by those newbie programmers that PHP lets actually program instead of just staring at an impenetrable wall, getting daunted, and walking away.

Glyph

@IceWolf @jalefkowit I acknowledge that that's a factor, but it's definitely not the only factor.

Anyway I don't need to yuck your yum; if you like it, and you don't agree with my take, that is your option. And while I don't mind putting that idea out there, I am not going to yell at you about it, if I am going to put effort into something, I will go make my own rickety pile of infrastructure more appealing and accessible, not just put down PHP 🙂

Tursiae

@IceWolf PHP truly is the YAML of programming languages.

Frost, Wolffucker 🐺:therian:

@tursiae Nahhh, it's the opposite, because it doesn't try to force one specific style on you!

Everyone else hates YAML because of its weird "do what you might possibly be guessed to potentially mean" semantics. I hate YAML because it straight-up bans us from using tabs in our /own config files/. We are not the same. :3

Frost, Wolffucker 🐺:therian:

@tursiae It's even worse than Rust's fucking "style warnings", and that's saying something!

Tursiae

@IceWolf I think we can all be glad it's not Go, though. Arrogant style guide, real syntax errors? Yes, compiler error. Same same.

Frost, Wolffucker 🐺:therian:

@tursiae Seriously, Go? Sheesh.

We read an article once shitting on it for other things but it didn't talk at all about that, and now I'm /really/ glad we never tried it out.

Tursiae

@IceWolf I tried it out a while back.. and when it refused to compile because I'd commented out a line, and now a variable was unused.. yeah, nah. Straight to the garbage pile.

Frost, Wolffucker 🐺:therian:

@tursiae Oh! Sheesh.

Yeah, that falls firmly in the "should be a warning, not an error" department IMO.

Tursiae

@IceWolf Cursed semantics? Restrictive syntax?

Both. Both is good. 😹

sabik

@IceWolf @glyph
I like how the explanation is also subtly wrong

#PHP

Netux

@IceWolf I thought we all memory holed that php even existed.

Frost, Wolffucker 🐺:therian:

@Netux PHP is actually pretty fuckin' awesome! It's supercharged templating, which makes it absolutely perfect when what you need is templating. My blog is 90% HTML with PHP include statements for all the boilerplate, a little loop for the homepage article list and the RSS feed, and that's...like...it. And from a visitor point of view it's indistinguishable from a static site, there's no client-side stuff involved at all.

And if you need more than just templating, it handles that, too. (We're currently trying to learn Symfony, and it's annoyingly overcomplicated but I'm pretty sure that's just frameworks in general.) Since it's all serverside it makes lightweight, usable pages by default, unlike every """modern""" Javascript framework.

@Netux PHP is actually pretty fuckin' awesome! It's supercharged templating, which makes it absolutely perfect when what you need is templating. My blog is 90% HTML with PHP include statements for all the boilerplate, a little loop for the homepage article list and the RSS feed, and that's...like...it. And from a visitor point of view it's indistinguishable from a static site, there's no client-side stuff involved at all.

Netux

@IceWolf true statements, but I'm more of an actual static or cgi guy. On the rare occasion I need something more complex I write the javascript (don't do this of you need help, most professionals only know some frameworks).

Php is just fun to rag on because so many weird things and bad decisions from the early days.

Frost, Wolffucker 🐺:therian:

@Netux Haha, PHP is also CGI so! :3

Yeah we skipped all the early stuff, only picked up PHP fairly recently. Apparently it's massively improved with 7/8.

Mateusz 🏳️‍🌈

@IceWolf Looks like a security vulnerability to me.

CyberFrog

@IceWolf@masto.brightfur.net yup, PHP type juggling attacks are an entire rabbit hole... another fun one: your password comparison mechanism very likely has a timing attack embedded somewhere, unless you use a framework or special newer PHP functions built for security

Siaržuk

@IceWolf Everything is fine, you just need to understand the specifics and capabilities of the programming language

eurosat7

@IceWolf it's fine.

3v4l.org/3uDep

```php
declare(strict_types=1);
echo '0e99' === '0e88' ? 'bad' : 'good';
```

> Output for 4.3.0 - 4.3.11, 4.4.0 - 4.4.9, 5.0.0 - 5.0.5, 5.1.0 - 5.1.6, 5.2.0 - 5.2.17, 7.0.0 - 7.0.33, 7.1.0 - 7.1.33, 7.2.0 - 7.2.34, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.31, 8.2.0 - 8.2.27, 8.3.0 - 8.3.16, 8.4.1 - 8.4.3

>> good

@IceWolf it's fine.

3v4l.org/3uDep

```php
declare(strict_types=1);
echo '0e99' === '0e88' ? 'bad' : 'good';
```

> Output for 4.3.0 - 4.3.11, 4.4.0 - 4.4.9, 5.0.0 - 5.0.5, 5.1.0 - 5.1.6, 5.2.0 - 5.2.17, 7.0.0 - 7.0.33, 7.1.0 - 7.1.33, 7.2.0 - 7.2.34, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.31, 8.2.0 - 8.2.27, 8.3.0 - 8.3.16, 8.4.1 - 8.4.3

hellhound gayming

@IceWolf HUH??? oh god does php seriously juggle strings BACK into integers even if both operands are strings

Frost, Wolffucker 🐺:therian:

@suetanvil PHP isn't an inherently bad language, though. Sure, it's got some wonkiness, every language does. But its good things more than make up for it IMO.

I will not stand for PHP hate over here!

Chris [list of emoji]

@IceWolf

I don't know PHP and so can't really critique it but nothing that I've heard about it makes me want to learn it either. There are certainly good reasons to use it but I have none of them.

Antwan van Houdt

@IceWolf thank you I wanted to start my day with a nightmare!

Irenes (many)

@IceWolf notice also how using a stronger hash doesn't make the issue go away

cthululemon

@IceWolf

I don’t know anything about PHP’s ‘type juggling’, but is this something where the md5 function should help by outputting a text/string type that wouldn’t require juggling?

Michal Špaček

@IceWolf Hi, I have generated those two strings and that exact comparison more than 10 years ago now, and since then I and many other people have generated some more for other algorithms as well, from CRC32 to SHA-256. I keep all of them here github.com/spaze/hashes Used the so called magic hashes to discover MD5 (or even plaintext) in sites and places where it shouldn't really be used, like password storage :-)

Mᴀʀᴋ VᴀɴᴅᴇWᴇᴛᴛᴇʀɪɴɢ

@IceWolf PHP has always struck me as one of the worst things ever. Not just the worst programming language mind you, but in fact one of the worst things of any kind, ever.

janusfox 🍅

@IceWolf hah yeah. Professionally, this is why we === all the things and have safety rules to find stuff like this. Thankfully, I didn't see too many of these when php'd for a living. Madness!

Robbie Coleman :verified:

@IceWolf I first needed to learn/use PHP in 2010 at a small startup. The more experienced dev mentoring me continually referred to it as a Clown Car language.

Florck

@IceWolf

@CedricLevasseur

C'est pas le typage dynamique que vous détestez, c'est php.

#PHP

Reiner Jung

@IceWolf me adding this to the list why PHP is a broken language.

kaiserkiwi :kiwibird:

@IceWolf That's why you don't compare without type safety.

If you don't know PHP, you do this with === instead of ==

blabaere

@IceWolf "SO CURSED" ? Surely you mean "this is pretty standard" since Excel would do the same.

Ret

@IceWolf holy fuck this thing is STILL GOING :blobfoxcrylaugh:

Volpeon

@IceWolf Who knew I'd be happy with JavaScript's type shenanigans because it at least isn't this bad? ​:drgn_woozy:​

Json Doh

@IceWolf it's "times". Zero *times* ten in the power of something. '0eX' = 0 * 10^X

sohpia

@IceWolf@masto.brightfur.net this is the kind of bug that should only arise in a toy language written by a twelve year old with no types other than a string

Malcolm Herbert

@IceWolf ... am I the only one that looked at that quote text in the image and thought that was a ChatGPT grab just on the face of it? I mean, now that I know it's PHP it still has a kind of horrible fascination, but at least that's of human generation ... :eyeroll:

Go Up