Ответ 1
Ну, PhpStorm 3.0 примет
@method static type name() description
См. соответствующий запрос функции http://youtrack.jetbrains.net/issue/WI-4051
Каков правильный способ аннотировать (в PHPDoc) функции, реализованные через __callStatic
? Более важно: есть ли способ, который сделает NetBeans и PHPStorm понятными, что это статические методы?
Если вы хотите увеличить картинку, вот как я добрался до этого вопроса.
Проблема. В моем текущем проекте у нас есть тонна классов, которые должны быть действительно одиночными (DB-прокси и тому подобное). Излишне говорить, что у нас есть как минимум несколько сотен строк 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 на самом деле не является необходимостью.
Ну, PhpStorm 3.0 примет
@method static type name() description
См. соответствующий запрос функции http://youtrack.jetbrains.net/issue/WI-4051
Вообще говоря, я считаю, что выбор использования магического материала связан с необходимостью принять компромисс с потерей эффективности таких вещей, как автозаполнение.
Однако в моем тестировании с 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()"