magic - phpdoc @return
PHPDoc y__callStatic (2)
Bueno, PhpStorm 3.0 aceptará
@method static type name() description
Ver solicitud de función relevante http://youtrack.jetbrains.net/issue/WI-4051
tl; dr
¿Cuál es la forma correcta de anotar (en PHPDoc) las funciones implementadas a través de __callStatic
? Más importante: ¿hay alguna forma de que NetBeans y PHPStorm comprendan que estos son métodos estáticos?
Motivación
Si quieres una imagen más grande, así es como llegué a esta pregunta.
Problema : en mi proyecto actual tenemos un montón de clases que realmente deberían ser singletons (proxies DB y similares). No hace falta decir que tenemos al menos unos cientos de require_once
y $foo = new FooProxy();
líneas.
Solución : creé una clase Loader
para resolver esto, usando el método mágico __callStatic
para que podamos decir $foo = Loader::FooProxy();
. Es perfecto para nuestros propósitos, pero:
Problema : de esta manera, obviamente, no hay sugerencias de tipo en ninguno de los IDE utilizados en el equipo.
Solución : Cada módulo define una subclase de Loader
, agregando métodos que solo se __callStatic
a __callStatic
.
Problema : Agregar código realmente interpretado solo por el hecho de completar automáticamente no es aceptable (esto podría ser discutido, pero aceptémoslo por el momento).
Solución : No agreguemos ningún método real, solo declaremos los métodos en PHPDoc de esta manera:
<?php
/**
* @method FooProxy FooProxy()
*/
class BarLoader extends Loader {}
?>
Problema : FooProxy
no es un método estático. Ninguno de los siguientes lo hace estático:
<?php
/**
* @static
* @method FooProxy FooProxy()
*/
///////////////
/**
* @static @method A A()
* @method static A A()
* @method A static A()
* @method A A() static
*/
Hacer el resumen de la clase no hace ninguna diferencia. Alrededor de una hora de Google no encontró soluciones. El objetivo principal es concienciar a los IDE de estas funciones; Tener PHPDoc correcto no es realmente una necesidad.
En términos generales, creo que la elección de usar las cosas mágicas viene con la advertencia de tener que aceptar un compromiso de perder la efectividad de cosas como la autocompletación.
Sin embargo, en mis pruebas con Eclipse PDT (Helios con PHP 5.3.2 en WinXP), pude obtener buenas autocompletaciones de un método estático explícito y dos métodos estáticos mágicos de mi clase Loader que modelé siguiendo su ejemplo.
En resumen, parece que el uso de la etiqueta @method en la clase docblock fue suficiente para que Eclipse resolviera las cosas. Si NetBeans y PHPStorm tienen problemas, no estoy seguro de si está relacionado con el aspecto "estático" o no ... puede ser que el análisis de dicho código dinámico sea más de lo que su lógica de autocompletado está diseñada para manejar.
<?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()"