How to Document Magic (_Call and _Callstatic) Methods for Ides

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

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:

  • https://docs.phpdoc.org/latest/references/phpdoc/tags/method.html
  • https://github.com/phpDocumentor/phpDocumentor2/blob/develop/docs/PSR.md#711-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):

  • https://github.com/phpDocumentor/phpDocumentor2/issues/689

Practical applications of PHP magic methods - __get, __set, and __call

__call()

I've seen it used to implement behaviors, as in add extra functions to a class through a pluginable interface.

Pseudo-code like so:

$method = function($self) {};
$events->register('object.method', $method);
$entity->method(); // $method($this);

It also makes it easier to write mostly similar functions, such as in ORMs. e.g.:

$entity->setName('foo'); // set column name to 'foo'

__get()/__set()

I've mostly seen it used to wrap access to private variables.

ORMs are the best example that comes to mind:

$entity->name = 'foo'; // set column name to 'foo'

Is there a way to indicate that a class has magic methods defined for every method on another class?

The proper solution is to use supported @method PHPDoc tags. This way it will also work in other editors/IDEs that support PHPDoc and understand such standard tag.

This approach requires every method to be listed separately. More on this in another StackOverflow question/answer: https://stackoverflow.com/a/15634488/783119.


In current PhpStorm versions you may use not-in-PHPDoc-specs (and therefore possibly PhpStorm-specific) @mixin tag.

Adding @mixing className in PHPDoc comment for your target class should do the job for you.

/**
* Class B
*
* @mixin A
*/
class B
{

Basically, @mixin tag does what actual PHP's traits do.

Please note that there is no guarantee that support for such tag will not be removed at some point in the future, although it's pretty unlikely.

execute (magic) method when existing method is called

There isn't a direct way to do this but it looks to me like your trying to implement a form of Aspect Oriented programming. There are several ways of achieving this in PHP, one would be to set up your class something like the following:

class MyClass
{
public function __startMethod ( $method, $args )
{
// a method just got called, so this is called first
echo ' [start] ';
}

public function _helloWorld ( )
{
echo ' [Hello] ';
}

public function __call($method, $args)
{
_startMethod($method, $args);
$actualMethod = '_'.$method;
call_user_func_array(array($this, $actualMethod), $args);
}
}

$obj = new MyClass();
$obj->helloWorld();

Look up other ways of implementing AOP in PHP to see what works best for you (I'll see if I can find a link somewhere).

EDIT: here's a document for you http://www.liacs.nl/assets/Bachelorscripties/07-MFAPouw.pdf

Allow Native Laravel Magic Methods in a Package

can't really help you without the source code for your theme package but it would look like this:

use Illuminate\Support\Traits\ForwardsCalls;

class Theme
{
use ForwardsCalls;
...
public function __call($method, $parameters)
{
return $this->forwardCallTo($this->getView(), $method, $parameters);
}
}

you can do the same for the __callStatic

Magic Methods __Call doesn't work well with multiple arguments

return call_user_func_array($this->objects[$this->methods[$method]]->$method, $args);

See http://php.net/call_user_func_array.



Related Topics



Leave a reply



Submit