Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Uhm, how about PHP attributes, getting rid of comments / annotations? Named arguments? Constructor property promotion? Readonly properties (8.1) / classes (8.2)? Arrow functions or typed properties (both 7.4)?

I'd say those are really cool things. Especially as a web developer, there's just so much boilerplate I can get rid of since using 8.0+.



I’m in agreement with you that it came a very long way.

Now, most of those have been present in many other languages [0], often with less limitations.

And as usual the old ways haven’t all been deprecated either, so it stays weird. For instance typed properties were a chance to reset the clock on type handling, but no, declaring a type will force cast parameters to that type instead of throwing an error (i.e. passing 0 for a string argument will convert it silently)

[0] Constructor property promotion isn’t, but TBH I’m of mixed feelings about it. We get conciseness in exchange for weirdness as the properties aren’t declared outside of the constructor, where they would be otherwise. I wished it was done the other way round.


> declaring a type will force cast parameters to that type instead of throwing an error

There is `declare(strict_types=1)`[0]

[0]: https://www.php.net/manual/en/language.types.declarations.ph...


Yes, except it has to be set on the _caller_ side.

I kinda see why, after all it’s the caller who will deal with the TypeError. But assuming we’re not setting types for all our functions, when I do for a specific one, I want to enforce that strictness on the _callee_ side (“for this function, it really matters that the parameters are correct”), and not have to go check if every single caller files properly has the strictness set. [0]

So in the end, the best option is to _not_ type scalar parameters, and do the strict check manually and throw your own TypeError, inside your function instead.

[0] Auto setting strictness for every file in your project and checking for it in CI clears the issue, but that becomes another boilerplate you’re adding to your system. And it still doesn’t work for native functions.

It’s so close. Really, so close to be good.


> Auto setting strictness for every file in your project and checking for it in CI clears the issue, but that becomes another boilerplate you’re adding to your system

There was this RFC[0] but it seems to have fizzled.

> And it still doesn’t work for native functions.

The page states: 'Function calls from within internal functions will not be affected by the strict_types declaration' (emphasis mine). Outside of array_map I don't think this happens all that much.

> So in the end, the best option is to _not_ type scalar parameters, and do the strict check manually and throw your own TypeError, inside your function instead.

That sounds awful. Why not install a nice static analyzer like phpstan or psalm and never think about it again?

[0]: https://wiki.php.net/rfc/namespace_scoped_declares


> native functions

Thanks

> That sounds awful. Why not install a nice static analyzer like phpstan or psalm and never think about it again?

It is completely unelegant, but works decently in practice (fits the subject perfectly…). We’re extensively using phpstan, especially as it’s the best way to expose in array types.

Phpstan still has blind spots, including the ability to disable it on the caller side (in particular, as far as I know you can’t disable specific errors inline, so if you have to do it for one parameter for instance, it applies to all parameters), and the option to overwrite a variable type just for phpstan. Those comes from developer error, but that’s exactly what we want to protect the system from.

Actually checking at runtime that a value is of the right type is more secure.


Yes, the backward compatibility is a crux on the one hand, on the other hand it has made upgrading PHP versions a breeze. In the past 6 months I updated several code bases from PHP 7 / 8.0 to PHP 8.1 / 8.2, the PHP part was easy (just the deprecated dynamic properties in 8.2 caused a wall of text in our loggers), the framework was a bit more difficult. The most problematic were the exotic packages that the clients had installed ages ago and that are not properly maintained anymore, so I have to figure out a replacement for those code modules.

Constructor property promotion is fine, I think. I think it ties in well with the readonly property.

    public function __construct(
        public readonly Company $company,
    )
    {
    }
There's just so much info & functionality + type safety crammed into there that wouldn't have been possible previously; it's really nice.




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

Search: