Hacker News new | past | comments | ask | show | jobs | submit login
Modern PHP features – PHP 8.0 and 8.1 (laravel-news.com)
182 points by mikece on Oct 27, 2022 | hide | past | favorite | 119 comments



Related:

Choosing PHP in 2022 and beyond - https://news.ycombinator.com/item?id=32280057 - July 2022 (80 comments)

Whats New in PHP 8.2 - https://news.ycombinator.com/item?id=31153698 - April 2022 (136 comments)

Modern PHP - https://news.ycombinator.com/item?id=30786927 - March 2022 (263 comments)

PHP – The Right Way - https://news.ycombinator.com/item?id=30219984 - Feb 2022 (332 comments)

PHP in 2022 - https://news.ycombinator.com/item?id=29889705 - Jan 2022 (306 comments)

Others?


The Match Expression feature is interesting. According to the PHP docs, it can even handle non-identity expression, although the approach seems a little hacky:

https://www.php.net/manual/en/control-structures.match.php#e...

    <?php

    $age = 23;

    $result = match (true) {
        $age >= 65 => 'senior',
        $age >= 25 => 'adult',
        $age >= 18 => 'young adult',
        default => 'kid',
    };
The above example will output:

    string(11) "young adult"


I use `match` like this a lot now, often with PHP 8.1's enums[1]. It makes it easy to write clean dynamic accessors, without all the extra blocks required with multiple `if` branches:

    /** Check the status of this Task instance. */
    public function status(): Status
    {
        return match (true) {
            $this->inProgress() || $this->isInReview() => Status::Started,
            $this->isApproved() || $this->isRejected() => Status::Finished,
            default                                    => Status::Planned,
        };
    }
[1] https://stitcher.io/blog/php-enums


I've seen the same hack done with `switch (true)` in pre-PHP8 code (and other languages) as well.


match is basically a cleaner, more succinct switch, I hardly ever used switches before, though I use match a LOT.

    switch ($i) {
      case 0:
        echo "i equals 0";
        break;
      case 1:
        echo "i equals 1";
        break;
      case 2:
        echo "i equals 2";
        break;
    }
verses:

    $output = match($i) {
       0 => 'i equals 0',
       1 => 'i equals 1',
       2 => 'i equals 2',
      default => 'i is unknown'
   }

   echo $output;
the result is basically the same, but match is more of an enclosed switch that just returns instead of does side effects, then you can do what you like w/ that.

Ymmv, but match is a great code saver, and is very nice for enums and methods on enums.

Before match i'd probably do something like:

    $output = 'i is unknown';

    if($i == 0){
        return 'i equals 0';
    }

    if($i == 1) {
        return 'i equals 1';
    }

    if ($i == 2) {
        return 'i equals 2';
    }
    return $output;

Not really, I'd probably do..

    if($i) {
        return "i equals {$i}";
    }
    return 'i is unknown';
but the point was if I had to check for multiples to match something, then do something else, that's how I would do it... albeit this is a simple case with a better solution.


What am I missing? Isn’t that the output that makes sense? Or am I misunderstanding your comment about it being hacky?


I think they're talking about the "match (true)".


You are correct. This is what I was referring to


PHP is improving, slowly, but it is still way better than the PHP 5.x days. If your last memory of PHP is from 5.x, it's a very different language now - even if it still has oddities, quirks, inconsistencies, and footguns, but PHP is still not the king of footguns - C++ is.

I would ask though that if any PHP developers are reading this, I would love a feature called `modern_syntax` or similar which represents a major break in backwards compatibility in exchange for modern language conventions (i.e. no `$` prefix on variables, no `;` ending lines, perhaps some renamed core functions for consistency - we can have a debate about this). Kind of like how we have `strict_types`. Or, perhaps it could be invokable on a per-file basis, by using `<?phpmodern` instead of `<?php`. Then you could have your traditional PHP framework (say, Laravel) which has years of work on it remain intact while having a modern-PHP layer of your app-specific code on top.

That would help, I would argue, with killing many of the PHP-specific criticisms while allowing some degree of backwards-compatibility.


> That would help, I would argue, with killing many of the PHP-specific criticisms

I don't see why appeasing critics should be the goal of PHP.

Removing $ and ; signs doesn't help me at all. I actually like the "$" sign. Maybe little bit less ;, but I don't really notice it.

But I would certainly notice the mess of splitting language syntax into two separate branches.

Breaking changes in language are not fun to address and take away the time from building features.

I would be a lot more happy with generics. Or scalar objects, something like:

$string = "abc";

var_dump($string->length()); // int(3)

var_dump($string->startsWith("a")); // bool(true)

https://github.com/nikic/scalar_objects

That would make PHP standard library a lot easier and fun to use.


I don't think people's proglem with PHP are the semicolons and $ variable declarations.

It's mostly legacy stuff like built in function naming.


The time when semicolons become optional in PHP, it'll probably be my primary language over Typescript.

I just don't get why people tend to type the semicolons in JS/TS when they don't need to like they don't know it's optional.


I dunno, I used to work in PHP and I came to really loathe all the $ and ->. Like I get it’s just aesthetics but it bothered me how unnecessary they are.


My last memory from PHP is 8.0 and I would still call it the king of footguns. I stopped coding PHP at 5.X and then after many years came back to 8.0 which everyone said was supposed to be better, and while it was better it was not much better. It is still a language full of footguns and unexpected behavior.


Do you want to elaborate a bit more? Which features that you saw as footguns.


I'll bite.

    ```
    >>> (bool)"1";
    => true
    
    >>> (bool)"0";
    => false
    
    >>> (bool)"false"
    => true
```

(there are plenty of other things like that; the default call-by-value is also unexpected)

Also: Laravel has plenty of "magic" ie things are intercepted via runtime reflection and then rerouted into something that hopefully "does-the-right-thing". It obfuscates control flow, causes unexpected side-effects and confuses IDEs and developers alike.

Even the popular frameworks have combinations of subawesome code and silly ideas. Just the latest example I ran into:

    ```
    int append(string $path, string $data) /* the signature of the Filesystem facade */    

    /* the implementation in FilesystemAdapter: */

    public function append($path, $data, $separator = PHP_EOL)
        {
            if ($this->fileExists($path)) {
                return $this->put($path, $this->get($path).$separator.$data);
            }

            return $this->put($path, $data);
        }

    ```

    - It's not correct as it will add (ffs why?) a newline in between the files.
    - Performance wise, this is bloody awful.
    - however, you *can* specify the separator in any call as the facade interface is just documentation and is bypassed via reflection (but that confuses your IDE)


Right, these are awful I totally agree.

There were even some incorrect type casting specially with numbers and "numeric strings", which were fixed recently.

I use strict typing in every new piece of code I work on, which largely fixed the problem.

Laravel, while being extremely popular, isn't exactly the flagship choice for "quality code", not even Laravel claims it to be. Symfony framework gets a lot of things right, and IMO the showcase for more modern PHP.


Some people absolutely LOVE their semicolons. As a fan of Python, I don't really get it. But I think you would have to pry the semicolon from some people's cold, dead hands.


TBF there are languages where the semicolon have important semantics meaning.

