PHPDOC и позднее (статическое или динамическое) связывание
-
27-10-2019 - |
Вопрос
Большинство Php Ides полагаются на PHPDOC, чтобы получить намеки на тип выражения. Тем не менее, я часто использую этот шаблон, который, кажется, не покрывается:
class Control {
private $label = '';
/** @return ??? */
public static function Make(){ return new static(); }
/** @return ??? */
public function WithLabel($value){ $this->label = $value; return $this; }
/** @return void */
public function Render(){ /* ... */ }
}
class Textbox extends Control {
private $text = '';
/** @return ??? */
public function WithText($text){ $this->width = $text; return $this; }
}
Теперь я могу использовать такие занятия, как это:
Textbox::Make() // <-- late static binding, returns Textbox
->WithLabel('foo') // <-- late dynamic binding, returns Textbox
->WithText('bar') // <-- normal binding, returns Textbox
->Render();
Есть ли способ заменить '???
Решение
/** @return Control */
Для нестатического:
/** @return $this */
но это не задокументировано в руководстве PHPDOC
Другие советы
Обновленный ответ в качестве ссылки самая популярная PHP IDE (Phpstorm 8):
За @return
вы можете использовать:
self
$this
За @method
вы можете использовать:
$this
Пример:
/**
* Class Model
* @method $this parentMethodA
*/
class Model
{
/**
* @return $this
*/
public function parentMethodB()
{
return $this;
}
/**
* @return self
*/
public function parentMethodC()
{
return $this;
}
}
/**
* Class Person
* @method $this childMethodA
*/
class Person extends Model
{
/**
* @return $this
*/
public function childMethodB()
{
return $this;
}
/**
* @return self
*/
public function childMethodC()
{
return $this;
}
}
$p = new Person();
//In the following lines IDE will recognize those variables as:
$t1 = $p->parentMethodA(); //Instance of Person
$t2 = $p->parentMethodB(); //Instance of Person
$t3 = $p->parentMethodC(); //Instance of Model
$t4 = $p->parentMethodA(); //Instance of Person
$t5 = $p->parentMethodB(); //Instance of Person
$t6 = $p->parentMethodC(); //Instance of Person
Обновление для Phpstorm 10 (EAP)
Кажется, что сейчас static
можно использовать тоже, но только для @return
.
Обновленный ответ CVSGuimaraes, чтобы включить статические параметры:
/**
* Class Bar
* @method $this parentMethodA
*/
class Bar
{
/**
* @return $this
*/
public function parentMethodB()
{
return $this;
}
/**
* @return self
*/
public function parentMethodC()
{
return $this;
}
/**
* @return static
*/
public static function staticMethod()
{
return new static();
}
/**
* @param $id
*
* @return bool
*/
public function load($id)
{
// test
return $id ? true : false;
}
/**
* @param null $id
*
* @return static
*/
public static function get($id = NULL){
$obj = static::staticMethod();
if (is_null($id)) {
return $obj;
}
if ($obj->load($id)) {
return $obj;
}
return false;
}
}
/**
* Class Foo
* @method $this childMethodA
*/
class Foo extends Bar
{
/**
* @return $this
*/
public function childMethodB()
{
return $this;
}
/**
* @return self
*/
public function childMethodC()
{
return $this;
}
}
/**
* Class Bar
*/
class Baz extends Bar
{
}
$p = new Foo();
/** @var Foo $Foo */
$Foo = 'Foo';
$Baz = 'Bar';
// IntelliJ recognizes the following as:
$t1 = $p->parentMethodA(); //Instance of Foo
$t2 = $p->parentMethodB(); //Instance of Foo
$t3 = $p->parentMethodC(); //Instance of Model
$t4 = $p->childMethodA(); //Instance of Foo
$t5 = $p->childMethodB(); //Instance of Foo
$t6 = $p->childMethodC(); //Instance of Foo
$t7 = $Foo::staticMethod(); //Instance of Foo
$t8 = Foo::staticMethod(); //Instance of Foo
$t9 = $p::staticMethod(); //Instance of Foo
$t10 = $Foo::get(); //Instance of Foo
$t12 = Bar::get(); //Instance of Bar
$t11 = $Baz::get(); // Unknown
Не связан с StackOverflow