How to document magic (_call and _callStatic) methods for IDEs

36,300

Solution 1

Use class-level PHPDoc comment -- specifically @method tag -- works fine in PhpStorm:

/**
 * @method static someClass get_by_user_id(int $id) Bla-bla
 * @method static someClass get_first_by_id(int $id) 
 */
abstract class a {
...

In the above:

  • @method -- PHPDoc tag
  • static -- tells that this is static method
  • someClass or $this -- return type
  • get_by_user_id -- method name
  • (int $id) -- method signature: ([[type] [parameter]<, ...>])
  • Bla-bla -- some optional description

More about @method:

P.S. While @method static works fine in PhpStorm (tells IDE that method is static) it may not be (yet?) supported by actual phpDocumentor tool (sorry, have not used it for a while).


Alternatively: (in PhpStorm, of course) Settings | Inspections | PHP | Undefined | Undefined method --> Downgrade severity if __magic methods are present in class -- it will not help with code completion for such methods in any way, but will not mark those magic methods as "undefined method" errors.


phpDocumentor's ticket regarding using RegEx/partial names for @property/@method tags (how it can be useful for documentation and how little help it may bring to the actual IDE when dealing with code completion):

Solution 2

Somewhat related to original question:

You can also define this in phpstorm meta file. Here's an example for factory method (v2016.3):

// Define in .phpstorm.meta.php
namespace PHPSTORM_META {
    $STATIC_METHOD_TYPES = [
        \Factory::create('') => [],
    ];
}

// Then use in code
$factory = new \Factory();
$user = $factory->create(\User::class);
// Here you get autocomplete.
$user->subscribe();

This way you don't have to docblock every possibility when magic happens.

Have some docs for details.

Share:
36,300
Rob Forrest
Author by

Rob Forrest

Updated on February 10, 2020

Comments

  • Rob Forrest
    Rob Forrest about 4 years

    After many happy years coding in notepad++ and sublime, I've been advised to give a PHP IDE a go. I'm trying out phpStorm and it seems nice. The code completion and documentation is a great feature but isn't working out for me when magic methods are used. Is there a work around to get phpStorm to understand what's going on in magic methods?

    Our situation is something like this:

    abstract class a {
        public static function __callStatic($method,$args)
        {
            if(strpos($method,"get_by_") === 0)
            {
                //do stuff
            } elseif(strpos($method,"get_first_by_") === 0) {
                //do stuff
            } elseif($method == "get_all") {
                //do stuff
            }
        }
    }
    
    class b extends a {
        // some more stuff
    }
    
    b::get_by_user_id(27);
    b::get_first_by_id(156);
    b::get_all();
    

    The magic callStatic method allows us to get a collection of objects via 1 or more arguments that make up the function call.

    I see that there is an @method statement for use in these cases but phpStorm is only picking up the first of these statements. Furthermore I can only set the return type to mixed where as I'd prefer to be able to set it as whatever class this was called on (b in my example).

    Any ideas or suggestions would be very gratefully received, thanks.

  • Rob Forrest
    Rob Forrest about 11 years
    Thanks, this looks like a reasonable suggestion and it certainly works in phpStorm, but I'm a bit loathed to write out the potentially hundreds of lines of @method at the top of each class. You see the get_by_* method can be prepended by any of the objects parameters to get objects of that type by the specified parameter. Even excluding the possibility of get_by__and_ i'd end up with about 1500 @methods across 140 different class. Is there not a more generic way to provide documentation?
  • LazyOne
    LazyOne about 11 years
    No. All magic methods must be declared specifically (that's the main point of documenting this way) - PHPDoc does not understand partial names (e.g. get_by_*(int $id)). For IDE (code inspection, not completion!) you have alt solution (disable warnings). For phpDocumentor (or alternative tool) - no solution known to me (maybe it is there, but I do not know about it). You have the link to github - file new ticket and ask for adding such "partial names" matching functionality - see what they will say (most likely will be rejected). If it will be implemented, then IDE may have it as well later.
  • LazyOne
    LazyOne about 11 years
    github.com/phpDocumentor/phpDocumentor2/issues -- but please check if similar ticket does not exist before posting yours.
  • Rob Forrest
    Rob Forrest about 11 years
    Thanks for all of that. There is a currently open ticket with regards to this but it all seems to have gone quiet. I've stuck a comment in there and we'll see what comes of it.
  • LazyOne
    LazyOne about 11 years
    Just for the reference, the phpDocumentor's ticket (so other users know what ticket you are talking about; also added it to the answer itself): github.com/phpDocumentor/phpDocumentor2/issues/689
  • Rob Forrest
    Rob Forrest about 11 years
    It looks like I've openned a can of worms there!! This could get interesting.
  • jgmjgm
    jgmjgm about 6 years
    This doesn't work with __call. It's also not documented and invalid PHP. PHPStorm only provides support for where you have statically defined methods that return a mixture of types depending on the input.
  • Guillaume Renoult
    Guillaume Renoult about 4 years
    The documentation says "@method tags MUST NOT be used in a PHPDoc that is not associated with a class or interface.". Therefore if you want to reference a method from another class, you can specify the @uses annotation and it works well.
  • CDuv
    CDuv over 2 years
    Here is the updated link to the @method tag documentation page : docs.phpdoc.org/latest/guide/references/phpdoc/tags/… (previous links in the answer and comments are broken/outdated).