PHPDoc и __callStatic - PullRequest
       50

PHPDoc и __callStatic

20 голосов
/ 12 мая 2011

tl; dr

Как правильно аннотировать (в PHPDoc) функции, реализованные с помощью __callStatic?Более важно: есть ли способ, который позволит NetBeans и PHPStorm понять, что это статические методы?

Мотивация

Если вы хотите получить более широкую картину, вот как я получилна этот вопрос.

Задача : В моем текущем проекте у нас есть тонна классов, которые действительно должны быть одиночными (прокси-серверы БД и тому подобное).Само собой разумеется, у нас есть по крайней мере несколько сотен require_once и $foo = new FooProxy(); строк.

Решение : я создал класс Loader, чтобы решить эту проблему, используя __callStaticмагический метод, поэтому мы можем просто сказать $foo = Loader::FooProxy();.Это идеально подходит для наших целей, но:

Проблема : Таким образом, очевидно, что ни в одной из IDE, используемых в команде, нет подсказок типа.

Решение : Каждый модуль определяет подкласс Loader, добавляя методы, которые просто перенаправляют на __callStatic.

Проблема : Фактическое добавлениеинтерпретируемый код только для автозавершения недопустим (это можно утверждать, но давайте его пока примем).

Решение : Давайте не будем добавлять никаких реальных методов, только объявимметоды в PHPDoc как это:

<?php
/**
 * @method FooProxy FooProxy()
 */
 class BarLoader extends Loader {}
?>

Проблема : FooProxy не является статическим методом.Ничто из следующего не делает его статичным:

<?php
/**
 * @static
 * @method FooProxy FooProxy()
 */

///////////////

/**
 * @static @method A A()
 * @method static A A()
 * @method A static A()
 * @method A A() static
 */

Создание абстрактного класса не имеет значения.Около часа работы Google не было найдено решений.Основная цель - ознакомить IDE с этими функциями;наличие правильного PHPDoc на самом деле не является необходимостью.

Ответы [ 2 ]

31 голосов
/ 14 сентября 2011

Ну, PhpStorm 3.0 примет

@method static type name() description

См. Соответствующий запрос функции http://youtrack.jetbrains.net/issue/WI-4051

1 голос
/ 13 мая 2011

Вообще говоря, я думаю, что выбор магического материала связан с необходимостью принять компромисс с потерей эффективности таких вещей, как автозаполнение.

Однако, в моем тестировании с Eclipse PDT (Helios с PHP 5.3.2 на WinXP) я смог получить хорошие автозаполнения из одного явного статического метода и двух магических статических методов из моего класса Loader, который я смоделировал по вашему примеру .

Короче говоря, похоже, что использование тега @method в классе docblock было достаточно для Eclipse, чтобы разобраться. Если у NetBeans и PHPStorm возникают проблемы, я не уверен, связано ли это со «статическим» аспектом или нет ... возможно, просто разбор такого динамического кода может быть больше, чем их логика автозаполнения, предназначенная для обработки.

<?php
/**
 * @method BarProxy BarProxy() returns an instance of BarProxy
 * @method BazProxy BazProxy() returns an instance of BazProxy
 */
class Loader
{
    public static function __callStatic($name, $arguments)
    {
        return new $name($arguments);
    }

    /**
     * @return FooProxy
     */
    public static function FooProxy(){
        return new FooProxy();
    }
}

class FooProxy
{
    public function sayCheese() {}
}

class BarProxy
{
    public function eatFries() {}
}

class BazProxy
{
    public function sleep() {}
}

$foo = Loader::FooProxy();
$foo->sayCheese(); // did this simply to verify explicit autocompletion succeeded

$bar = Loader::BarProxy();
$bar->eatFries();  // autocompletion of just "$bar->" brought up "eatFries()"

$baz = Loader::BazProxy();
$baz->sleep();     // autocompletion of just "$baz->" brought up "sleep()"
...