Not needing to `\` every other line is also nice.

And then there's javascript, of course, eating glue in the corner as usual.


Right - I'm only throwing the idea out there of a "modern PHP" layer that breaks some old conventions for more modern ones, but it would be opt-in and not too different, so that old code doesn't run into massive compatibility issues, and so that the "modern PHP" can be gracefully added (or not added) into any application where the developer has a different programming background, so as to allow a smoother transition.


I'm a fan of both but when I started with Python, after years of PHP, it took me a minute to get the indentation and line breaks in the right places so it would execute a simple script. This may have improved but it was really hard to find where I did something wrong with format and with PHP I could easily spot a missing $ or ;. Going back to PHP, the $ and ; made things look messy at first. With either, if you stick around long enough it just becomes muscle memory and you don't even consider it overhead of writing code and your eyes adjust to the syntax. I find it a non-issue these days.


Honestly this is something I love about Kotlin/Rust/Go. You either have them, or you do not. There are no time-wasting silly arguments over their veracity... just because a language makes them optional.


In Rust, they are not optional though. The semicolon turns an expression into an expression statement.[1]

[1] https://doc.rust-lang.org/reference/statements.html


> The semicolon turns an expression into an expression statement.[1]

And more relevant, this has the effect of suppressing the expression's value when used in tail position of a block, by moving from the second to the first branch of the block expression grammar: https://doc.rust-lang.org/reference/expressions/block-expr.h...

Which also explains why it sometimes doesn't work e.g. in non-block match arms, because they're not blocks, and thus don't accept statements.


Right, that's exactly what I'm saying. They're NOT optional in any of those languages. Some of them (Kotlin and Go) don't have them, but there is no argument.


Oh, I misunderstood. I don't know Go very well but they do seem optional there:

    $ cat with_semicolons.go                $ cat without_semicolons.go
    package main                            package main
                                    
    import "fmt"                            import "fmt"
                                    
    func main() {                           func main() {
        var x = 3;                              var x = 3
                                    
        x += 1;                                 x += 1
                                    
        fmt.Printf("%d\n", x);                  fmt.Printf("%d\n", x)
    }                                       }
    $ go run with_semicolons.go             $ go run without_semicolons.go
    4                                       4
    $                                       $


Go requires every line to end in semi-colons if you look at the EBNF in the specification, but the compiler will insert them for you. It's kind of a subtle detail, but it shows up in some places, for example the following being a compile error:

  if true {
  }
  else {
  }
Because the semicolon is inserted when the last character on a line is "one of the operators and punctuation ++, --, ), ], or }" (among other cases, see https://go.dev/ref/spec#Semicolons). So you need to use the } else { style.

In practice, you can just leave of the semicolons at the end of lines (gofmt will remove them) and it's as if semicolons are not required, but if you want to get all technical about it then they are required.


i like using them in php and not javascript, it's almost like a switch, that tells me we're in a new context, don't write php here.

Python is nice, but the whitespace can often have issues, and formatters can be wonky in vscode... It's pretty though, like rails. Still, I'm most comfortable w/ Laravel/php so will stick w/ that for time-being.


I always felt they focused on the wrong thing with all these improvements. PHP 5 as a language after 5.4/5.5 or so was okay; not great, but okay, or at least workable enough. It has footguns and issues but you can deal with those with a bit of practice. I always considered the standard library to be a far bigger problem.

For example, as near as I can tell I still can't have fopen() tell me why it failed; it just returns False and one of those magic E_WARNING things. This is simple stuff, but also pretty critical to correctly implement some basic file I/O of the kind that you can do in ... pretty much any other language.

Language blitz is nice, I guess, but not really "needed" as such. PHP5-the-language never really prevented me from doing things, PHP5-the-standard-library did, and from the looks of it, it still does. Things like no $ or ; are non-issues, and a good example of the wrong focus on syntax and "blitz" rather than things that actually matter.

I'm not expecting things to be free of inconsistencies, oddities, historical baggage, etc. I just want ... basic functionality.


I don't understand what's wrong with breaking changes. Do they not happen in php major versions anyway? Why not fix the parameter ordering and built in function names whilst you're at it? Seems odd to me.


1. it requires that all your users churn their codebase for something which doesn't directly add value

2. it introduces errors which can remain latent or unfound for a while, especially when you're just changing the parameter ordering of a function in a dynamically typed language


> Do they not happen in php major versions anyway?

PHP has actually been awesome at preserving backwards compatibility.

I wrote a server, when PHP 4 was still the cutting edge, and it still works, now, at 8.1 (although I know that it is being rewritten, in order to leverage things like Laravel).


I set up something for someone in 2003/2004. It was largely PHP4 code that got a bit upgraded to 5.0. We lost touch.

I got a call at end of 2017 saying "this isn't working". Someone else had taken over hosting and been upgrading PHP along the way. There was finally something that broke (some weird dynamic object stuff that was making up for some PHP4 shortfall at the time) and... I did some small patch to get around it but suggested they have someone rebuild, either in PHP 7 or ... any tech from 2017. Just needed to migrate relatively simple database over.

I pointed out that they had basically 13 years of hassle-free system - that's generally a bit outside the norm for that sort of thing, and... that was the recommendation they gave back to their org's board of directors (small non-profit sort of thing).


There are breaking changes - but they tend to be very granular, and typically occur after a few rounds of deprecation. Renaming a bunch of core functions, and doing something radical (like, deleting the `$` prefix requirement) would break every single line of code, in every function, and in every library. It would be Python 3 all over again.

Whereas... imagine if Python 3 rolled out simply as an optional "mode of operation" on top of Python 2. If you opt-in on this particular file, the syntax requirements are different. Obviously that would prevent some deeper changes, but it would help modernize the language without as much of a radical break.


> Whereas... imagine if Python 3 rolled out simply as an optional "mode of operation" on top of Python 2.

It's easy to imagine: Python 3 would not have existed. At all.

Python 3 changed fundamental language semantics in ways which went way beyond syntax, that's why the core team shoveled so many changes in: they were breaking the language in a way which didn't brook mere syntactic opt-ins, this meant additional changes were minor issues easily handled compared to the fundamental difficulty of overhauling the language's entire string model and significant parts of the object model.

> If you opt-in on this particular file, the syntax requirements are different.

You're about 20 years late to the party, welcome to Python 2.1: https://docs.python.org/3/whatsnew/2.1.html#pep-236-future-d...


Sometimes it's fine, sometimes it's not. And PHP has VERY FEW breaking changes in general.

Think about something like WordPress, it powers so much of the internet, they're not going to be doing massive rewrites so that PHP can fix some legacy issues.


"I don't understand what's wrong with breaking changes. Do they not happen in php major versions anyway?"

See python2 vs python3. It almost ended the language IMHO.


PHP is getting good, sometimes I feel better than Typescript even.

You can't do named parameters in Typescript unless you put every parameter as a dictionary and destructure it at the method.

I just want array of class type hinting or else every return value returning an array of a class is treated as an array of mixed values unless you complement it with PHPdoc.


>PHP is getting good, sometimes I feel better than Typescript even.

PHP is good, and has been for years. The Zend VM is probably top 3 in the world next to JVM and V8. Incredibly more performant than Ruby or Python. The bad rap that PHP got in the early days is from all the pre-7.0 spaghetti code that was written. It’s a solid choice nowadays.


Maybe outside the top 3 if we count the BEAM VM too.


Actually, I think most of the bad rap comes from the community. A community where the majority still thinks that using the CodeIgniter framework is a reasonable way to develop in 2022.


I'm not sure what "community" represents here, but I don't think that CodeIgniter is the majority in any shape or form.

The _vast_ majority would be Laravel and Symfony.


imho, as someone who was almost a Ruby on Rails dev, because of gems, and the ease of adding packages. When laravel hit, and composer got popular that was a moot point, and php being more widely used on shared servers which was more popular w/ small clients for being 'cheap', I went w/ laravel and honestly laravel feels way more polished...

For example even now with Rails you need to role your own authentication system (95% of the time that's devise) and a lot of other things baked into Laravel you need to figure out on your own, and I think they've switched asset provisioning/build systems a bunch of times, laravel has a few but each one sunset the previous mostly, except mix and vite are kinda still both in production, vite I think will probably become the defacto before long in most new projects.

PHP is beautiful since 7.0, and keeps getting better. Before 7 and Before composer it was just a hackety POS, and didn't look appetizing at all, there's definitely sexier languages/frameworks out there that have 10x the reqs/second than php can get, but there's costs w/ that - and that's usually length, and time to market.


> I just want array of class type hinting

This is pretty much the only thing I still need to use PHPDoc for these days... I guess it shows how far things have come :)


Isn't that supposed to be something they're working on? I think I read that somewhere. Maybe in the 9.0 release though.


might as well ask this here: does anyone have any recommendations for minimalist PHP frameworks, in 2022? I have a hand-rolled PHP site that's been getting quite a bit of traffic and it needs quite a bit of internal reworking to make things more performant and such. I'm looking at evaluating Fat-Free Framework as it seems to be more or less what I'm looking for, but I haven't seen any recent opinions anywhere about it (aside from top-ten lists, which is all you can find when you search google for such opinions).

all I need is routing, caching, possibly some light database abstraction, and possibly some light templating stuff (but PHP is a templating language, and that's how I'm currently using it). I don't want MVC or any of that, just the absolute basics.


Fat-Free might be your best bet if you really want to go with a framework, but another possibility is using libraries that will do what you want rather than a framework, e.g.:

Routing - FastRoute

Light DB abstraction - if PDO alone can't cut it, maybe Doctrine DBAL (without the ORM)

Templating - rolling your own is pretty easy if you feel you have the discipline not to stuff business logic in there

Part of me appreciates how PHP is being driven forward by Laravel and friends; another part of me wonders if PHP has become a cargo cult version of Java to the point where many frameworks, and even libraries, are tremendously over-engineered.


I haven't used PHP in a lot of years. I just took over a team that uses it so I thought, "let's play with it a bit". After looking at Symfony (and not hating it) I thought, "this looks so much like Java+Perl (with some C++ thrown in) why not just write Java/Kotlin SpringBoot at this point??"


These things stand out to me:

(1) Dead-simple deployment story across a wide variety of needs. You want to throw your app's filetree in a directory on $10/mo hosting via SFTP? Easy peasy. You want turnkey autoscaling cloud deployments you don't have to build infra for? People will sell it to you.

(2) Beginner/junior friendly culture. Really, everywhere along the learning curve.

Both have long been PHP strengths. #2 was also a weakness for a long long time, that's how a lot of bad practices and blind-leading-the-blind happened. In the last 10 years that's been very much changed.

Java has also changed, of course, and selling people easy deployment has become industry-wide bread and butter, so you're probably correct that some gaps have narrowed, but AFAICT they haven't gone away.


Yes, with Java, the advent of the "fat-jar"/"uber-jar" deployments with an embedded server is far different than the massive deployable war to an application server stuff from yesteryear. And I can see that. PHP definitely allows one to "ladder up" a whole lot easier than some other languages.

Once we get into these large "batteries included" frameworks like Symfony and to a little lesser extent Laravel, it almost seems like that simplicity disappears.


If you don't want a framework, why do you want a framework? Picking an old, barely-used framework because it pitches itself as "fat-free" is a mistake: either use a good, modern, widely-used framework (like Laravel or Symfony) and benefit from a cohesive framework experience OR skip the framework altogether and grab best-in-class packages for each of the individual things you need and wire them together yourself. You could probably get all of what you need out of PHP League's packages: https://thephpleague.com/


I'm not looking at F3 because of how it pitches itself, I'm looking at it because I skimmed the docs and it looks like the closest thing to what I'm looking for.

right now my whole website is hilariously one giant PHP file (CSS and Javascript both embedded, lol), with a giant switch branch on the after-the-domain part of $_SERVER['REQUEST_URI'] (there's only a few branches because the landing page is the main bulk of the site). the website was rapidly prototyped, and I hadn't used PHP since like 2008. I don't have any interest in overly-complex ways of doing things (using classes for everything, using the MVC pattern), but I do want slightly better organization. I had to monkey-patch in some rudimentary caching on the database-intensive landing page when we started getting lots of traffic, and anything that would make that easier as I add more functionality (that also should be cached) to the site would be great.

oh, and I'm running the whole thing on IONOS shared hosting and for business reasons it's not really feasible to use anything else at the moment.

so this is why I'm looking at evaluating F3 or any other similar "minimalist" frameworks—I don't want or need a super opinionated complex rejiggering of my existing code, but some small amount of better formal structure would be nice.

also, I'm not using any other packages or libraries or anything, except for Stripe, which was incredibly easy to integrate.


Just an (unsolicited) opinion - MVC pattern if one of the few mainstays, and it's like that for a reason. It might (or might not) fit your use case, but it is hardly complex. Also any other dev looking at the code wil probably know it.

Apart from that, I would skip framework if I were you. Web is littered with abandoned PHP frameworks which were all viable at some time. If it already works, just clean it up, refactor as needed and identify + resolve any performance bottlenecks.


I appreciate the unsolicited opinion regardless, but yeah MVC is just too complicated for what this website does. I may end up just going with some kinda routing package instead of a framework, not sure yet.


In that case I'm not sure I'd use a route package either. If it is very simple, you can create separate files for each page and include them based on the path or query string. Few (or 0) dependencies can also be an advantage, as it will be easier to update and maintain


Have you looked at Slim (PHP microframework)? --> https://www.slimframework.com/


Can I recommend you try something with laravel, just for fun?

Build a small app using laravel + filamentphp (admin/backend): https://filamentphp.com/

In one day or less you get an amazing backend system that's so easy to manage it drives me crazy how hard I had to work for the same functionality before.

Filament kinda made me fall back in love w/ Laravel to be honest.


Slim is really nice. We've used it with great success in several production systems.


Slim is the other one I'm looking at. in a just world I would be able to type "slim vs fat free framework" into google and see at least some forum posts or something comparing and contrasting the two, but all I get instead is top-ten lists that mention both without really giving a good comparison.


I've never heard of F3 so I can't compare and contrast, but Slim is definitely my go-to for projects like the one you describe. Just enough boilerplate to handle the basics, but not a ton of framework-specific quirks and conventions to learn.


F3 is pretty good, I still run it in a few applications. It surprisingly held well with PHP 8 migration as well.

However, the reason why I don't use F3 anymore is because of the god-object model. You are pretty much carrying around the `Base` class everywhere, and you are golden as long as you stick with what's provided with F3. However, it's difficult to adapt to more modular applications that you mix and match template engines, routers, DBALs, and a DI containers.

I can HIGHLY recommend Slim PHP. The version 3 is a little bit opinionated, and the 4.x is more modular. So pick your poison.

F3 has a ton of functionality in a surprisingly small package. If F3 covers all of your requirements, go with F3. My grudge with it is that it's not as easy to decouple as Slim, which mostly stays away after it does it's thing.


Have a look at Framework X (https://framework-x.org). It's barebones, but provides routing and basic request/response handling to build your own stuff upon. It's based on ReactPHP so you can use it as standalone service or use it in shared hosting with FPM, whichever suits you.


I went with Slim for a recent light project and then tore everything out and used the stdlib only, and then I realized I didn't even really need even a routing library in my case. It worked out great, but it's probably unusual. For a really small project, you likely just need a routing lib.


Not sure why you want a framework if the only thing you’re looking to make things more performant. Raw PHP is going to always be faster unless it’s a framework based on C modules.

I’m not saying don’t do it and I know this isn’t answering your question but I’d really think about if a framework is what you’re looking for.

Where are your bottle necks? I’m assuming this app is a monolith?


Used to be Slim, but I haven't used it recently (2-3 years). Worth to take a look.


Wordpress is a framework as of this point. Just put one up for your site. Maintaining a custom made website is not worth the hassle unless you have a very, very specific implementation that requires it.


WordPress could more accurately be described as three goblins in a trenchcoat, masquerading as a "framework".

If all that's needed is a brochure site or some light ecommerce, it's servicable.

But the moment youre building an app, all that cms and legacy style code stuff becomes an anchor around your neck.


> WordPress could more accurately be described as three goblins in a trenchcoat, masquerading as a "framework".

It runs practically 50% of the web now. From gigantic sites like Reuters to CNN.

That sounds pretty legit as a framework to me.

> But the moment youre building an app, all that cms and legacy style code stuff becomes an anchor around your neck.

They don't. You never have to worry about that 'legacy' style code, cms, and actually practically anything. WP prioritizes backwards compatibility over anything else. So instead of jumping through the hoops of another framework's breaking updates, you can concentrate on your own app.

Thinking of WP as 'a web framework as a service' is a much better way to describe it. Not even a 'framework'.


It's pretty decent in headless mode, with something like Gatsby fetching data using its GraphQL API. (and surprisingly I had zero issues explaining to clients that now their site needs to be "built" first before they can see their changes live)


best barebones php framework is symfony.com they also have the best components that everybody uses


Another option is Laravel Lumen


Lumen is being deprecated due to PHP and Laravel performance improvements that make it largely irrelevant. https://lumen.laravel.com/docs/9.x

> Note: In the years since releasing Lumen, PHP has made a variety of wonderful performance improvements. For this reason, along with the availability of Laravel Octane, we no longer recommend that you begin new projects with Lumen. Instead, we recommend always beginning new projects with Laravel.


Lumen is officially not recommended. If you think you need Lumen, just use Laravel and rip out the things you don’t need. It’s much easier to pare down these days than it was when Lumen was released


symfony flex



"None capturing catch blocks"

Since when do you not need the actual error object in the catch clause? The example is one of a bad habit of making debugging hard by not telling what exactly happened. Maybe it timed out, maybe the connection was refused, or maybe it returned 404 but I guess the author doesn't care what the detail is making it harder to reach the source of the problem.

Not sure how this feature made its way in.


This information is often communicated by the type of the exception itself. Maybe it timed out: TimeoutException. Maybe the connection was refused: ConnectionRefusedException. Maybe it returned 404: NotFoundException.

Depending on the specifics of how it's handled, you may or may not need the actual error message. For example, in production you may want to implement some sort of logic (retry, display friendly error message, etc.), none of which needs the actual error message.

This feature isn't unique to PHP. Other languages with Exceptions, for example C# and C++, have this exact same feature.


> Not sure how this feature made its way in.

It's possible the language was just following usage rather than leading it. Regardless of whether or not it's right, I commonly see something like

    } catch (\Exception $e) {
        // no-op
    }


JavaScript did that too in the last couple of years. It's thoroughly confusing that we'd want to catch an exception and toss away all knowledge of WHAT exception was thrown. Unless one really just wants to log, "bad things happened".


This happens all the time. You're doing something risky, which has no consequence to the rest of the system if it fails. Sure you could catch it and log it out, but why?


Also, often you don't need more info. Like in some contexts, dividebyzero...you have all you need.


"Constructor property promotion" - so the parameters of your constructor now automatically become properties of the class? So, for saving a few keystrokes in some cases, they have introduced a feature that I imagine is extremely confusing if you're not familiar with it (parameters go in, and then nothing happens with them - whaaat)? And what if I don't want to have my constructor parameters as properties, maybe because I process them somehow in the constructor, and set some other properties instead?

And a colleague of mine is a huge fan of the new "match" keyword - he's working on a sports management application, and of course he had a "Match" class, used everywhere, which he had to rename...


> And what if I don't want to have my constructor parameters as properties, maybe because I process them somehow in the constructor, and set some other properties instead?

Then you don't use property promotion. It's optional: it only happens if you add a visibility modifier before the parameter name.


they only get promoted if you add private/public/protected before the parameter


Ah, ok, yeah, thanks, guess that makes sense :) - and may also give someone who doesn't know this feature a hint as to what's going on...


Beyond that, this is becoming more and more common in other languages. Anyone who ever touches TypeScript will immediately recognize it, for example, or (with a bit more of a stretch) Java/C#/Kotlin/Scala data classes and records.

Feature convergence is only a bad thing if you're not spending enough time in other tools to recognize them.


from my experience from learning typescript this is really easy to pick up on your own


Re: Constructor property promotion

Class Access Modifiers (mixin selectors) are now potentially/usually going to be in 2 places. The object level and the constructor level. Property promotion will land somewhere in PHP-FIG eventually as recommended or not, and then you'll have to know it regardless of how often you use it. Ironically, PHP is feeling (and looking!) more and more like Perl.

Java has inspired auto getter/setter support in the IDE (even PHP IDEs), so why does this need to be a feature instead of an IDE extension to type it for you at the class level? To be fair, @AllArgsConstructor is a thing and it's been great for Java, which is meaningfully different and more succinct. I guess I can give a minimal kudos for not making it an annotation. shrug

Re: Union Types, Unpacking, Enums, et al aren't bad, although I have smaller issues with some of it. What I think doesn't matter that much as I don't think I'll ever go back to PHP, despite decades of experience with it.


Development is primarily about automation, so I expect more and more tooling support to aid in working with more complex applications that have grown to absurd sizes (in terms of LoC). I expect, long after I'm dead, all languages will be tightly bound into IDEs, bringing us full circle (LISP, erlang, et al).


i don't think so. we're moving towards language servers, so as long as your ide speaks langserver, you'll have a few choices


>And a colleague of mine is a huge fan of the new "match" keyword - he's working on a sports management application, and of course he had a "Match" class, used everywhere, which he had to rename...

Namespace?


If match was made into a hard keyword, there's no fixing it, it just becomes forbidden as a bareword.


Well yeah, I guess he could have prefixed every usage of the class with the namespace, but probably decided to rename it to have less verbose code...


This would be unneeded if PHP wouldn't have case-insensitive identifiers, right?

But such a breaking change would of course be too much to ask


Then just do it. Nobody forces you to use promoted properties


Sometimes all I want to do in life is build some sort of community website with PHP. I might even upload it through SFTP the first version. Maybe when I retire and don’t care about employability anymore I’ll be able to make that dream a reality.


PHP is awesome.

I’ve been using it since my early career and didn’t switch to other stack… it’s been evolving like a crazy lately.

The only thing I miss in the language right now is generics.

PHP is not your ugly language any more, quite some time to be honest…


Why do you need generics? It’s dynamically typed.


I've asked this question a couple of times on stackoverflow, but it get's removed, even though it is a legitimate question to me:

I have found that working in a team with php has made it, sometimes, difficult to catch bugs that a typed language would prevent at compile time.

How do larger teams work with php and frameworks like Laravel and prevent errors that are related to type-checking?


I'd like to combine and expand on a few answers you got. Firstly:

> bugs that a typed language would prevent

This sounds like you think PHP isn't typed. It is, and with 8.1 (and even more so 8.2) the type system isn't exactly Haskell (ha) but gets much stronger than it historically has been for PHP.

You enable a feature called strict_types which enforces these rules.

Then you have a layer of even more powerful type checking and analysis which, though not enforced at the runtime level, is picked up and validated against by your IDE's real-time (or async external) static analysis tools. This is partially in phpDoc and there are various ways to do it.

Then, besides static analysis with popular tools like PHPStan or Psalm, there are nice inspection tools like EAInspections, Sonar, etc that check for hundreds of possible errors, code smells, style issues, etc.

Large, professional PHP codebases are not a big wild west of implicit coerced dynamic types. For my own projects, I consider any avoidable reliance on PHP's dynamic typing a bug, i.e. casting null to bool in conditionals.


I wrote awful untyped PHP 5.6 code for many years, using CodeIgniter and a very basic editor.

Fully embracing PHPStorm, strict_types and EAInspections completely changed me as a developer. I hated them at first, just getting in the way and annoying me… But now several years later and I fully credit them for revitalising my career and giving me a newfound love for coding.


Lots of people, particularly Laravel people, are doing static analysis with tools like PHPStan or Psalm. Over time there have been more and more type-oriented features introduced to the language too. Obviously you can't catch everything, but it's a dynamic language so that's the trade off you've signed up for.


Re: your Stack Overflow woes

Stack Overflow makes a lot more sense when you think of it as Wikipedia run by mathematicians rather than a forum. If your question is ambiguous or open for discussion, it's probably not a good fit for Stack Overflow.

I don't spend much time on there anymore but now you know


You just keep adding types, it gets better by time. When you do add types, go with strict types (strict_types=1). Type errors pop early when there are many type enforcements.

When you find parts that you can't easily type (open file handlers for example), you can create wrappers that encapsulate the handlers.

Also, use phpstan/Phan or other static analyzers like others mentioned.


I have worked on a large PHP monolith with 100+ devs. We rarely had any major bugs make it to production. I think unit tests really helped there. Of course, having QA department helped a lot too but unit tests are first line of defense.

And we also used all other best practices such as PSR code formatting standards, linters, code reviews, etc.


Lots of answers on using the type support that is there, but some use of forced casting is also common, as is using === when appropriate, avoiding "if ($bool)" in favor of "if ($bool === true)" for boolean comparisons, using linters, static analyzers, and so on.


> using === when appropriate

It’s always appropriate. A good IDE should highlight == as a warning.

My code quality and programming abilities got significantly better since forcing strict types and comparisons on myself. I can’t imagine writing PHP any other way now.


There are a few instances where using == is desirable, for instance it allows you to compare two instances of an object and returns true if the properties are the same.

In this case === will always return false since it checks if the two instances are the same object.


I used PHPDoc to document stuff, now there is native support to declare types. Then my IDE (Intelij) will highlight type related issues as errors or warnings. It will also show you lot of other errors like using the wrong parameter count, the wrong parameter types etc. With PHPDoc you can also document "magic" stuff like objects that are auto-generated from DB tables, so you get error checks and autocompletion on column names.

But I work on a small team.

We use PHPUnit for unit testing, but this is not related to types.


Basically what everybody else said: tests and a static code analyzer.


It depends on the team workflow, php can be very relaxed or very strict about types, to check correctness when you pick strict modes you have tools like PhpStan, but you can also verify correctness with PhpUnit


PHP has static types.


Others have explained how PHP can be statically typed. Here's how to enforce it:

Set up a linting rule that every project PHP file (with some exceptions, like templating files) needs to have the `declare(strict_types=1);` directive. Then you can also have PHPCS fix it or just generally have linting checks on PRs.

For large legacy apps you can still add exceptions.


static analysis does a lot, but yes, dynamically typed languages mean runtime bugs that a compiler would catch. this is true of php, but also javascript, ruby, python, most lisps, just oodles of languages that people build huge systems with. i'd prefer evryone embraced compile time type checked languages, but here we are.


the same way you check every other code that will join the system: pipelines.

I know you mean: "when i hit compile i dont see the errors directly" but that can be achieved by activated the strict type setting and your screen will turn red too =)

I really think that, from all the frameworks i have used, symfony actually has the most decent debugging system. it comes with tracing logging and live debugging. so pretty much everything you would get out of any other language.

With xdebug and editors like phpstorm you are also able to pretty much mimic working with PHP as you would with C#. I believe there are working plugins for Visual Studio too.

Just as an excourse, I have also worked with projects that compiled php to other languages too on the fly.


PHPstan (or Psalm) catch any type safety issues for me. I use types extensively in my PHP code.


Use PHP 8.1 with typed properties and parameters, PHPDoc, PHP Storm with xDebug, unit tests, code review by peers, Composer, and declare(strict_types = 1);


Use the type checking features of the language. They may be optional, but they exist.


you use some static analysis tools like phpstan and psalm - I personally use phpstan and it helps a lot. Obviously you must use all the type hinting where possible and use annotations where the native ours are limited




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: