Modern PHP features – PHP 8.0 and 8.1
laravel-news.com
laravel-news.com
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?
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" 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. /** 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-enumsI 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.
Not needing to `\` every other line is also nice.
And then there's javascript, of course, eating glue in the corner as usual.
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.
$ 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
$ $ 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.
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.
```
>>> (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)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.
It's mostly legacy stuff like built in function naming.
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.
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.
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...
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
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 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).
See python2 vs python3. It almost ended the language IMHO.
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 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.
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.
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 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.
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.
The _vast_ majority would be Laravel and Symfony.
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 :)
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.
> 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.
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.
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.
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.
(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.
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.
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.
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.
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.
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'.
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?
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.
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.
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
}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...
Feature convergence is only a bad thing if you're not spending enough time in other tools to recognize them.
Then you don't use property promotion. It's optional: it only happens if you add a visibility modifier before the parameter name.
Namespace?
But such a breaking change would of course be too much to ask
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.
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…
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?
And we also used all other best practices such as PSR code formatting standards, linters, code reviews, etc.
But I work on a small team.
We use PHPUnit for unit testing, but this is not related to types.
> 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.
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.
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.
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.
In this case === will always return false since it checks if the two instances are the same object.
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.
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.
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