Hi,
I wanted to ask you what do you think about my concept of extending PHP with JSDoc capabilities. I was just frustrated that I cannot pass an array with big number of optional keys as a function parameter. I decided to create the intellisense as VS Code extension which turned out to be not crazy hard to do. So my question should be, is anyone else willing to use that feature?
Lemme give you an example of usage:
We have a function paginateDBData($params), where $params have mandatory $select and $table and optional $order and $where. Don’t go too far into logical aspects of it, just showing what advantages it gives
You can execute it as
paginateDBData(["select"
=> "*", "table" => "products", "where" => "1"]);
totally skipping the $order, also no need to create an object with params above the call. Autocompletion and descriptions – all built in. What else it can do?
Well, you can even have multiple levels of params, like in JS:
/** @/typedef {{
* column:? string // possibly a comment here, notation can be anything
* row?: {
* width: number
* height: number
* }
* }} GridPosition // it's actually a random name
*/
Enums are also going to be supported and maybe even more than that.
I am using it just for my own project but it might be cool to share it as an open source maybe. Obviously feel free to ask questions, I might seem like a newbie.
EDIT: I’m planning to add more features for type hinting, it is supposed to be more typescript alike than what I have shown above. It will be able to spot errors just in time. It’s a really complicated topic.
All static analysers (PHPStan, Psalm, Phan) support the following:
A while ago there was the intention to add something similar as official phpdoc, but not sure what happened to that.
That looks cool, what about extending, more levels or optional parameters? I can also see why it would be considered as anti-pattern. EDIT: nevermind, I can already see it
You should look at PHPDoc, and specifically the extended array types implemented by tools such as Psalm: https://psalm.dev/docs/annotating_code/type_syntax/array_types/
Rather than completely reinventing the wheel, use if possible, otherwise extend existing standard ways of doing things. Future developers will thank you for it and you’ll often get tooling support (eg. IDEs such as PHPStorm understand a lot of the PHPDoc extensions used by Psalm and other tools).
Alternatively, stop using arrays when you should be using objects (whilst generally a micro-optimization, this can result in performance improvements:
https://steemit.com/php/@crell/php-use-associative-arrays-basically-never ).
I generally consider passing an “array of options” as in the paginateDBData
example given to be an anti-pattern. These functions frequently do too much, end up hard to maintain, and are hard to quickly see how they should be used (“code as if the next developer to work on the code is a psychopathic murderer and they know where you live”)
Whilst they can be documented, in my experience the documentation almost always falls out-of-line with the actual code behavior.
Additionally, in my experience it can be very difficult to almost impossible to determine if a particular behavior is no longer used by any code on the system, which inhibits the tidying up of dead code and contributes to maintenance issues.
Having phpstorm would be useful for sure, I’m wondering how to get it running in vs code, from your experience – does it provide just in time autocompletion and error checking?
Fwiw psalm and phpstan already have this functionality for php
i get where you come from but from my point of view arrays are just the wrong type for it.
If your working on “optional” or “mandatory” stuff i wouldnt rely on arrays with parameters. Use the parameters itself as method inputs or use an object.
Or use something like this: https://symfony.com/doc/current/components/options_resolver.html
The point was to avoid creating objects to simply write less code, does it sound silly? I enjoyed how javascript works with it and thought that maybe it would be nice to use in php because if it’s similar once you know one you can use another.
Sure, I might use it if you made it open source.
I often do this as an “options” parameter as the last argument of a function.
regarding the main feature (not the enum part), wouldn’t it be covered by php8 named arguments?
I think that’s the case, but I wanted to go beyond that. So what it really does is it’s objectifying arrays for any purpose.
I consider arrays of options as anti-pattern.
Look who does it: https://developer.wordpress.org/reference/functions/register_post_type/ In the labels key, you have another array, which is documented elsewhere: https://developer.wordpress.org/reference/functions/get_post_type_labels/
Phpstorm can not really help here.
+1 for Psalm. It’s possible to use Psalm for this purpose, and it’s incredibly useful for other things, too.
If you have a look at https://psalm.dev/docs/annotating_code/type_syntax/array_types/#object-like-arrays it gives some examples, but the gist is that you can specify the shape of the array, including making certain keys optional.
A much much better solution is passing in objects, not arrays. In your example I would use a Query
object, which has the select/table as required constructor params, and methods for setting the where/order.
You get all the benefits of autocomplete, type checking, etc. without needing an extra layer of complexity. Not to mention it makes refactoring easier, adding options, etc. you could take it a step further and make it an interface, and your domain can define custom query objects to keep things better encapsulated.
Trust me, using arrays for this will only lead to sadness and hair pulling. Not to mention onboarding new developers: instead of having to explain how your fancy JSDoc stuff works, they just use objects…that everyone understands.