¿Cómo podría un tipo sugerir un método estático de devolución de singleton en una clase abstracta, que devuelve instancias de las clases llamadas extendidas?
Por ejemplo, veamos el siguiente código:
<?php abstract class Foo { /** @return Foo */ public function init() { static $instance; if ( is_null($instance) ) { $class = get_called_class(); $instance = new $class(); } return $instance; } } class Bar extends Foo { public $name = "Bar name"; } class Baz extends Foo { public $age = 42; } Mi intención es que herramientas como PhpStorm entiendan que Bar::init() devuelve un objeto de tipo Bar y que Baz::init() devuelve un objeto de tipo Baz . Así, por ejemplo, los objetos creados a partir del método Baz::init() completarían automáticamente la propiedad de name pero no la propiedad de age .
Obviamente, la sugerencia de tipo actual @return Foo es incorrecta, ya que el método nunca devolverá una instancia de objeto de una clase abstracta.
Entonces @return static funcionará en este caso para PHPStorm. Es la opción más fácil y te proporcionará lo que buscas.
Opcionalmente, puede usar la anotación @method contra la clase, aunque esto es muy manual y debe hacerse para cada clase. Hay otra cosa extraña con este método en PHPStorm donde si navega al método init() (ctrl+clic o w/e) navegará primero a esta anotación. Sin embargo, así es como se ve:
/** * @method Bar init() */ class Baz extends Foo { }Donde opcionalmente como último recurso, y realmente no creo que lo necesite, pero está aquí para completarlo. Extienda el método y agregue su anotación de devolución como lo haría con un método normal.
/** * @return Baz */ public function init() { return parent::init(); }Podrías intentar esto:
abstract class Foo { /** @return static */ public function init() { static $instance; if ( is_null($instance) ) { $class = get_called_class(); $instance = new $class(); } return $instance; } }Esto probablemente requerirá que PhpStorm esté configurado con sugerencias de tipo PHP 5.3+ para que funcione.