PHP's Oddities

(flowtwo.io)

33 points | by thejoeflow 3 days ago

12 comments

  • mfonda 1 hour 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).

    • mdavid626 36 minutes 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.
      • mfonda 19 minutes ago
        An “array” in PHP is an ordered map.
    • shevy-java 52 minutes 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.

      • xp84 22 minutes ago
        > objectively

        > Ruby is dying

        How exactly do you define these “objective” criteria for such sensationalism?

      • customguy 36 minutes 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 1 minute 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.

      • skydhash 13 minutes ago
        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.
      • greybeard69 39 minutes ago
        Mate, not to be rude but your entire comment isn't based on factual analysis; it's a rant about unrelated languages.
  • Ayesh 1 hour 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.

    [^1]: https://www.php.net/manual/en/class.splfixedarray.php

  • chuckadams 45 minutes 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.

  • t1234s 15 minutes ago
    The last part about "$" is epic.
  • makeitdouble 1 hour 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 36 minutes 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 1 minute 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 53 minutes 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.
  • spiderfarmer 1 hour ago
    I think the “bad rep” is coming from developers that stopped developing themselves.
    • chuckadams 27 minutes 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.
    • esskay 21 minutes 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.
    • fg137 16 minutes ago
      No. Bad rep comes from developers who used other languages and never looked back.
    • frutjgma 36 minutes ago
      I did PHP for 15 years. Modern PHP looks good but I still wouldn't go back.
  • nasretdinov 1 hour ago
    if("0") {} being equivalent to if(false) {} still gives me nightmares even though I've stopped using PHP for at least 6 years now :)
    • moritzwarhier 1 hour ago
      I knew this in and out, but as a Full-Stack PHP/Symfony/Frontend/JS guy who pivoted to mainly TS for b2b stuff, I still have to occasionally enter

        !""
      
      
      into the browser console just to be sure, during code reviews :D
    • kif 1 hour ago
      Also `empty("0") === true` is a common gotcha.
  • shevy-java 54 minutes 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 9 minutes 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.

  • ceejayoz 1 hour ago
    Every time I work in another language I miss PHP’s arrays.
    • lazka 3 minutes ago
      That array keys are auto-coerced to integers has bit me multiple times.
    • conceptme 52 minutes ago
      Basically every other language has the same functionality (or better) as a hashmap.
      • ceejayoz 44 minutes ago
        I’m well aware of them. I’m not sure I agree with “better”.
    • rokkamokka 1 hour ago
      They are an incredibly versatile tool for sure. Even more so wrapped in a Laravel Collection
    • bakugo 1 hour 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.
    • spiderfarmer 1 hour ago
      Absolutely. If you don’t know PHP arrays aren’t actually arrays, the other languages feel inferior.
  • bakugo 57 minutes 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.